From 6c0dbfbde8da69e1439bf21fbe3d557411a62d4a Mon Sep 17 00:00:00 2001 From: Jonald Fyookball <jonaldfyookball@outlook.com> Date: Wed, 26 Jul 2023 14:07:30 -0400 Subject: [PATCH 001/379] Push local changes to branch. --- lib/services/cashfusion/comms.dart | 183 ++ lib/services/cashfusion/connection.dart | 285 ++ lib/services/cashfusion/covert.dart | 499 ++++ lib/services/cashfusion/encrypt.dart | 125 + lib/services/cashfusion/fusion.dart | 1583 +++++++++++ lib/services/cashfusion/fusion.pb.dart | 2501 +++++++++++++++++ lib/services/cashfusion/main.dart | 122 + lib/services/cashfusion/pedersen.dart | 187 ++ .../cashfusion/protobuf/build-proto-fusion.sh | 11 + .../cashfusion/protobuf/fusion.pb.dart | 2501 +++++++++++++++++ .../cashfusion/protobuf/fusion.pbenum.dart | 7 + .../cashfusion/protobuf/fusion.pbjson.dart | 427 +++ lib/services/cashfusion/protobuf/fusion.proto | 281 ++ lib/services/cashfusion/protocol.dart | 59 + lib/services/cashfusion/socketwrapper.dart | 46 + lib/services/cashfusion/util.dart | 330 +++ lib/services/cashfusion/validation.dart | 293 ++ .../coins/bitcoincash/bitcoincash_wallet.dart | 122 + 18 files changed, 9562 insertions(+) create mode 100644 lib/services/cashfusion/comms.dart create mode 100644 lib/services/cashfusion/connection.dart create mode 100644 lib/services/cashfusion/covert.dart create mode 100644 lib/services/cashfusion/encrypt.dart create mode 100644 lib/services/cashfusion/fusion.dart create mode 100644 lib/services/cashfusion/fusion.pb.dart create mode 100644 lib/services/cashfusion/main.dart create mode 100644 lib/services/cashfusion/pedersen.dart create mode 100644 lib/services/cashfusion/protobuf/build-proto-fusion.sh create mode 100644 lib/services/cashfusion/protobuf/fusion.pb.dart create mode 100644 lib/services/cashfusion/protobuf/fusion.pbenum.dart create mode 100644 lib/services/cashfusion/protobuf/fusion.pbjson.dart create mode 100644 lib/services/cashfusion/protobuf/fusion.proto create mode 100644 lib/services/cashfusion/protocol.dart create mode 100644 lib/services/cashfusion/socketwrapper.dart create mode 100644 lib/services/cashfusion/util.dart create mode 100644 lib/services/cashfusion/validation.dart diff --git a/lib/services/cashfusion/comms.dart b/lib/services/cashfusion/comms.dart new file mode 100644 index 000000000..dd623459b --- /dev/null +++ b/lib/services/cashfusion/comms.dart @@ -0,0 +1,183 @@ + +import 'util.dart'; +import 'connection.dart'; +import 'fusion.dart'; +import 'fusion.pb.dart'; +import 'dart:io'; +import 'dart:async'; +import 'package:protobuf/protobuf.dart'; +import 'socketwrapper.dart'; + +typedef PbCreateFunc = GeneratedMessage Function(); + +Map<Type, PbCreateFunc> pbClassCreators = { + CovertResponse: () => CovertResponse(), + ClientMessage: () => ClientMessage(), + InputComponent: () => InputComponent(), + OutputComponent: () => OutputComponent(), + BlankComponent: () => BlankComponent(), + Component: () => Component(), + InitialCommitment: () => InitialCommitment(), + Proof: () => Proof(), + ClientHello: () => ClientHello(), + ServerHello: () => ServerHello(), + JoinPools: () => JoinPools(), + TierStatusUpdate: () => TierStatusUpdate(), + FusionBegin: ()=> FusionBegin(), + StartRound: ()=> StartRound(), + PlayerCommit: ()=> PlayerCommit(), + BlindSigResponses: ()=> BlindSigResponses(), + AllCommitments: ()=> AllCommitments(), + CovertComponent: ()=> CovertComponent(), + ShareCovertComponents: ()=> ShareCovertComponents(), + CovertTransactionSignature: ()=> CovertTransactionSignature(), + FusionResult: ()=> FusionResult(), + MyProofsList: ()=> MyProofsList(), + TheirProofsList: ()=> TheirProofsList(), + Blames: ()=> Blames(), + RestartRound: ()=> RestartRound(), + Error: ()=> Error(), + Ping: ()=> Ping(), + OK: ()=> OK(), + ClientMessage: ()=> ClientMessage(), + ServerMessage: ()=> ServerMessage(), + CovertMessage: ()=> CovertMessage(), + CovertResponse: ()=> CovertResponse() + +}; + + + +Future<void> sendPb(Connection connection, Type pbClass, GeneratedMessage subMsg, {Duration? timeout}) async { + + // Construct the outer message with the submessage. + + if (pbClassCreators[pbClass] == null) { + print('pbClassCreators[pbClass] is null'); + return; + } + + var pbMessage = pbClassCreators[pbClass]!()..mergeFromMessage(subMsg); + final msgBytes = pbMessage.writeToBuffer(); + try { + await connection.sendMessage(msgBytes, timeout: timeout); + } on SocketException { + throw FusionError('Connection closed by remote'); + } on TimeoutException { + throw FusionError('Timed out during send'); + } catch (e) { + throw FusionError('Communications error: ${e.runtimeType}: $e'); + } +} + + + +Future<void> sendPb2(SocketWrapper socketwrapper, Connection connection, Type pbClass, GeneratedMessage subMsg, {Duration? timeout}) async { + + + // Construct the outer message with the submessage. + + if (pbClassCreators[pbClass] == null) { + print('pbClassCreators[pbClass] is null'); + return; + } + + var pbMessage = pbClassCreators[pbClass]!()..mergeFromMessage(subMsg); + final msgBytes = pbMessage.writeToBuffer(); + try { + await connection.sendMessageWithSocketWrapper(socketwrapper, msgBytes, timeout: timeout); + } on SocketException { + throw FusionError('Connection closed by remote'); + } on TimeoutException { + throw FusionError('Timed out during send'); + } catch (e) { + throw FusionError('Communications error: ${e.runtimeType}: $e'); + } +} + + + + +Future<Tuple<GeneratedMessage, String>> recvPb2(SocketWrapper socketwrapper, Connection connection, Type pbClass, List<String> expectedFieldNames, {Duration? timeout}) async { + try { + + List<int> blob = await connection.recv_message2(socketwrapper, timeout: timeout); + + var pbMessage = pbClassCreators[pbClass]!()..mergeFromBuffer(blob); + + if (!pbMessage.isInitialized()) { + throw FusionError('Incomplete message received'); + } + + for (var name in expectedFieldNames) { + var fieldInfo = pbMessage.info_.byName[name]; + + if (fieldInfo == null) { + throw FusionError('Expected field not found in message: $name'); + } + + if (pbMessage.hasField(fieldInfo.tagNumber)) { + return Tuple(pbMessage, name); + } + } + + throw FusionError('None of the expected fields found in the received message'); + + } catch (e) { + // Handle different exceptions here + if (e is SocketException) { + throw FusionError('Connection closed by remote'); + } else if (e is InvalidProtocolBufferException) { + throw FusionError('Message decoding error: ' + e.toString()); + } else if (e is TimeoutException) { + throw FusionError('Timed out during receive'); + } else if (e is OSError && e.errorCode == 9) { + throw FusionError('Connection closed by local'); + } else { + throw FusionError('Communications error: ${e.runtimeType}: ${e.toString()}'); + } + } +} + + +Future<Tuple<GeneratedMessage, String>> recvPb(Connection connection, Type pbClass, List<String> expectedFieldNames, {Duration? timeout}) async { + try { + + List<int> blob = await connection.recv_message(timeout: timeout); + + var pbMessage = pbClassCreators[pbClass]!()..mergeFromBuffer(blob); + + if (!pbMessage.isInitialized()) { + throw FusionError('Incomplete message received'); + } + + for (var name in expectedFieldNames) { + var fieldInfo = pbMessage.info_.byName[name]; + + if (fieldInfo == null) { + throw FusionError('Expected field not found in message: $name'); + } + + if (pbMessage.hasField(fieldInfo.tagNumber)) { + return Tuple(pbMessage, name); + } + } + + throw FusionError('None of the expected fields found in the received message'); + + } catch (e) { + // Handle different exceptions here + if (e is SocketException) { + throw FusionError('Connection closed by remote'); + } else if (e is InvalidProtocolBufferException) { + throw FusionError('Message decoding error: ' + e.toString()); + } else if (e is TimeoutException) { + throw FusionError('Timed out during receive'); + } else if (e is OSError && e.errorCode == 9) { + throw FusionError('Connection closed by local'); + } else { + throw FusionError('Communications error: ${e.runtimeType}: ${e.toString()}'); + } + } +} + diff --git a/lib/services/cashfusion/connection.dart b/lib/services/cashfusion/connection.dart new file mode 100644 index 000000000..b9b4cc64b --- /dev/null +++ b/lib/services/cashfusion/connection.dart @@ -0,0 +1,285 @@ +import 'socketwrapper.dart'; +import 'dart:io'; +import 'dart:async'; +import 'dart:convert'; +import 'dart:typed_data'; +import 'package:convert/convert.dart'; +import 'package:collection/collection.dart'; + +/* +This file might need some fixing up because each time we call fillBuf, we're trying to +remove data from a buffer but its a local copy , might not actually +remove the data from the socket buffer. We may need a wrapper class for the buffer?? + + */ + +class BadFrameError extends Error { + final String message; + + BadFrameError(this.message); + + @override + String toString() => message; +} + + + +Future<Connection> openConnection(String host, int port, + {double connTimeout = 5.0, + double defaultTimeout = 5.0, + bool ssl = false, + dynamic socksOpts}) async { + + try { + // Dart's Socket class handles connection timeout internally. + Socket socket = await Socket.connect(host, port); + if (ssl) { + // We can use SecureSocket.secure to upgrade socket connection to SSL/TLS. + socket = await SecureSocket.secure(socket); + } + + return Connection(socket: socket, timeout: Duration(seconds: defaultTimeout.toInt())); + + } catch (e) { + throw 'Failed to open connection: $e'; + } +} + + +class Connection { + Duration timeout = Duration(seconds: 1); + Socket? socket; + + static const int MAX_MSG_LENGTH = 200*1024; + static final Uint8List magic = Uint8List.fromList([0x76, 0x5b, 0xe8, 0xb4, 0xe4, 0x39, 0x6d, 0xcf]); + final Uint8List recvbuf = Uint8List(0); + Connection({required this.socket, this.timeout = const Duration(seconds: 1)}); + Connection.withoutSocket({this.timeout = const Duration(seconds: 1)}); + + Future<void> sendMessageWithSocketWrapper(SocketWrapper socketwrapper, List<int> msg, {Duration? timeout}) async { + timeout ??= this.timeout; + print ("DEBUG sendmessage msg sending "); + print (msg); + final lengthBytes = Uint8List(4); + final byteData = ByteData.view(lengthBytes.buffer); + byteData.setUint32(0, msg.length, Endian.big); + + final frame = <int>[] + ..addAll(Connection.magic) + ..addAll(lengthBytes) + ..addAll(msg); + + try { + socketwrapper.send(frame); + } on SocketException catch (e) { + throw TimeoutException('Socket write timed out', timeout); + } + } + + + + Future<void> sendMessage(List<int> msg, {Duration? timeout}) async { + + timeout ??= this.timeout; + + final lengthBytes = Uint8List(4); + final byteData = ByteData.view(lengthBytes.buffer); + byteData.setUint32(0, msg.length, Endian.big); + + print (Connection.magic); + final frame = <int>[] + ..addAll(Connection.magic) + ..addAll(lengthBytes) + ..addAll(msg); + + try { + + StreamController<List<int>> controller = StreamController(); + + controller.stream.listen((data) { + socket?.add(data); + }); + + try { + controller.add(frame); + // Remove the socket.flush() if it doesn't help. + // await socket?.flush(); + } catch (e) { + print('Error when adding to controller: $e'); + } finally { + controller.close(); + } + + } on SocketException catch (e) { + throw TimeoutException('Socket write timed out', timeout); + } + + } + + + void close() { + socket?.close(); + } + + Future<List<int>> fillBuf2(SocketWrapper socketwrapper, List<int> recvBuf, int n, {Duration? timeout}) async { + final maxTime = timeout != null ? DateTime.now().add(timeout) : null; + + await for (var data in socketwrapper.socket!.cast<List<int>>()) { + print("DEBUG fillBuf2 1 - new data received: $data"); + if (maxTime != null && DateTime.now().isAfter(maxTime)) { + throw SocketException('Timeout'); + } + + if (data.isEmpty) { + if (recvBuf.isNotEmpty) { + throw SocketException('Connection ended mid-message.'); + } else { + throw SocketException('Connection ended while awaiting message.'); + } + } + + recvBuf.addAll(data); + print("DEBUG fillBuf2 2 - data added to recvBuf, new length: ${recvBuf.length}"); + + if (recvBuf.length >= n) { + print("DEBUG fillBuf2 3 - breaking loop, recvBuf is big enough"); + break; + } + } + + return recvBuf; + } + + Future<List<int>> fillBuf(int n, {Duration? timeout}) async { + var recvBuf = <int>[]; + socket?.listen((data) { + print('Received from server: $data'); + }, onDone: () { + print('Server closed connection.'); + socket?.destroy(); + }, onError: (error) { + print('Error: $error'); + socket?.destroy(); + }); + return recvBuf; + + + + StreamSubscription<List<int>>? subscription; // Declaration moved here + subscription = socket!.listen( + (List<int> data) { + recvBuf.addAll(data); + if (recvBuf.length >= n) { + subscription?.cancel(); + } + }, + onError: (e) { + subscription?.cancel(); + throw e; + }, + onDone: () { + print ("DEBUG ON DONE"); + if (recvBuf.length < n) { + throw SocketException('Connection closed before enough data was received'); + } + }, + ); + + if (timeout != null) { + Future.delayed(timeout, () { + if (recvBuf.length < n) { + subscription?.cancel(); + throw SocketException('Timeout'); + } + }); + } + + return recvBuf; + } + + + Future<List<int>> recv_message2(SocketWrapper socketwrapper, {Duration? timeout}) async { + if (timeout == null) { + timeout = this.timeout; + } + + final maxTime = timeout != null ? DateTime.now().add(timeout) : null; + + List<int> recvBuf = []; + int bytesRead = 0; + + print("DEBUG recv_message2 1 - about to read the header"); + + try { + await for (var data in socketwrapper.receiveStream) { + if (maxTime != null && DateTime.now().isAfter(maxTime)) { + throw SocketException('Timeout'); + } + + if (data.isEmpty) { + if (recvBuf.isNotEmpty) { + throw SocketException('Connection ended mid-message.'); + } else { + throw SocketException('Connection ended while awaiting message.'); + } + } + + recvBuf.addAll(data); + + if (bytesRead < 12) { + bytesRead += data.length; + } + + if (recvBuf.length >= 12) { + final magic = recvBuf.sublist(0, 8); + + if (!ListEquality().equals(magic, Connection.magic)) { + throw BadFrameError('Bad magic in frame: ${hex.encode(magic)}'); + } + + final byteData = ByteData.view(Uint8List.fromList(recvBuf.sublist(8, 12)).buffer); + final messageLength = byteData.getUint32(0, Endian.big); + + if (messageLength > MAX_MSG_LENGTH) { + throw BadFrameError('Got a frame with msg_length=$messageLength > $MAX_MSG_LENGTH (max)'); + } + + print("DEBUG recv_message2 3 - about to read the message body, messageLength: $messageLength"); + + print ("DEBUG recvfbuf len is "); + print (recvBuf.length); + print ("bytes read is "); + print (bytesRead); + print ("message length is "); + print(messageLength); + if (recvBuf.length == bytesRead && bytesRead == 12 + messageLength) { + final message = recvBuf.sublist(12, 12 + messageLength); + + print("DEBUG recv_message2 4 - message received, length: ${message.length}"); + print("DEBUG recv_message2 5 - message content: $message"); + + return message; + } else { + // Throwing exception if the length doesn't match + throw Exception('Message length mismatch: expected ${12 + messageLength} bytes, received ${recvBuf.length} bytes.'); + } + } + } + } on SocketException catch (e) { + print('Socket exception: $e'); + } + + // This is a default return in case of exceptions. + return []; + } + + + Future<List<int>> recv_message({Duration? timeout}) async { + + + // DEPRECATED + return []; + } + + +} // END OF CLASS diff --git a/lib/services/cashfusion/covert.dart b/lib/services/cashfusion/covert.dart new file mode 100644 index 000000000..825846548 --- /dev/null +++ b/lib/services/cashfusion/covert.dart @@ -0,0 +1,499 @@ +import 'dart:math'; +import 'dart:async'; +import 'dart:io'; +import 'dart:collection'; +import 'connection.dart'; +import 'package:protobuf/protobuf.dart' as pb; +import 'comms.dart'; +import 'fusion.pb.dart'; +import 'dart:convert'; + +const int TOR_COOLDOWN_TIME = 660; +const int TIMEOUT_INACTIVE_CONNECTION = 120; + + +class FusionError implements Exception { + String cause; + FusionError(this.cause); +} + +class Unrecoverable extends FusionError { + Unrecoverable(String cause): super(cause); +} + + + +Future<bool> isTorPort(String host, int port) async { + if (port < 0 || port > 65535) { + return false; + } + + try { + Socket sock = await Socket.connect(host, port, timeout: Duration(milliseconds: 100)); + sock.write("GET\n"); + List<int> data = await sock.first; + sock.destroy(); + if (utf8.decode(data).contains("Tor is not an HTTP Proxy")) { + return true; + } + } on SocketException { + return false; + } + + return false; +} + + + +class TorLimiter { + Queue<DateTime> deque = Queue<DateTime>(); + int lifetime; + // Declare a lock here, may need a special Dart package for this + int _count=0; + + TorLimiter(this.lifetime); + + void cleanup() {} + + int get count { + // return some default value for now + return 0; + } + + void bump() {} +} + +TorLimiter limiter = TorLimiter(TOR_COOLDOWN_TIME); + + +double randTrap(Random rng) { + final sixth = 1.0 / 6; + final f = rng.nextDouble(); + final fc = 1.0 - f; + + if (f < sixth) { + return sqrt(0.375 * f); + } else if (fc < sixth) { + return 1.0 - sqrt(0.375 * fc); + } else { + return 0.75 * f + 0.125; + } +} + + + +class CovertConnection { + Connection? connection; // replace dynamic with the type of your connection + int? slotNum; + DateTime? tPing; + int? connNumber; + Completer wakeup = Completer(); + double? delay; + + Future<bool> waitWakeupOrTime(DateTime? t) async { + if (t == null) { + return false; + } + + var remTime = t.difference(DateTime.now()).inMilliseconds; + remTime = remTime > 0 ? remTime : 0; + + await Future.delayed(Duration(milliseconds: remTime)); + wakeup.complete(true); + + var wasSet = await wakeup.future; + wakeup = Completer(); + return wasSet; + } + + void ping() { + if (this.connection != null) { + sendPb(this.connection!, CovertMessage, Ping(), + timeout: Duration(seconds: 1)); + } + + this.tPing = null; + } + + void inactive() { + throw Unrecoverable("Timed out from inactivity (this is a bug!)"); + } +} + +class CovertSlot { + int submitTimeout; + pb.GeneratedMessage? subMsg; // The work to be done. + bool done; // Whether last work requested is done. + CovertConnection? covConn; // which CovertConnection is assigned to work on this slot + CovertSlot(this.submitTimeout) : done = true; + DateTime? t_submit; + + // Define a getter for tSubmit + DateTime? get tSubmit => t_submit; + + Future<void> submit() async { + var connection = covConn?.connection; + + if (connection == null) { + throw Unrecoverable('connection is null'); + } + + await sendPb(connection, CovertMessage, subMsg!, timeout: Duration(seconds: submitTimeout)); + var result = await recvPb(connection, CovertResponse, ['ok', 'error'], timeout: Duration(seconds: submitTimeout)); + + if (result.item1 == 'error') { + throw Unrecoverable('error from server: ${result.item2}'); + } + done = true; + t_submit = DateTime.fromMillisecondsSinceEpoch(0); + covConn?.tPing = DateTime.fromMillisecondsSinceEpoch(0); // if a submission is done, no ping is needed. + } + + + +} + + + + + +class PrintError { + // Declare properties here +} + +class CovertSubmitter extends PrintError { + // Declare properties here + List<CovertSlot> slots; + bool done = true; + String failure_exception= ""; + int num_slots; + + bool stopping = false; + Map<String, dynamic>? proxyOpts; + String? randtag; + String? destAddr; + int? destPort; + bool ssl = false; + Object lock = Object(); + int countFailed = 0; + int countEstablished = 0; + int countAttempted=0; + Random rng = Random.secure(); + int? randSpan; + DateTime? stopTStart; + List<CovertConnection> spareConnections= []; + String? failureException; + int submit_timeout=0; + + CovertSubmitter( + String dest_addr, + int dest_port, + bool ssl, + String tor_host, + int tor_port, + this.num_slots, + double randSpan, // changed from int to double + double submit_timeout) // changed from int to double + : slots = List<CovertSlot>.generate(num_slots, (index) => CovertSlot(submit_timeout.toInt())) { + + // constructor body... + } + + + void wakeAll() { + for (var s in slots) { + if (s.covConn != null) { + s.covConn!.wakeup.complete(); + } + } + for (var c in spareConnections) { + c.wakeup.complete(); + } + } + + void setStopTime(int tstart) { + this.stopTStart = DateTime.fromMillisecondsSinceEpoch(tstart * 1000); + if (this.stopping) { + this.wakeAll(); + } + } + + + void stop([Exception? exception]) { + if (this.stopping) { + // already requested! + return; + } + this.failureException = exception?.toString(); + this.stopping = true; + var timeRemaining = this.stopTStart?.difference(DateTime.now()).inSeconds ?? 0; + print("Stopping; connections will close in approximately $timeRemaining seconds"); + this.wakeAll(); + } + +// PYTHON USES MULTITHREADING, WHICH ISNT IMPLEMENTED HERE YET + void scheduleConnections(DateTime tStart, Duration tSpan, {int numSpares = 0, int connectTimeout = 10}) { + var newConns = <CovertConnection>[]; + + for (var sNum = 0; sNum < this.slots.length; sNum++) { + var s = this.slots[sNum]; + if (s.covConn == null) { + s.covConn = CovertConnection(); + s.covConn?.slotNum = sNum; + CovertConnection? myCovConn = s.covConn; + if (myCovConn != null) { + newConns.add(myCovConn); + } + + + } + } + + var numNewSpares = max(0, numSpares - this.spareConnections.length); + var newSpares = List.generate(numNewSpares, (index) => CovertConnection()); + this.spareConnections = [...newSpares, ...this.spareConnections]; + + newConns.addAll(newSpares); + + for (var covConn in newConns) { + covConn.connNumber = this.countAttempted; + this.countAttempted++; + var connTime = tStart.add(Duration(seconds: (tSpan.inSeconds * randTrap(this.rng)).round())); + var randDelay = (this.randSpan ?? 0) * randTrap(this.rng); + + runConnection(covConn, connTime.millisecondsSinceEpoch, randDelay, connectTimeout); + + } + } + + + + void scheduleSubmit(int slotNum, DateTime tStart, dynamic subMsg) { + var slot = slots[slotNum]; + + assert(slot.done, "tried to set new work when prior work not done"); + + slot.subMsg = subMsg; + slot.done = false; + slot.t_submit= tStart; + var covConn = slot.covConn; + if (covConn != null) { + covConn.wakeup.complete(); + } + } + + + void scheduleSubmissions(DateTime tStart, List<dynamic> slotMessages) { + // Convert to list (Dart does not have tuples) + slotMessages = List.from(slotMessages); + + // Ensure that the number of slot messages equals the number of slots + assert(slotMessages.length == slots.length); + + // First, notify the spare connections that they will need to make a ping. + // Note that Dart does not require making a copy of the list before iteration, + // since Dart does not support mutation during iteration. + for (var c in spareConnections) { + c.tPing = tStart; + c.wakeup.complete(); + } + + // Then, notify the slots that there is a message to submit. + for (var i = 0; i < slots.length; i++) { + var slot = slots[i]; + var subMsg = slotMessages[i]; + var covConn = slot.covConn; + + if (covConn != null) { + if (subMsg == null) { + covConn.tPing = tStart; + } else { + slot.subMsg = subMsg; + slot.done = false; + slot.t_submit = tStart; + } + covConn.wakeup.complete(); + } + } + } + + + Future runConnection( + CovertConnection covConn, int connTime, double randDelay, int connectTimeout) async { + // Main loop for connection thread + DateTime connDateTime = DateTime.fromMillisecondsSinceEpoch(connTime * 1000); + while (await covConn.waitWakeupOrTime(connDateTime)) { + // if we are woken up before connection and stopping is happening, then just don't make a connection at all + if (this.stopping) { + return; + } + + final tBegin = DateTime.now().millisecondsSinceEpoch; + + try { + // STATE 1 - connecting + Map<String, dynamic> proxyOpts; + + if (this.proxyOpts == null) { + proxyOpts = {}; + } else { + final unique = 'CF${this.randtag}_${covConn.connNumber}'; + proxyOpts = { + 'proxy_username': unique, + 'proxy_password': unique, + }; + proxyOpts.addAll(this.proxyOpts!); + } + + limiter.bump(); + + try { + final connection = await openConnection( + this.destAddr!, this.destPort!, + connTimeout: connectTimeout.toDouble(), ssl: this.ssl, socksOpts: proxyOpts); + covConn.connection = connection; + } + + catch (e) { + this.countFailed++; + + final tEnd = DateTime.now().millisecondsSinceEpoch; + + print( + 'could not establish connection (after ${((tEnd - tBegin) / 1000).toStringAsFixed(3)}s): $e'); + rethrow; + } + + + this.countEstablished++; + + final tEnd = DateTime.now().millisecondsSinceEpoch; + + print( + '[${covConn.connNumber}] connection established after ${((tEnd - tBegin) / 1000).toStringAsFixed(3)}s'); + + + covConn.delay = (randTrap(this.rng) ?? 0) * (this.randSpan ?? 0); + + var lastActionTime = DateTime.now().millisecondsSinceEpoch; + + // STATE 2 - working + while (!this.stopping) { + DateTime? nextTime; + final slotNum = covConn.slotNum; + Function()? action; // callback to hold the action function + + // Second preference: submit something + if (slotNum != null) { + CovertSlot slot = this.slots[slotNum]; + nextTime = slot.tSubmit; + action = slot.submit; + } + // Third preference: send a ping + if (nextTime == null && covConn.tPing != null) { + nextTime = covConn.tPing; + action = covConn.ping; + } + // Last preference: wait doing nothing + if (nextTime == null) { + nextTime = DateTime.now().add(Duration(seconds: TIMEOUT_INACTIVE_CONNECTION)); + action = covConn.inactive; + } + + nextTime = nextTime.add(Duration(seconds: randDelay.toInt())); + + if (await covConn.waitWakeupOrTime(nextTime)) { + // got woken up ... let's go back and reevaluate what to do + continue; + } + + // reached action time, time to do it + final label = "[${covConn.connNumber}-$slotNum]"; + try { + await action?.call(); + } catch (e) { + print("$label error $e"); + rethrow; + } finally { + print("$label done"); + } + + lastActionTime = DateTime.now().millisecondsSinceEpoch; + } + + // STATE 3 - stopping + while (true) { + final stopTime = this.stopTStart?.add(Duration(seconds: randDelay.toInt())) ?? DateTime.now(); + + if (!(await covConn.waitWakeupOrTime(stopTime))) { + break; + } + } + + print("[${covConn.connNumber}] closing from stop"); + } catch (e) { + // in case of any problem, record the exception and if we have a slot, reassign it. + final exception = e; + + final slotNum = covConn.slotNum; + if (slotNum != null) { + try { + final spare = this.spareConnections.removeLast(); + // Found a spare. + this.slots[slotNum].covConn = spare; + spare.slotNum = slotNum; + spare.wakeup.complete(); // python code is using set, possibly dealing wiht multi thread...double check this is ok. + + covConn.slotNum = null; + } catch (e) { + // We failed, and there are no spares. Party is over! + + if (exception is Exception) { + this.stop(exception); + } else { + // Handle the case where the exception is not an instance of Exception + } + + } + } + } finally { + covConn.connection?.close(); + } + } + } + + + void checkOk() { + // Implement checkOk logic here + var e = this.failure_exception; + if (e != null) { + throw FusionError('Covert connections failed: ${e.runtimeType} $e'); + } + } + + void checkConnected() { + // Implement checkConnected logic here + this.checkOk(); + var numMissing = this.slots + .where((s) => s.covConn?.connection == null) + .length; + if (numMissing > 0) { + throw FusionError( + "Covert connections were too slow ($numMissing incomplete out of ${this + .slots.length})."); + } + } + + void checkDone() { + // Implement checkDone logic here + this.checkOk(); + var numMissing = this.slots + .where((s) => !s.done) + .length; + if (numMissing > 0) { + throw FusionError( + "Covert submissions were too slow ($numMissing incomplete out of ${this + .slots.length})."); + } + } +} \ No newline at end of file diff --git a/lib/services/cashfusion/encrypt.dart b/lib/services/cashfusion/encrypt.dart new file mode 100644 index 000000000..39ab8a2c5 --- /dev/null +++ b/lib/services/cashfusion/encrypt.dart @@ -0,0 +1,125 @@ +import 'dart:convert'; +import 'dart:typed_data'; +import 'package:pointycastle/pointycastle.dart' hide Mac; +import 'package:crypto/crypto.dart' as crypto; +import 'package:cryptography/cryptography.dart'; +import 'util.dart'; + +final ECDomainParameters params = ECDomainParameters('secp256k1'); +final BigInt order = params.n; + +class EncryptionFailed implements Exception {} +class DecryptionFailed implements Exception {} + +Future<Uint8List> encrypt(Uint8List message, ECPoint pubkey, {int? padToLength}) async { + ECPoint pubpoint; + try { + pubpoint = Util.ser_to_point(pubkey.getEncoded(true), params); + } catch (_) { + throw EncryptionFailed(); + } + var nonceSec = Util.secureRandomBigInt(params.n.bitLength); + var G_times_nonceSec = params.G * nonceSec; + if (G_times_nonceSec == null) { + throw Exception('Multiplication of G with nonceSec resulted in null'); + } + var noncePub = Util.point_to_ser(G_times_nonceSec, true); + + var pubpoint_times_nonceSec = pubpoint * nonceSec; + if (pubpoint_times_nonceSec == null) { + throw Exception('Multiplication of pubpoint with nonceSec resulted in null'); + } + var key = crypto.sha256.convert(Util.point_to_ser(pubpoint_times_nonceSec, true)).bytes; + + + + var plaintext = Uint8List(4 + message.length)..buffer.asByteData().setUint32(0, message.length, Endian.big)..setRange(4, 4 + message.length, message); + if (padToLength == null) { + padToLength = ((plaintext.length + 15) ~/ 16) * 16; // round up to nearest 16 + } else if (padToLength % 16 != 0) { + throw ArgumentError('$padToLength not multiple of 16'); + } + if (padToLength < plaintext.length) { + throw ArgumentError('$padToLength < ${plaintext.length}'); + } + plaintext = Uint8List(padToLength)..setRange(0, message.length + 4, plaintext); + + final secretKey = SecretKey(key); + + final macAlgorithm = Hmac(Sha256()); + + final cipher = AesCbc.with128bits(macAlgorithm: macAlgorithm); + + + final nonce = Uint8List(16); // Random nonce + final secretBox = await cipher.encrypt(plaintext, secretKey: secretKey, nonce: nonce); + + final ciphertext = secretBox.cipherText; + + return Uint8List(noncePub.length + ciphertext.length + secretBox.mac.bytes.length) + ..setRange(0, noncePub.length, noncePub) + ..setRange(noncePub.length, noncePub.length + ciphertext.length, ciphertext) + ..setRange(noncePub.length + ciphertext.length, noncePub.length + ciphertext.length + secretBox.mac.bytes.length, secretBox.mac.bytes); +} + +Future<Uint8List> decryptWithSymmkey(Uint8List data, Uint8List key) async { + if (data.length < 33 + 16 + 16) { + throw DecryptionFailed(); + } + var ciphertext = data.sublist(33, data.length - 16); + if (ciphertext.length % 16 != 0) { + throw DecryptionFailed(); + } + + final secretKey = SecretKey(key); + final cipher = AesCbc.with128bits(macAlgorithm: Hmac.sha256()); + final nonce = Uint8List(16); // Random nonce + + final secretBox = SecretBox(ciphertext, mac: Mac(data.sublist(data.length - 16)), nonce: nonce); + final plaintext = await cipher.decrypt(secretBox, secretKey: secretKey); + + if (plaintext.length < 4) { + throw DecryptionFailed(); + } + + Uint8List uint8list = Uint8List.fromList(plaintext); + ByteData byteData = ByteData.sublistView(uint8list); + var msgLength = byteData.getUint32(0, Endian.big); + + + if (msgLength + 4 > plaintext.length) { + throw DecryptionFailed(); + } + return Uint8List.fromList(plaintext.sublist(4, 4 + msgLength)); + +} + +Future<Tuple<Uint8List, Uint8List>> decrypt(Uint8List data, ECPrivateKey privkey) async { + if (data.length < 33 + 16 + 16) { + throw DecryptionFailed(); + } + var noncePub = data.sublist(0, 33); + ECPoint noncePoint; + try { + noncePoint = Util.ser_to_point(noncePub, params); + } catch (_) { + throw DecryptionFailed(); + } + + // DOUBLE CHECK THIS IS RIGHT IDEA MATCHING PYTHON. + + ECPoint G = params.G; + var key; + + if (privkey.d != null && noncePoint != null) { + var point = (G * privkey.d)! + noncePoint; + key = crypto.sha256.convert(Util.point_to_ser(point!, true)).bytes; + // ... + } else { + // Handle the situation where privkey.d or noncePoint is null + } + + var decryptedData = await decryptWithSymmkey(data, Uint8List.fromList(key)); + return Tuple(decryptedData, Uint8List.fromList(key)); +} + diff --git a/lib/services/cashfusion/fusion.dart b/lib/services/cashfusion/fusion.dart new file mode 100644 index 000000000..bcb03ac5a --- /dev/null +++ b/lib/services/cashfusion/fusion.dart @@ -0,0 +1,1583 @@ +import 'socketwrapper.dart'; +import 'package:protobuf/protobuf.dart'; +import 'dart:convert'; +import 'dart:math'; +import 'fusion.pb.dart'; +import 'util.dart'; +import 'dart:typed_data'; +import 'package:fixnum/fixnum.dart'; +import 'pedersen.dart'; +import 'dart:io'; +import 'package:crypto/crypto.dart'; +import 'dart:async'; +import 'comms.dart'; +import 'protocol.dart'; +import 'package:fixnum/fixnum.dart'; // so int and intt64 can be combined in some protobuff code +import 'encrypt.dart'; +import "package:pointycastle/export.dart"; +import 'covert.dart'; +import 'connection.dart'; +import 'package:collection/collection.dart'; +import 'package:convert/convert.dart'; +import 'validation.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; + + +class FusionError implements Exception { + final String message; + FusionError(this.message); + String toString() => "FusionError: $message"; +} + +class ComponentResult { + final Uint8List commitment; + final int counter; + final Uint8List component; + final Proof proof; + final Uint8List privateKey; + final dynamic pedersenAmount; // replace dynamic with actual type + final dynamic pedersenNonce; // replace dynamic with actual type + + ComponentResult( + this.commitment, + this.counter, + this.component, + this.proof, + this.privateKey, + {this.pedersenAmount, + this.pedersenNonce} + ); +} + +class Transaction { + List<Input> Inputs = []; + List<Output> Outputs = []; + + Transaction(); + + + static Tuple txFromComponents(List<dynamic> allComponents, List<dynamic> sessionHash) { + Transaction tx = Transaction(); // Initialize a new Transaction + // This should be based on wallet layer... implement the logic of constructing the transaction from components + // For now, it just initializes Inputs and Outputs as empty lists + tx.Inputs = []; + tx.Outputs = []; + + // For now, just returning an empty list for inputIndices + List<int> inputIndices = []; + + return Tuple(tx, inputIndices); + } + + List<int> serializePreimage(int index, int hashType, {bool useCache = true}) { + // Add implementation here + // For now, returning an empty byte array + return []; + } + + String serialize() { + // To implement... + return ""; + } + + bool isComplete() { + // implement based on wallet. + return true; + } + + String txid() { + // To implement... + return ""; + } +} + + +class Input { + List<int> prevTxid; + int prevIndex; + List<int> pubKey; + int amount; + List<dynamic> signatures =[]; + + Input({required this.prevTxid, required this.prevIndex, required this.pubKey, required this.amount}); + + int sizeOfInput() { + assert(1 < pubKey.length && pubKey.length < 76); // need to assume regular push opcode + return 108 + pubKey.length; + } + + int get value { + return amount; + } + + String getPubKey(int pubkey_index) { + // TO BE IMPLEMENTED... + return ""; + } + + String getPrivKey(int pubkey_index) { + // TO BE IMPLEMENTED... + return ""; + } + + + static Input fromInputComponent(InputComponent inputComponent) { + return Input( + prevTxid: inputComponent.prevTxid, // Make sure the types are matching + prevIndex: inputComponent.prevIndex.toInt(), + pubKey: inputComponent.pubkey, + amount: inputComponent.amount.toInt(), + ); + } + + static Input fromStackUTXO(UTXO utxo) { + return Input( + prevTxid: utf8.encode(utxo.txid), // Convert txid to a List<int> + prevIndex: utxo.vout, + pubKey: utf8.encode('0000'), // Placeholder + amount: utxo.value, + ); + } + +} + + + +class Output { + int value; + Address addr; + + int amount=0; + + Output({required this.value, required this.addr}); + + int sizeOfOutput() { + List<int> scriptpubkey = addr.toScript(); // assuming addr.toScript() returns List<int> that represents the scriptpubkey + assert(scriptpubkey.length < 253); + return 9 + scriptpubkey.length; + } + + static Output fromOutputComponent(OutputComponent outputComponent) { + Address address = Address.fromScriptPubKey(outputComponent.scriptpubkey); + return Output( + value: outputComponent.amount.toInt(), + addr: address, + ); + } + +} + + + +// Class to handle fusion +class Fusion { + + List<Input> coins = []; //"coins" and "inputs" are often synonmous in the original python code. + List<Output> outputs =[]; + bool server_connected_and_greeted = false; + bool stopping = false; + bool stopping_if_not_running = false; + String stopReason=""; + String tor_host=""; + bool server_ssl= false; + String server_host ="cashfusion.stackwallet.com"; + int server_port = 8787; + + //String server_host = "fusion.servo.cash"; + //int server_port = 8789; + + int tor_port = 0; + int roundcount = 0; + String txid=""; + + Tuple<String, String> status = Tuple("", ""); + Connection? connection; + + int numComponents =0; + double componentFeeRate=0; + double minExcessFee=0; + double maxExcessFee=0; + List<int> availableTiers =[]; + + int maxOutputs=0; + int safety_sum_in =0; + Map<int, int> safety_exess_fees = {}; + Map<int, List<int>> tierOutputs ={}; // not sure if this should be using outputs class. + + int inactiveTimeLimit = 0; + int tier = 0; + int covertPort = 0; + bool covertSSL = false; + double beginTime = 0.0; // represent time in seconds. + List<int> lastHash = <int>[]; + List<Address> reservedAddresses = <Address>[]; + int safetyExcessFee = 0; + DateTime t_fusionBegin = DateTime.now(); + Uint8List covertDomainB = Uint8List(0); + + var txInputIndices; + Transaction tx= Transaction(); + List<int> myComponentIndexes=[]; + List<int> myCommitmentIndexes=[]; + Set<int> badComponents ={}; + + Fusion () { + //initializeConnection(host, port) + } + /* + Future<void> initializeConnection(String host, int port) async { + Socket socket = await Socket.connect(host, port); + connection = Connection()..socket = socket; + } +*/ + + Future<void> add_coins_from_wallet(List<UTXO> utxoList) async { + // Convert each UTXO to an Input and add to 'coins' + for (UTXO utxo in utxoList) { + coins.add(Input.fromStackUTXO(utxo)); + } + } + + Future<void> fusion_run() async { + + print ("DEBUG FUSION 223...fusion run...."); + try { + + try { + + // Check compatibility - This was done in python version to see if fast libsec installed. + // For now , in dart, just pass this test. + ; + } on Exception catch(e) { + // handle exception, rethrow as a custom FusionError + throw FusionError("Incompatible: " + e.toString()); + } + + // Check if can connect to Tor proxy, if not, raise FusionError. Empty String treated as no host. + if (tor_host.isNotEmpty && tor_port != 0 && !await isTorPort(tor_host, tor_port)) { + throw FusionError("Can't connect to Tor proxy at $tor_host:$tor_port"); + } + + try { + // Check stop condition + check_stop(running: false); + } + catch (e) { + print (e); + } + + try { + // Check coins + check_coins(); + } + catch (e) { + print (e); + } + + + + // Connect to server + status = Tuple("connecting", ""); + try { + connection = await openConnection(server_host, server_port, connTimeout: 5.0, defaultTimeout: 5.0, ssl: server_ssl); + } catch (e) { + print("Connect failed: $e"); + String sslstr = server_ssl ? ' SSL ' : ''; + throw FusionError('Could not connect to $sslstr$server_host:$server_port'); + } + + + // Once connection is successful, wrap operations inside this block + // Within this block, version checks, downloads server params, handles coins and runs rounds + try { + + + SocketWrapper socketwrapper = SocketWrapper(server_host, server_port); + await socketwrapper.connect(); + + // Version check and download server params. + await greet(socketwrapper); + + socketwrapper.status(); + server_connected_and_greeted = true; + notify_server_status(true); + + // In principle we can hook a pause in here -- user can insert coins after seeing server params. + + try { + if (coins.isEmpty) { + throw FusionError('Started with no coins'); + return; + } + } + catch (e) { + print(e); + return; + } + + await allocateOutputs(socketwrapper); + // In principle we can hook a pause in here -- user can tweak tier_outputs, perhaps cancelling some unwanted tiers. + + // Register for tiers, wait for a pool. + await registerAndWait(socketwrapper); + + + print ("FUSION DEBUG 273"); + print ("RETURNING early in fusion_run...."); + return; + + + // launch the covert submitter + CovertSubmitter covert = await start_covert(); + try { + // Pool started. Keep running rounds until fail or complete. + while (true) { + roundcount += 1; + if (await run_round(covert)) { + break; + } + } + } finally { + covert.stop(); + } + } finally { + (await connection)?.close(); + } + + for (int i = 0; i < 60; i++) { + if (stopping) { + break; // not an error + } + + if (Util.walletHasTransaction(txid)) { + break; + } + + await Future.delayed(Duration(seconds: 1)); + } + + // Set status to 'complete' with 'time_wait' + status = Tuple('complete', 'txid: $txid'); + + // Wait for transaction to show up in wallets + // Set status to 'complete' with txid + + } on FusionError catch(err) { + print('Failed: ${err}'); + status.item1 = "failed"; + status.item2 = err.toString(); // setting the error message + } catch(exc) { + print('Exception: ${exc}'); + status.item1 = "failed"; + status.item2= "Exception: ${exc.toString()}"; // setting the exception message + } finally { + clear_coins(); + if (status.item1 != 'complete') { + for (var output in outputs) { + Util.unreserve_change_address(output.addr); + } + if (!server_connected_and_greeted) { + notify_server_status(false, tup: status); + } + } + } + + + } // end fusion_run function. + + + + + + Future<CovertSubmitter> start_covert() async { + // Function implementation here... + + // For now, just return a new instance of CovertSubmitter + return CovertSubmitter("dummy",0,true,"some_host",0,0,0,0); + } + + + Future<bool> run_round(CovertSubmitter covert) async { + // function implementation here... + + // placeholder return statement + return Future.value(false); + } + + void notify_server_status(bool b, {Tuple? tup}) { + // Function implementation goes here + } + + + void stop([String reason = 'stopped', bool notIfRunning = false]) { + if (stopping) { + return; + } + if (notIfRunning) { + if (stopping_if_not_running) { + return; + } + stopReason = reason; + stopping_if_not_running = true; + } else { + stopReason = reason; + stopping = true; + } + // note the reason is only overwritten if we were not already stopping this way. + } + + void check_stop({bool running = true}) { + // Gets called occasionally from fusion thread to allow a stop point. + if (stopping || (!running && stopping_if_not_running)) { + throw FusionError(stopReason ?? 'Unknown stop reason'); + } + } + +void check_coins() { + // Implement by calling wallet layer to check the coins are ok. + return; +} + + static void foo() { +print ("hello"); +} + + void clear_coins() { + coins = []; + } + + void addCoins(List<Input> newCoins) { + coins.addAll(newCoins); + } + + void notify_coins_UI() { + return; + } + +static bool walletCanFuse() { + return true; + + // Implement logic here to return false if the wallet can't fuse. (If its read only or non P2PKH) +} + +static double nextDoubleNonZero(Random rng) { + double value = 0.0; + while (value == 0.0) { + value = rng.nextDouble(); + } + return value; +} + + static List<int>? randomOutputsForTier(Random rng, int inputAmount, int scale, int offset, int maxCount) { + + if (inputAmount < offset) { + return []; + } + double lambd = 1.0 / scale; + int remaining = inputAmount; + List<double> values = []; // list of fractional random values without offset + bool didBreak = false; // Add this flag to detect when a break is encountered + + for (int i = 0; i < maxCount + 1; i++) { + double val = -lambd * log(nextDoubleNonZero(rng)); + remaining -= (val.ceil() + offset); + if (remaining < 0) { + didBreak = true; // If you break, set this flag to true + break; + } + values.add(val); + } + + if (!didBreak && values.length > maxCount) { + values = values.sublist(0, maxCount); + } + + if (values.isEmpty) { + // Our first try put us over the limit, so we have nothing to work with. + // (most likely, scale was too large) + return []; + } + + int desiredRandomSum = inputAmount - values.length * offset; + assert(desiredRandomSum >= 0, 'desiredRandomSum is less than 0'); + + /*Now we need to rescale and round the values so they fill up the desired. + input amount exactly. We perform rounding in cumulative space so that the + sum is exact, and the rounding is distributed fairly. + */ + + // Dart equivalent of itertools.accumulate + List<double> cumsum = []; + double sum = 0; + for (double value in values) { + sum += value; + cumsum.add(sum); + } + + double rescale = desiredRandomSum / cumsum[cumsum.length - 1]; + List<int> normedCumsum = cumsum.map((v) => (rescale * v).round()).toList(); + assert(normedCumsum[normedCumsum.length - 1] == desiredRandomSum, 'Last element of normedCumsum is not equal to desiredRandomSum'); + List<int> differences = []; + differences.add(normedCumsum[0]); // First element + for (int i = 1; i < normedCumsum.length; i++) { + differences.add(normedCumsum[i] - normedCumsum[i - 1]); + } + + List<int> result = differences.map((d) => offset + d).toList(); + assert(result.reduce((a, b) => a + b) == inputAmount, 'Sum of result is not equal to inputAmount'); + return result; + + } + + + static List<ComponentResult> genComponents(int numBlanks, List<Input> inputs, List<Output> outputs, int feerate) { + assert(numBlanks >= 0); + + List<Tuple<Component, int>> components = []; + + // Set up Pedersen setup instance + Uint8List HBytes = Uint8List.fromList([0x02] + 'CashFusion gives us fungibility.'.codeUnits); + ECDomainParameters params = ECDomainParameters('secp256k1'); + ECPoint? HMaybe = params.curve.decodePoint(HBytes); + if (HMaybe == null) { + throw Exception('Failed to decode point'); + } + ECPoint H = HMaybe; + PedersenSetup setup = PedersenSetup(H); + + for (Input input in inputs) { + int fee = Util.componentFee(input.sizeOfInput(), feerate); + + var comp = Component(); + comp.input = InputComponent( + prevTxid: Uint8List.fromList(input.prevTxid.reversed.toList()), + prevIndex: input.prevIndex, + pubkey: input.pubKey, + amount: Int64(input.amount) + ); + components.add(Tuple<Component, int>(comp, input.amount - fee)); + } + + for (Output output in outputs) { + var script = output.addr.toScript(); + int fee = Util.componentFee(output.sizeOfOutput(), feerate); + + var comp = Component(); + comp.output = OutputComponent( + scriptpubkey: script, + amount: Int64(output.value) + ); + components.add(Tuple<Component, int>(comp, -output.value - fee)); + } + + for (int i = 0; i < numBlanks; i++) { + var comp = Component(); + comp.blank = BlankComponent(); + components.add(Tuple<Component, int>(comp, 0)); + } + + List<ComponentResult> resultList = []; + + components.asMap().forEach((cnum, Tuple<Component, int> componentTuple) { + Uint8List salt = Util.tokenBytes(32); + componentTuple.item1.saltCommitment = Util.sha256(salt); + var compser = componentTuple.item1.writeToBuffer(); + + Tuple<Uint8List, Uint8List> keyPair = Util.genKeypair(); + Uint8List privateKey = keyPair.item1; + Uint8List pubKey = keyPair.item2; + + Commitment commitmentInstance = setup.commit(BigInt.from(componentTuple.item2)); + Uint8List amountCommitment = commitmentInstance.PUncompressed; + + +// Convert BigInt nonce to Uint8List + Uint8List pedersenNonce = Uint8List.fromList([int.parse(commitmentInstance.nonce.toRadixString(16), radix: 16)]); + +// Generating initial commitment + InitialCommitment commitment = InitialCommitment( + saltedComponentHash: Util.sha256(Uint8List.fromList([...compser, ...salt])), + amountCommitment: amountCommitment, + communicationKey: pubKey + ); + + Uint8List commitser = commitment.writeToBuffer(); + + // Generating proof + Proof proof = Proof( + componentIdx: cnum, + salt: salt, + pedersenNonce: pedersenNonce + ); + + // Adding result to list + resultList.add(ComponentResult(commitser, cnum, compser, proof, privateKey)); + }); + + return resultList; +} + + + Future<GeneratedMessage> recv2(SocketWrapper socketwrapper, List<String> expectedMsgNames, {Duration? timeout}) async { + if (connection == null) { + throw FusionError('Connection not initialized'); + } + + var result = await recvPb2( + socketwrapper, + connection!, + ServerMessage, + expectedMsgNames, + timeout: timeout + ); + + var submsg = result.item1; + var mtype = result.item2; + + if (mtype == 'error') { + throw FusionError('server error: ${submsg.toString()}'); + } + + return submsg; + } + + + + Future<GeneratedMessage> recv(List<String> expectedMsgNames, {Duration? timeout}) async { + // DEPRECATED + if (connection == null) { + throw FusionError('Connection not initialized'); + } + + var result = await recvPb( + connection!, + ServerMessage, + expectedMsgNames, + timeout: timeout + ); + + var submsg = result.item1; + var mtype = result.item2; + + if (mtype == 'error') { + throw FusionError('server error: ${submsg.toString()}'); + } + + return submsg; + } + + + Future<void> send(GeneratedMessage submsg, {Duration? timeout}) async { + // DEPRECATED + if (connection != null) { + await sendPb(connection!, ClientMessage, submsg, timeout: timeout); + } else { + print('Connection is null'); + } + + } + + + Future<void> send2(SocketWrapper socketwrapper, GeneratedMessage submsg, {Duration? timeout}) async { + + if (connection != null) { + await sendPb2(socketwrapper, connection!, ClientMessage, submsg, timeout: timeout); + } else { + print('Connection is null'); + } + + } + + Future<void> greet(SocketWrapper socketwrapper) async { + ClientHello clientHello = ClientHello( + version: Uint8List.fromList(utf8.encode(Protocol.VERSION)), + genesisHash: Util.get_current_genesis_hash()); + + ClientMessage clientMessage = ClientMessage() + ..clienthello = clientHello; + + //deprecated + //Connection greet_connection_1 = Connection.withoutSocket(); + + /* + lets move this up a level to the fusion_run and pass it in.... + SocketWrapper socketwrapper = SocketWrapper(server_host, server_port); + await socketwrapper.connect(); +*/ + send2(socketwrapper,clientMessage); + + + var replyMsg = await recv2(socketwrapper, ['serverhello']); + if (replyMsg is ServerMessage) { + ServerHello reply = replyMsg.serverhello; + + numComponents = reply.numComponents; + componentFeeRate = reply.componentFeerate.toDouble(); + minExcessFee = reply.minExcessFee.toDouble(); + maxExcessFee = reply.maxExcessFee.toDouble(); + availableTiers = reply.tiers.map((tier) => tier.toInt()).toList(); + + // Enforce some sensible limits, in case server is crazy + if (componentFeeRate > Protocol.MAX_COMPONENT_FEERATE) { + throw FusionError('excessive component feerate from server'); + } + if (minExcessFee > 400) { // note this threshold should be far below MAX_EXCESS_FEE + throw FusionError('excessive min excess fee from server'); + } + if (minExcessFee > maxExcessFee) { + throw FusionError('bad config on server: fees'); + } + if (numComponents < Protocol.MIN_TX_COMPONENTS * 1.5) { + throw FusionError('bad config on server: num_components'); + } + } else { + throw Exception('Received unexpected message type: ${replyMsg.runtimeType}'); + } + } + + + Future<void> allocateOutputs(socketwrapper) async { + print ("DBUG allocateoutputs 746"); + + print ("CHECK socketwrapper 746"); + socketwrapper.status(); + assert(['setup', 'connecting'].contains(status.item1)); + + List<Input> inputs = coins; + int numInputs = inputs.length; + + int maxComponents = min(numComponents, Protocol.MAX_COMPONENTS); + int maxOutputs = maxComponents - numInputs; + if (maxOutputs < 1) { + throw FusionError('Too many inputs ($numInputs >= $maxComponents)'); + } + + if (maxOutputs != null) { + assert(maxOutputs >= 1); + maxOutputs = min(maxOutputs, maxOutputs); + } + + int numDistinct = inputs.map((e) => e.value).toSet().length; + int minOutputs = max(Protocol.MIN_TX_COMPONENTS - numDistinct, 1); + if (maxOutputs < minOutputs) { + throw FusionError('Too few distinct inputs selected ($numDistinct); cannot satisfy output count constraint (>= $minOutputs, <= $maxOutputs)'); + } + + + int sumInputsValue = inputs.map((e) => e.value).reduce((a, b) => a + b); + int inputFees = inputs.map((e) => Util.componentFee(e.sizeOfInput(), componentFeeRate.toInt())).reduce((a, b) => a + b); + int availForOutputs = sumInputsValue - inputFees - minExcessFee.toInt(); + + int feePerOutput = Util.componentFee(34, componentFeeRate.toInt()); + + int offsetPerOutput = Protocol.MIN_OUTPUT + feePerOutput; + + if (availForOutputs < offsetPerOutput) { + throw FusionError('Selected inputs had too little value'); + } + + var rng = Random(); + var seed = List<int>.generate(32, (_) => rng.nextInt(256)); + + print ("DBUG allocateoutputs 785"); + tierOutputs = {}; + var excessFees = <int, int>{}; + for (var scale in availableTiers) { + int fuzzFeeMax = scale ~/ 1000000; + int fuzzFeeMaxReduced = min(fuzzFeeMax, min(Protocol.MAX_EXCESS_FEE - minExcessFee.toInt(), maxExcessFee.toInt())); + + assert(fuzzFeeMaxReduced >= 0); + int fuzzFee = rng.nextInt(fuzzFeeMaxReduced + 1); + + int reducedAvailForOutputs = availForOutputs - fuzzFee; + if (reducedAvailForOutputs < offsetPerOutput) { + continue; + } + + var outputs = randomOutputsForTier(rng, reducedAvailForOutputs, scale, offsetPerOutput, maxOutputs); + if (outputs != null) { + print (outputs); + } + if (outputs == null || outputs.length < minOutputs) { + + + continue; + } + outputs = outputs.map((o) => o - feePerOutput).toList(); + + assert(inputs.length + (outputs?.length ?? 0) <= Protocol.MAX_COMPONENTS); + + excessFees[scale] = sumInputsValue - inputFees - reducedAvailForOutputs; + tierOutputs[scale] = outputs!; + } + + + print('Possible tiers: $tierOutputs'); + + print ("CHECK socketwrapper 839"); + socketwrapper.status(); + safety_sum_in = sumInputsValue; + safety_exess_fees = excessFees; + return; + } + + + + Future<void> registerAndWait(SocketWrapper socketwrapper) async { + + // msg can be different classes depending on which protobuf msg is sent. + dynamic? msg; + + var tierOutputs = this.tierOutputs; + var tiersSorted = tierOutputs.keys.toList()..sort(); + + if (tierOutputs.isEmpty) { + throw FusionError('No outputs available at any tier (selected inputs were too small / too large).'); + } + + print('registering for tiers: $tiersSorted'); + + int self_fuse = 1; // Temporary value for now + var cashfusionTag = [1];// temp value for now + + + + check_stop(running: false); + check_coins(); + + + var tags = [JoinPools_PoolTag(id: cashfusionTag, limit: self_fuse)]; + +// Create JoinPools message + JoinPools joinPools = JoinPools( + tiers: tiersSorted.map((i) => Int64(i)).toList(), + tags: tags + ); + +// Wrap it in a ClientMessage + ClientMessage clientMessage = ClientMessage() + ..joinpools = joinPools; + + send2(socketwrapper, clientMessage); + + + status = Tuple<String, String>('waiting', 'Registered for tiers'); + + var tiersStrings = {for (var entry in tierOutputs.entries) entry.key: (entry.key * 1e-8).toStringAsFixed(8).replaceAll(RegExp(r'0+$'), '')}; + + while (true) { + var msg = await recv2(socketwrapper,['tierstatusupdate', 'fusionbegin'], timeout: Duration(seconds: 10)); + + var fieldInfoFusionBegin = msg.info_.byName["fusionbegin"]; + if (fieldInfoFusionBegin != null && msg.hasField(fieldInfoFusionBegin.tagNumber)) { + break; + } + + check_stop(running: false); + check_coins(); + + // Define the bool variable + + + + var fieldInfo = msg.info_.byName["tierstatusupdate"]; + if (fieldInfo == null) { + throw FusionError('Expected field not found in message: tierstatusupdate'); + } + + bool messageIsTierStatusUpdate = msg.hasField(fieldInfo.tagNumber); + + + if (!messageIsTierStatusUpdate) { + throw FusionError('Expected a TierStatusUpdate message'); + } + + late var statuses; + if (messageIsTierStatusUpdate) { + //TierStatusUpdate tierStatusUpdate = msg.tierstatusupdate; + var tierStatusUpdate = msg.getField(fieldInfo.tagNumber) as TierStatusUpdate; + statuses = tierStatusUpdate.statuses; + } + + + double maxfraction = 0.0; + var maxtiers = <int>[]; + int? besttime; + int? besttimetier; + for (var entry in statuses.entries) { + double frac = entry.value.players / entry.value.min_players; + if (frac >= maxfraction) { + if (frac > maxfraction) { + maxfraction = frac; + maxtiers.clear(); + } + maxtiers.add(entry.key); + } + if (entry.value.hasField('time_remaining')) { + int tr = entry.value.time_remaining; + if (besttime == null || tr < besttime) { + besttime = tr; + besttimetier = entry.key; + } + } + } + + var displayBest = <String>[]; + var displayMid = <String>[]; + var displayQueued = <String>[]; + for (var tier in tiersSorted) { + if (statuses.containsKey(tier)) { + var tierStr = tiersStrings[tier]; + if (tierStr == null) { + throw FusionError('server reported status on tier we are not registered for'); + } + if (tier == besttimetier) { + displayBest.insert(0, '**$tierStr**'); + } else if (maxtiers.contains(tier)) { + displayBest.add('[$tierStr]'); + } else { + displayMid.add(tierStr); + } + } else { + displayQueued.add(tiersStrings[tier]!); + } + } + + var parts = <String>[]; + if (displayBest.isNotEmpty || displayMid.isNotEmpty) { + parts.add("Tiers: ${displayBest.join(', ')} ${displayMid.join(', ')}"); + } + if (displayQueued.isNotEmpty) { + parts.add("Queued: ${displayQueued.join(', ')}"); + } + var tiersString = parts.join(' '); + + if (besttime == null && inactiveTimeLimit != null) { + if (DateTime.now().millisecondsSinceEpoch > inactiveTimeLimit) { + throw FusionError('stopping due to inactivity'); + } + } + + if (besttime != null) { + status = Tuple<String, String>('waiting', 'Starting in ${besttime}s. $tiersString'); + } else if (maxfraction >= 1) { + status = Tuple<String, String>('waiting', 'Starting soon. $tiersString'); + } else if (displayBest.isNotEmpty || displayMid.isNotEmpty) { + status = Tuple<String, String>('waiting', '${(maxfraction * 100).round()}% full. $tiersString'); + } else { + status = Tuple<String, String>('waiting', tiersString); + } + } + + var fieldInfoFusionBegin = msg.info_.byName["fusionbegin"]; + if (fieldInfoFusionBegin == null) { + throw FusionError('Expected field not found in message: fusionbegin'); + } + + bool messageIsFusionBegin = msg.hasField(fieldInfoFusionBegin.tagNumber); + if (!messageIsFusionBegin) { + throw FusionError('Expected a FusionBegin message'); + } + + + + + t_fusionBegin = DateTime.now(); + + + var clockMismatch = msg.serverTime - DateTime.now().millisecondsSinceEpoch / 1000; + if (clockMismatch.abs() > Protocol.MAX_CLOCK_DISCREPANCY) { + throw FusionError("Clock mismatch too large: ${clockMismatch.toStringAsFixed(3)}."); + } + + tier = msg.tier; + if (msg is FusionBegin) { + covertDomainB = Uint8List.fromList(msg.covertDomain); + } + + covertPort = msg.covertPort; + covertSSL = msg.covertSSL; + beginTime = msg.serverTime; + + lastHash = Util.calcInitialHash(tier, covertDomainB, covertPort, covertSSL, beginTime); + + var outAmounts = tierOutputs[tier]; + var outAddrs = Util.reserve_change_addresses(outAmounts?.length ?? 0); + + reservedAddresses = outAddrs; + outputs = Util.zip(outAmounts ?? [], outAddrs).map((pair) => Output(value: pair[0], addr: pair[1])).toList(); + + safetyExcessFee = safety_exess_fees[tier] ?? 0; + + print("starting fusion rounds at tier $tier: ${coins.length} inputs and ${outputs.length} outputs"); + } + + Future<CovertSubmitter> startCovert() async { + status = Tuple('running', 'Setting up Tor connections'); + + String covertDomain; + try { + covertDomain = utf8.decode(covertDomainB); + } catch (e) { + throw FusionError('badly encoded covert domain'); + } + CovertSubmitter covert = CovertSubmitter( + covertDomain, + covertPort, + covertSSL, + tor_host, + tor_port, + numComponents, + Protocol.COVERT_SUBMIT_WINDOW, + Protocol.COVERT_SUBMIT_TIMEOUT + ); + try { + covert.scheduleConnections( + t_fusionBegin, + Duration(seconds: Protocol.COVERT_CONNECT_WINDOW.toInt()), + numSpares: Protocol.COVERT_CONNECT_SPARES.toInt(), + connectTimeout: Protocol.COVERT_CONNECT_TIMEOUT.toInt() + ); + + + // loop until a just a bit before we're expecting startRound, watching for status updates + final tend = t_fusionBegin.add(Duration(seconds: (Protocol.WARMUP_TIME - Protocol.WARMUP_SLOP - 1).round())); + + while (DateTime.now().millisecondsSinceEpoch / 1000 < tend.millisecondsSinceEpoch / 1000) { + + int numConnected = covert.slots.where((s) => s.covConn?.connection != null).length; + + int numSpareConnected = covert.spareConnections.where((c) => c.connection != null).length; + + status = Tuple('running', 'Setting up Tor connections ($numConnected+$numSpareConnected out of $numComponents)'); + + await Future.delayed(Duration(seconds: 1)); + + covert.checkOk(); + this.check_stop(); + this.check_coins(); + } + } catch (e) { + covert.stop(); + rethrow; + } + + return covert; + } + + + void runRound(CovertSubmitter covert) async { + status = Tuple('running', 'Starting round ${roundcount.toString()}'); + int timeoutInSeconds = (2 * Protocol.WARMUP_SLOP + Protocol.STANDARD_TIMEOUT).toInt(); + var msg = await recv(['startround'], timeout: Duration(seconds: timeoutInSeconds)); + + // Record the time we got this message; it forms the basis time for all covert activities. + final covertT0 = DateTime.now().millisecondsSinceEpoch / 1000; + double covertClock() => (DateTime.now().millisecondsSinceEpoch / 1000) - covertT0; + + final roundTime = (msg as StartRound).serverTime; + + // Check the server's declared unix time, which will be committed. + final clockMismatch = (msg as StartRound).serverTime - DateTime.now().millisecondsSinceEpoch / 1000; + if (clockMismatch.abs() > Protocol.MAX_CLOCK_DISCREPANCY) { + throw FusionError("Clock mismatch too large: ${clockMismatch.toInt().toStringAsPrecision(3)}."); + } + + if (t_fusionBegin != null) { + // On the first startround message, check that the warmup time was within acceptable bounds. + final lag = covertT0 - (t_fusionBegin.millisecondsSinceEpoch / 1000) - Protocol.WARMUP_TIME; + if (lag.abs() > Protocol.WARMUP_SLOP) { + throw FusionError("Warmup period too different from expectation (|${lag.toStringAsFixed(3)}s| > ${Protocol.WARMUP_SLOP.toStringAsFixed(3)}s)."); + } + t_fusionBegin = DateTime.now(); + } + + print("round starting at ${DateTime.now().millisecondsSinceEpoch / 1000}"); + + final inputFees = coins.map((e) => Util.componentFee(e.sizeOfInput(), componentFeeRate.toInt())).reduce((a, b) => a + b); + final outputFees = outputs.length * Util.componentFee(34, componentFeeRate.toInt()); + + final sumIn = coins.map((e) => e.amount).reduce((a, b) => a + b); + final sumOut = outputs.map((e) => e.value).reduce((a, b) => a + b); + + final totalFee = sumIn - sumOut; + final excessFee = totalFee - inputFees - outputFees; + final safeties = [ + sumIn == safety_sum_in, + excessFee == safetyExcessFee, + excessFee <= Protocol.MAX_EXCESS_FEE, + totalFee <= Protocol.MAX_FEE, + ]; + + if (!safeties.every((element) => element)) { + throw Exception("(BUG!) Funds re-check failed -- aborting for safety. ${safeties.toString()}"); + } + + final roundPubKey = (msg as StartRound).roundPubkey; + + final blindNoncePoints = (msg as StartRound).blindNoncePoints; + if (blindNoncePoints.length != numComponents) { + throw FusionError('blind nonce miscount'); + } + + final numBlanks = numComponents - coins.length - outputs.length; + final List<ComponentResult> genComponentsResults = genComponents(numBlanks, coins, outputs, componentFeeRate.toInt()); + + final List<Uint8List> myCommitments = []; + final List<int> myComponentSlots = []; + final List<Uint8List> myComponents = []; + final List<Proof> myProofs = []; + final List<Uint8List> privKeys = []; + final List<dynamic> pedersenAmount = []; // replace dynamic with the actual type + final List<dynamic> pedersenNonce = []; // replace dynamic with the actual type + + for (var genComponentResult in genComponentsResults) { + myCommitments.add(genComponentResult.commitment); + myComponentSlots.add(genComponentResult.counter); + myComponents.add(genComponentResult.component); + myProofs.add(genComponentResult.proof); + privKeys.add(genComponentResult.privateKey); + pedersenAmount.add(genComponentResult.pedersenAmount); + pedersenNonce.add(genComponentResult.pedersenNonce); + } + assert(excessFee == pedersenAmount.reduce((a, b) => a + b)); // sanity check that we didn't mess up the above + assert(myComponents.toSet().length == myComponents.length); // no duplicates + + // Need to implement this! schnorr is from EC schnorr.py + var blindSigRequests = <dynamic>[]; + + /* + final blindSigRequests = blindNoncePoints.map((e) => Schnorr.BlindSignatureRequest(roundPubKey, e, sha256(myComponents.elementAt(e)))).toList(); + +*/ + final randomNumber = Util.getRandomBytes(32); + covert.checkOk(); + check_stop(); + check_coins(); + + + await send(PlayerCommit( + initialCommitments: myCommitments, + excessFee: Int64(excessFee), + pedersenTotalNonce: pedersenNonce.cast<int>(), + randomNumberCommitment: sha256.convert(randomNumber).bytes, + blindSigRequests: blindSigRequests.map((r) => r.getRequest() as List<int>).toList(), + )); + + + msg = await recv(['blindsigresponses'], timeout: Duration(seconds: Protocol.T_START_COMPS.toInt())); + + + if (msg is BlindSigResponses) { + var typedMsg = msg as BlindSigResponses; + assert(typedMsg.scalars.length == blindSigRequests.length); + } else { + // Handle the case where msg is not of type BlindSigResponses + throw Exception('Unexpected message type: ${msg.runtimeType}'); + } + + final blindSigs = List.generate( + blindSigRequests.length, + (index) { + if (msg is BlindSigResponses) { + var typedMsg = msg as BlindSigResponses; + return blindSigRequests[index].finalize(typedMsg.scalars[index], check: true); + } else { + // Handle the case where msg is not of type BlindSigResponses + throw Exception('Unexpected message type: ${msg.runtimeType}'); + } + }, + ); + + +// Sleep until the covert component phase really starts, to catch covert connection failures. + var remainingTime = Protocol.T_START_COMPS - covertClock(); + if (remainingTime < 0) { + throw FusionError('Arrived at covert-component phase too slowly.'); + } + await Future.delayed(Duration(seconds: remainingTime.floor())); + +// Our final check to leave the fusion pool, before we start telling our +// components. This is much more annoying since it will cause the round +// to fail, but since we would end up killing the round anyway then it's +// best for our privacy if we just leave now. +// (This also is our first call to check_connected.) + covert.checkConnected(); + check_coins(); + +// Start covert component submissions + print("starting covert component submission"); + status = Tuple('running', 'covert submission: components'); + +// If we fail after this point, we want to stop connections gradually and +// randomly. We don't want to stop them all at once, since if we had already +// provided our input components then it would be a leak to have them all drop at once. + covert.setStopTime((covertT0 + Protocol.T_START_CLOSE).toInt()); + + + // Schedule covert submissions. + List<CovertComponent?> messages = List.filled(myComponents.length, null); + + for (var i = 0; i < myComponents.length; i++) { + messages[myComponentSlots[i]] = CovertComponent( + roundPubkey: roundPubKey, + signature: blindSigs[i], + component: myComponents[i] + ); + } + if (messages.any((element) => element == null)) { + throw FusionError('Messages list includes null values.'); + } + + final targetDateTime = DateTime.fromMillisecondsSinceEpoch(((covertT0 + Protocol.T_START_COMPS) * 1000).toInt()); + covert.scheduleSubmissions(targetDateTime, messages); + + + // While submitting, we download the (large) full commitment list. + msg = await recv(['allcommitments'], timeout: Duration(seconds: Protocol.T_START_SIGS.toInt())); + AllCommitments allCommitmentsMsg = msg as AllCommitments; + List<InitialCommitment> allCommitments = allCommitmentsMsg.initialCommitments.map((commitmentBytes) { + return InitialCommitment.fromBuffer(commitmentBytes); + }).toList(); + + + // Quick check on the commitment list. + if (allCommitments.toSet().length != allCommitments.length) { + throw FusionError('Commitments list includes duplicates.'); + } + try { + List<Uint8List> allCommitmentsBytes = allCommitments.map((commitment) => commitment.writeToBuffer()).toList(); + myCommitmentIndexes = myCommitments.map((c) => allCommitmentsBytes.indexOf(c)).toList(); + + + } on Exception { + throw FusionError('One or more of my commitments missing.'); + } + + remainingTime = Protocol.T_START_SIGS - covertClock(); + if (remainingTime < 0) { + throw FusionError('took too long to download commitments list'); + } + + // Once all components are received, the server shares them with us: + msg = await recv(['sharecovertcomponents'], timeout: Duration(seconds: Protocol.T_START_SIGS.toInt())); + + ShareCovertComponents shareCovertComponentsMsg = msg as ShareCovertComponents; + List<List<int>> allComponents = shareCovertComponentsMsg.components; + bool skipSignatures = msg.getField(2); + + // Critical check on server's response timing. + if (covertClock() > Protocol.T_START_SIGS) { + throw FusionError('Shared components message arrived too slowly.'); + } + + covert.checkDone(); + + try { + myComponentIndexes = myComponents.map((c) => allComponents.indexWhere((element) => ListEquality().equals(element, c))).toList(); + if (myComponentIndexes.contains(-1)) { + throw FusionError('One or more of my components missing.'); + } + } on StateError { + throw FusionError('One or more of my components missing.'); + } + + // Need to implement: check the components list and see if there are enough inputs/outputs + // for there to be significant privacy. + + List<List<int>> allCommitmentsBytes = allCommitments.map((commitment) => commitment.writeToBuffer().toList()).toList(); + List<int> sessionHash = Util.calcRoundHash(lastHash, roundPubKey, roundTime.toInt(), allCommitmentsBytes, allComponents); + + + if (shareCovertComponentsMsg.sessionHash != null && !ListEquality().equals(shareCovertComponentsMsg.sessionHash, sessionHash)) { + + throw FusionError('Session hash mismatch (bug!)'); + } + + if (!shareCovertComponentsMsg.skipSignatures) { + print("starting covert signature submission"); + status = Tuple('running', 'covert submission: signatures'); + + if (allComponents + .toSet() + .length != allComponents.length) { + throw FusionError('Server component list includes duplicates.'); + } + + + var txInputIndices = Transaction.txFromComponents( + allComponents, sessionHash); + + + Tuple txData = Transaction.txFromComponents(allComponents, sessionHash); + tx = txData.item1; + List<int> inputIndices = txData.item2; + + + List< + CovertTransactionSignature?> covertTransactionSignatureMessages = List< + CovertTransactionSignature?>.filled(myComponents.length, null); + + var my_combined = List<Tuple<int, Input>>.generate( + inputIndices.length, + (index) => Tuple(inputIndices[index], tx.Inputs[index]), + ); + + + + for (var i = 0; i < my_combined.length; i++) { + int cIdx = my_combined[i].item1; + Input inp = my_combined[i].item2; + + int myCompIdx = myComponentIndexes.indexOf(cIdx); + if (myCompIdx == -1) continue; // not my input + + var pubKey = inp.getPubKey(0); + var sec = inp.getPrivKey(0); + + var preimageBytes = tx.serializePreimage(i, 0x41, useCache: true); + var sighash = sha256.convert(sha256.convert(preimageBytes).bytes); + + //var sig = schnorr.sign(sec, sighash); // Needs implementation + var sig = <int>[0, 1, 2, 3, 4]; // dummy placeholder + + covertTransactionSignatureMessages[myComponentSlots[myCompIdx]] = + CovertTransactionSignature(txsignature: sig, whichInput: i); + } + + DateTime covertT0DateTime = DateTime.fromMillisecondsSinceEpoch( + covertT0.toInt() * 1000); // covertT0 is in seconds + covert.scheduleSubmissions( + covertT0DateTime.add( + Duration(milliseconds: Protocol.T_START_SIGS.toInt())), + covertTransactionSignatureMessages + ); + + + // wait for result + int timeoutMillis = (Protocol.T_EXPECTING_CONCLUSION - + Protocol.TS_EXPECTING_COVERT_COMPONENTS).toInt(); + Duration timeout = Duration(milliseconds: timeoutMillis); + msg = await recv(['fusionresult'], timeout: timeout); + + + // Critical check on server's response timing. + if (covertClock() > Protocol.T_EXPECTING_CONCLUSION) { + throw FusionError('Fusion result message arrived too slowly.'); + } + + covert.checkDone(); + FusionResult fusionResultMsg = msg as FusionResult; + if (fusionResultMsg.ok) { + List<List<int>> allSigs = msg.txsignatures; + + // assemble the transaction. + if (allSigs.length != tx.Inputs.length) { + throw FusionError('Server gave wrong number of signatures.'); + } + for (var i = 0; i < allSigs.length; i++) { + List<int> sigBytes = allSigs[i]; + String sig = base64.encode(sigBytes); + Input inp = tx.Inputs[i]; + if (sig.length != 64) { + throw FusionError('server relayed bad signature'); + } + inp.signatures = [sig + '41']; + } + + assert(tx.isComplete()); + String txHex = tx.serialize(); + + txid = tx.txid(); + String sumInStr = Util.formatSatoshis(sumIn, + numZeros: 8); + String feeStr = totalFee + .toString(); + String feeLoc = 'fee'; + + String label = "CashFusion ${coins.length}⇢${outputs + .length}, ${sumInStr} BCH (−${feeStr} sats ${feeLoc})"; + + Util.updateWalletLabel(txid, label); + } + + else { + badComponents = msg.badComponents.toSet(); + if (badComponents.intersection(myComponentIndexes.toSet()).isNotEmpty) { + print("bad components: ${badComponents.toList()} mine: ${myComponentIndexes.toList()}"); + throw FusionError("server thinks one of my components is bad!"); + } + } + + + } + else { // skip_signatures True + Set<int> badComponents = Set<int>(); + } + +// ### Blame phase ### + + + covert.setStopTime((covertT0 + Protocol.T_START_CLOSE_BLAME).floor()); + + print("sending proofs"); + status = Tuple('running', 'round failed - sending proofs'); + + +// create a list of commitment indexes, but leaving out mine. + List<int> othersCommitmentIdxes = []; + for(int i=0; i<allCommitments.length; i++) { + if (!myCommitmentIndexes.contains(i)) { + othersCommitmentIdxes.add(i); + } + } + int N = othersCommitmentIdxes.length; + assert(N == allCommitments.length - myCommitments.length); + if (N == 0) { + throw FusionError("Fusion failed with only me as player -- I can only blame myself."); + } + +// where should I send my proofs? + List<InitialCommitment> dstCommits = []; + for(int i=0; i<myCommitments.length; i++) { + dstCommits.add(allCommitments[othersCommitmentIdxes[Util.randPosition(randomNumber, N, i)]]); + } + +// generate the encrypted proofs + List<String> encproofs = List<String>.filled(myCommitments.length, ''); + + + ECDomainParameters params = ECDomainParameters('secp256k1'); + for (int i=0; i<dstCommits.length; i++) { + InitialCommitment msg = dstCommits[i]; + Proof proof = myProofs[i]; + proof.componentIdx = myComponentIndexes[i]; + + ECPoint? communicationKeyPointMaybe = params.curve.decodePoint(Uint8List.fromList(msg.communicationKey)); + if (communicationKeyPointMaybe == null) { + // handle the error case here, e.g., throw an exception or skip this iteration. + continue; + } + ECPoint communicationKeyPoint = communicationKeyPointMaybe; + + try { + Uint8List encryptedData = await encrypt(proof.writeToBuffer(), communicationKeyPoint, padToLength: 80); + encproofs[i] = String.fromCharCodes(encryptedData); + } catch (EncryptionFailed) { + // The communication key was bad (probably invalid x coordinate). + // We will just send a blank. They can't even blame us since there is no private key! :) + continue; + } + } + + List<Uint8List> encodedEncproofs = encproofs.map((e) => Uint8List.fromList(e.codeUnits)).toList(); + this.send(MyProofsList(encryptedProofs: encodedEncproofs, randomNumber: randomNumber)); + + status = Tuple('running', 'round failed - checking proofs'); + + print("receiving proofs"); + msg = await this.recv(['theirproofslist'], timeout: Duration(seconds: (2 * Protocol.STANDARD_TIMEOUT).round())); + + List<Blames_BlameProof> blames = []; + + int countInputs = 0; + + TheirProofsList proofsList = msg as TheirProofsList; + + var privKey; + var commitmentBlob; + for (var i = 0; i < proofsList.proofs.length; i++) { + var rp = msg.proofs[i]; + try { + privKey = privKeys[rp.dstKeyIdx]; + commitmentBlob = allCommitments[rp.srcCommitmentIdx]; + } on RangeError catch (e) { + throw FusionError("Server relayed bad proof indices"); + } + + var sKey; + var proofBlob; + + + + try { + var result = await decrypt(Uint8List.fromList(rp.encryptedProof), privKey); + proofBlob = result.item1; // First item is the decrypted data + sKey = result.item2; // Second item is the symmetric key + } on Exception catch (e) { + print("found an undecryptable proof"); + blames.add(Blames_BlameProof(whichProof: i, privkey: privKey, blameReason: 'undecryptable')); + continue; + } + + + var commitment = InitialCommitment(); + try { + commitment.mergeFromBuffer(commitmentBlob); // Method to parse protobuf data + } on FormatException catch (e) { + throw FusionError("Server relayed bad commitment"); + } + + var inpComp; + + try { + // Convert allComponents to List<Uint8List> + List<Uint8List> allComponentsUint8 = allComponents.map((component) => Uint8List.fromList(component)).toList(); + // Convert badComponents to List<int> + List<int> badComponentsList = badComponents.toList(); + // Convert componentFeeRate to int if it's double + int componentFeerateInt = componentFeeRate.round(); // or use .toInt() if you want to truncate instead of rounding + + var inpComp = validateProofInternal(proofBlob, commitment, allComponentsUint8, badComponentsList, componentFeerateInt); + } on Exception catch (e) { + print("found an erroneous proof: ${e.toString()}"); + var blameProof = Blames_BlameProof(); + blameProof.whichProof = i; + blameProof.sessionKey = sKey; + blameProof.blameReason = e.toString(); + blames.add(blameProof); + continue; + } + + + if (inpComp != null) { + countInputs++; + try { + Util.checkInputElectrumX(inpComp); + } on Exception catch (e) { + print("found a bad input [${rp.srcCommitmentIdx}]: $e (${inpComp.prevTxid.reversed.toList().toHex()}:${inpComp.prevIndex})"); + + var blameProof = Blames_BlameProof(); + blameProof.whichProof = i; + blameProof.sessionKey = sKey; + blameProof.blameReason = 'input does not match blockchain: ' + e.toString(); + blameProof.needLookupBlockchain = true; + blames.add(blameProof); + + } catch (e) { + print("verified an input internally, but was unable to check it against blockchain: ${e}"); + } + } + + + } + print("checked ${msg.proofs.length} proofs, $countInputs of them inputs"); + + print("sending blames"); + send(Blames(blames: blames)); + + status = Tuple('running', 'awaiting restart'); + +// Await the final 'restartround' message. It might take some time +// to arrive since other players might be slow, and then the server +// itself needs to check blockchain. + await recv(['restartround'], timeout: Duration(seconds: 2 * (Protocol.STANDARD_TIMEOUT.round() + Protocol.BLAME_VERIFY_TIME.round()))); + + + } // end of run_round() function. + + + + +} // END OF CLASS + diff --git a/lib/services/cashfusion/fusion.pb.dart b/lib/services/cashfusion/fusion.pb.dart new file mode 100644 index 000000000..dac659f95 --- /dev/null +++ b/lib/services/cashfusion/fusion.pb.dart @@ -0,0 +1,2501 @@ +/// +// Generated code. Do not modify. +// source: fusion.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name + +import 'dart:core' as $core; + +import 'package:fixnum/fixnum.dart' as $fixnum; +import 'package:protobuf/protobuf.dart' as $pb; + +class InputComponent extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'InputComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'prevTxid', $pb.PbFieldType.QY) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'prevIndex', $pb.PbFieldType.QU3) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pubkey', $pb.PbFieldType.QY) + ..a<$fixnum.Int64>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amount', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ; + + InputComponent._() : super(); + factory InputComponent({ + $core.List<$core.int>? prevTxid, + $core.int? prevIndex, + $core.List<$core.int>? pubkey, + $fixnum.Int64? amount, + }) { + final _result = create(); + if (prevTxid != null) { + _result.prevTxid = prevTxid; + } + if (prevIndex != null) { + _result.prevIndex = prevIndex; + } + if (pubkey != null) { + _result.pubkey = pubkey; + } + if (amount != null) { + _result.amount = amount; + } + return _result; + } + factory InputComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory InputComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + InputComponent clone() => InputComponent()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + InputComponent copyWith(void Function(InputComponent) updates) => super.copyWith((message) => updates(message as InputComponent)) as InputComponent; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static InputComponent create() => InputComponent._(); + InputComponent createEmptyInstance() => create(); + static $pb.PbList<InputComponent> createRepeated() => $pb.PbList<InputComponent>(); + @$core.pragma('dart2js:noInline') + static InputComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<InputComponent>(create); + static InputComponent? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get prevTxid => $_getN(0); + @$pb.TagNumber(1) + set prevTxid($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasPrevTxid() => $_has(0); + @$pb.TagNumber(1) + void clearPrevTxid() => clearField(1); + + @$pb.TagNumber(2) + $core.int get prevIndex => $_getIZ(1); + @$pb.TagNumber(2) + set prevIndex($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasPrevIndex() => $_has(1); + @$pb.TagNumber(2) + void clearPrevIndex() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get pubkey => $_getN(2); + @$pb.TagNumber(3) + set pubkey($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasPubkey() => $_has(2); + @$pb.TagNumber(3) + void clearPubkey() => clearField(3); + + @$pb.TagNumber(4) + $fixnum.Int64 get amount => $_getI64(3); + @$pb.TagNumber(4) + set amount($fixnum.Int64 v) { $_setInt64(3, v); } + @$pb.TagNumber(4) + $core.bool hasAmount() => $_has(3); + @$pb.TagNumber(4) + void clearAmount() => clearField(4); +} + +class OutputComponent extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'OutputComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scriptpubkey', $pb.PbFieldType.QY) + ..a<$fixnum.Int64>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amount', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ; + + OutputComponent._() : super(); + factory OutputComponent({ + $core.List<$core.int>? scriptpubkey, + $fixnum.Int64? amount, + }) { + final _result = create(); + if (scriptpubkey != null) { + _result.scriptpubkey = scriptpubkey; + } + if (amount != null) { + _result.amount = amount; + } + return _result; + } + factory OutputComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory OutputComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + OutputComponent clone() => OutputComponent()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + OutputComponent copyWith(void Function(OutputComponent) updates) => super.copyWith((message) => updates(message as OutputComponent)) as OutputComponent; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static OutputComponent create() => OutputComponent._(); + OutputComponent createEmptyInstance() => create(); + static $pb.PbList<OutputComponent> createRepeated() => $pb.PbList<OutputComponent>(); + @$core.pragma('dart2js:noInline') + static OutputComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OutputComponent>(create); + static OutputComponent? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get scriptpubkey => $_getN(0); + @$pb.TagNumber(1) + set scriptpubkey($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasScriptpubkey() => $_has(0); + @$pb.TagNumber(1) + void clearScriptpubkey() => clearField(1); + + @$pb.TagNumber(2) + $fixnum.Int64 get amount => $_getI64(1); + @$pb.TagNumber(2) + set amount($fixnum.Int64 v) { $_setInt64(1, v); } + @$pb.TagNumber(2) + $core.bool hasAmount() => $_has(1); + @$pb.TagNumber(2) + void clearAmount() => clearField(2); +} + +class BlankComponent extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlankComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..hasRequiredFields = false + ; + + BlankComponent._() : super(); + factory BlankComponent() => create(); + factory BlankComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory BlankComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + BlankComponent clone() => BlankComponent()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + BlankComponent copyWith(void Function(BlankComponent) updates) => super.copyWith((message) => updates(message as BlankComponent)) as BlankComponent; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static BlankComponent create() => BlankComponent._(); + BlankComponent createEmptyInstance() => create(); + static $pb.PbList<BlankComponent> createRepeated() => $pb.PbList<BlankComponent>(); + @$core.pragma('dart2js:noInline') + static BlankComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BlankComponent>(create); + static BlankComponent? _defaultInstance; +} + +enum Component_Component { + input, + output, + blank, + notSet +} + +class Component extends $pb.GeneratedMessage { + static const $core.Map<$core.int, Component_Component> _Component_ComponentByTag = { + 2 : Component_Component.input, + 3 : Component_Component.output, + 4 : Component_Component.blank, + 0 : Component_Component.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Component', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [2, 3, 4]) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'saltCommitment', $pb.PbFieldType.QY) + ..aOM<InputComponent>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'input', subBuilder: InputComponent.create) + ..aOM<OutputComponent>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'output', subBuilder: OutputComponent.create) + ..aOM<BlankComponent>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blank', subBuilder: BlankComponent.create) + ; + + Component._() : super(); + factory Component({ + $core.List<$core.int>? saltCommitment, + InputComponent? input, + OutputComponent? output, + BlankComponent? blank, + }) { + final _result = create(); + if (saltCommitment != null) { + _result.saltCommitment = saltCommitment; + } + if (input != null) { + _result.input = input; + } + if (output != null) { + _result.output = output; + } + if (blank != null) { + _result.blank = blank; + } + return _result; + } + factory Component.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Component.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Component clone() => Component()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Component copyWith(void Function(Component) updates) => super.copyWith((message) => updates(message as Component)) as Component; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Component create() => Component._(); + Component createEmptyInstance() => create(); + static $pb.PbList<Component> createRepeated() => $pb.PbList<Component>(); + @$core.pragma('dart2js:noInline') + static Component getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Component>(create); + static Component? _defaultInstance; + + Component_Component whichComponent() => _Component_ComponentByTag[$_whichOneof(0)]!; + void clearComponent() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.List<$core.int> get saltCommitment => $_getN(0); + @$pb.TagNumber(1) + set saltCommitment($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasSaltCommitment() => $_has(0); + @$pb.TagNumber(1) + void clearSaltCommitment() => clearField(1); + + @$pb.TagNumber(2) + InputComponent get input => $_getN(1); + @$pb.TagNumber(2) + set input(InputComponent v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasInput() => $_has(1); + @$pb.TagNumber(2) + void clearInput() => clearField(2); + @$pb.TagNumber(2) + InputComponent ensureInput() => $_ensure(1); + + @$pb.TagNumber(3) + OutputComponent get output => $_getN(2); + @$pb.TagNumber(3) + set output(OutputComponent v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasOutput() => $_has(2); + @$pb.TagNumber(3) + void clearOutput() => clearField(3); + @$pb.TagNumber(3) + OutputComponent ensureOutput() => $_ensure(2); + + @$pb.TagNumber(4) + BlankComponent get blank => $_getN(3); + @$pb.TagNumber(4) + set blank(BlankComponent v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasBlank() => $_has(3); + @$pb.TagNumber(4) + void clearBlank() => clearField(4); + @$pb.TagNumber(4) + BlankComponent ensureBlank() => $_ensure(3); +} + +class InitialCommitment extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'InitialCommitment', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'saltedComponentHash', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amountCommitment', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'communicationKey', $pb.PbFieldType.QY) + ; + + InitialCommitment._() : super(); + factory InitialCommitment({ + $core.List<$core.int>? saltedComponentHash, + $core.List<$core.int>? amountCommitment, + $core.List<$core.int>? communicationKey, + }) { + final _result = create(); + if (saltedComponentHash != null) { + _result.saltedComponentHash = saltedComponentHash; + } + if (amountCommitment != null) { + _result.amountCommitment = amountCommitment; + } + if (communicationKey != null) { + _result.communicationKey = communicationKey; + } + return _result; + } + factory InitialCommitment.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory InitialCommitment.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + InitialCommitment clone() => InitialCommitment()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + InitialCommitment copyWith(void Function(InitialCommitment) updates) => super.copyWith((message) => updates(message as InitialCommitment)) as InitialCommitment; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static InitialCommitment create() => InitialCommitment._(); + InitialCommitment createEmptyInstance() => create(); + static $pb.PbList<InitialCommitment> createRepeated() => $pb.PbList<InitialCommitment>(); + @$core.pragma('dart2js:noInline') + static InitialCommitment getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<InitialCommitment>(create); + static InitialCommitment? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get saltedComponentHash => $_getN(0); + @$pb.TagNumber(1) + set saltedComponentHash($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasSaltedComponentHash() => $_has(0); + @$pb.TagNumber(1) + void clearSaltedComponentHash() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get amountCommitment => $_getN(1); + @$pb.TagNumber(2) + set amountCommitment($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasAmountCommitment() => $_has(1); + @$pb.TagNumber(2) + void clearAmountCommitment() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get communicationKey => $_getN(2); + @$pb.TagNumber(3) + set communicationKey($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasCommunicationKey() => $_has(2); + @$pb.TagNumber(3) + void clearCommunicationKey() => clearField(3); +} + +class Proof extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Proof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'componentIdx', $pb.PbFieldType.QF3) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'salt', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pedersenNonce', $pb.PbFieldType.QY) + ; + + Proof._() : super(); + factory Proof({ + $core.int? componentIdx, + $core.List<$core.int>? salt, + $core.List<$core.int>? pedersenNonce, + }) { + final _result = create(); + if (componentIdx != null) { + _result.componentIdx = componentIdx; + } + if (salt != null) { + _result.salt = salt; + } + if (pedersenNonce != null) { + _result.pedersenNonce = pedersenNonce; + } + return _result; + } + factory Proof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Proof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Proof clone() => Proof()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Proof copyWith(void Function(Proof) updates) => super.copyWith((message) => updates(message as Proof)) as Proof; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Proof create() => Proof._(); + Proof createEmptyInstance() => create(); + static $pb.PbList<Proof> createRepeated() => $pb.PbList<Proof>(); + @$core.pragma('dart2js:noInline') + static Proof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Proof>(create); + static Proof? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get componentIdx => $_getIZ(0); + @$pb.TagNumber(1) + set componentIdx($core.int v) { $_setUnsignedInt32(0, v); } + @$pb.TagNumber(1) + $core.bool hasComponentIdx() => $_has(0); + @$pb.TagNumber(1) + void clearComponentIdx() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get salt => $_getN(1); + @$pb.TagNumber(2) + set salt($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasSalt() => $_has(1); + @$pb.TagNumber(2) + void clearSalt() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get pedersenNonce => $_getN(2); + @$pb.TagNumber(3) + set pedersenNonce($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasPedersenNonce() => $_has(2); + @$pb.TagNumber(3) + void clearPedersenNonce() => clearField(3); +} + +class ClientHello extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ClientHello', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'version', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'genesisHash', $pb.PbFieldType.OY) + ; + + ClientHello._() : super(); + factory ClientHello({ + $core.List<$core.int>? version, + $core.List<$core.int>? genesisHash, + }) { + final _result = create(); + if (version != null) { + _result.version = version; + } + if (genesisHash != null) { + _result.genesisHash = genesisHash; + } + return _result; + } + factory ClientHello.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ClientHello.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ClientHello clone() => ClientHello()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ClientHello copyWith(void Function(ClientHello) updates) => super.copyWith((message) => updates(message as ClientHello)) as ClientHello; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ClientHello create() => ClientHello._(); + ClientHello createEmptyInstance() => create(); + static $pb.PbList<ClientHello> createRepeated() => $pb.PbList<ClientHello>(); + @$core.pragma('dart2js:noInline') + static ClientHello getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ClientHello>(create); + static ClientHello? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get version => $_getN(0); + @$pb.TagNumber(1) + set version($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasVersion() => $_has(0); + @$pb.TagNumber(1) + void clearVersion() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get genesisHash => $_getN(1); + @$pb.TagNumber(2) + set genesisHash($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasGenesisHash() => $_has(1); + @$pb.TagNumber(2) + void clearGenesisHash() => clearField(2); +} + +class ServerHello extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ServerHello', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tiers', $pb.PbFieldType.PU6) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'numComponents', $pb.PbFieldType.QU3) + ..a<$fixnum.Int64>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'componentFeerate', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'minExcessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ..a<$fixnum.Int64>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'maxExcessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ..aOS(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'donationAddress') + ; + + ServerHello._() : super(); + factory ServerHello({ + $core.Iterable<$fixnum.Int64>? tiers, + $core.int? numComponents, + $fixnum.Int64? componentFeerate, + $fixnum.Int64? minExcessFee, + $fixnum.Int64? maxExcessFee, + $core.String? donationAddress, + }) { + final _result = create(); + if (tiers != null) { + _result.tiers.addAll(tiers); + } + if (numComponents != null) { + _result.numComponents = numComponents; + } + if (componentFeerate != null) { + _result.componentFeerate = componentFeerate; + } + if (minExcessFee != null) { + _result.minExcessFee = minExcessFee; + } + if (maxExcessFee != null) { + _result.maxExcessFee = maxExcessFee; + } + if (donationAddress != null) { + _result.donationAddress = donationAddress; + } + return _result; + } + factory ServerHello.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ServerHello.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ServerHello clone() => ServerHello()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ServerHello copyWith(void Function(ServerHello) updates) => super.copyWith((message) => updates(message as ServerHello)) as ServerHello; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ServerHello create() => ServerHello._(); + ServerHello createEmptyInstance() => create(); + static $pb.PbList<ServerHello> createRepeated() => $pb.PbList<ServerHello>(); + @$core.pragma('dart2js:noInline') + static ServerHello getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ServerHello>(create); + static ServerHello? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$fixnum.Int64> get tiers => $_getList(0); + + @$pb.TagNumber(2) + $core.int get numComponents => $_getIZ(1); + @$pb.TagNumber(2) + set numComponents($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasNumComponents() => $_has(1); + @$pb.TagNumber(2) + void clearNumComponents() => clearField(2); + + @$pb.TagNumber(4) + $fixnum.Int64 get componentFeerate => $_getI64(2); + @$pb.TagNumber(4) + set componentFeerate($fixnum.Int64 v) { $_setInt64(2, v); } + @$pb.TagNumber(4) + $core.bool hasComponentFeerate() => $_has(2); + @$pb.TagNumber(4) + void clearComponentFeerate() => clearField(4); + + @$pb.TagNumber(5) + $fixnum.Int64 get minExcessFee => $_getI64(3); + @$pb.TagNumber(5) + set minExcessFee($fixnum.Int64 v) { $_setInt64(3, v); } + @$pb.TagNumber(5) + $core.bool hasMinExcessFee() => $_has(3); + @$pb.TagNumber(5) + void clearMinExcessFee() => clearField(5); + + @$pb.TagNumber(6) + $fixnum.Int64 get maxExcessFee => $_getI64(4); + @$pb.TagNumber(6) + set maxExcessFee($fixnum.Int64 v) { $_setInt64(4, v); } + @$pb.TagNumber(6) + $core.bool hasMaxExcessFee() => $_has(4); + @$pb.TagNumber(6) + void clearMaxExcessFee() => clearField(6); + + @$pb.TagNumber(15) + $core.String get donationAddress => $_getSZ(5); + @$pb.TagNumber(15) + set donationAddress($core.String v) { $_setString(5, v); } + @$pb.TagNumber(15) + $core.bool hasDonationAddress() => $_has(5); + @$pb.TagNumber(15) + void clearDonationAddress() => clearField(15); +} + +class JoinPools_PoolTag extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'JoinPools.PoolTag', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id', $pb.PbFieldType.QY) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'limit', $pb.PbFieldType.QU3) + ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'noIp') + ; + + JoinPools_PoolTag._() : super(); + factory JoinPools_PoolTag({ + $core.List<$core.int>? id, + $core.int? limit, + $core.bool? noIp, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (limit != null) { + _result.limit = limit; + } + if (noIp != null) { + _result.noIp = noIp; + } + return _result; + } + factory JoinPools_PoolTag.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory JoinPools_PoolTag.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + JoinPools_PoolTag clone() => JoinPools_PoolTag()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + JoinPools_PoolTag copyWith(void Function(JoinPools_PoolTag) updates) => super.copyWith((message) => updates(message as JoinPools_PoolTag)) as JoinPools_PoolTag; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static JoinPools_PoolTag create() => JoinPools_PoolTag._(); + JoinPools_PoolTag createEmptyInstance() => create(); + static $pb.PbList<JoinPools_PoolTag> createRepeated() => $pb.PbList<JoinPools_PoolTag>(); + @$core.pragma('dart2js:noInline') + static JoinPools_PoolTag getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<JoinPools_PoolTag>(create); + static JoinPools_PoolTag? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get id => $_getN(0); + @$pb.TagNumber(1) + set id($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.int get limit => $_getIZ(1); + @$pb.TagNumber(2) + set limit($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasLimit() => $_has(1); + @$pb.TagNumber(2) + void clearLimit() => clearField(2); + + @$pb.TagNumber(3) + $core.bool get noIp => $_getBF(2); + @$pb.TagNumber(3) + set noIp($core.bool v) { $_setBool(2, v); } + @$pb.TagNumber(3) + $core.bool hasNoIp() => $_has(2); + @$pb.TagNumber(3) + void clearNoIp() => clearField(3); +} + +class JoinPools extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'JoinPools', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tiers', $pb.PbFieldType.PU6) + ..pc<JoinPools_PoolTag>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tags', $pb.PbFieldType.PM, subBuilder: JoinPools_PoolTag.create) + ; + + JoinPools._() : super(); + factory JoinPools({ + $core.Iterable<$fixnum.Int64>? tiers, + $core.Iterable<JoinPools_PoolTag>? tags, + }) { + final _result = create(); + if (tiers != null) { + _result.tiers.addAll(tiers); + } + if (tags != null) { + _result.tags.addAll(tags); + } + return _result; + } + factory JoinPools.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory JoinPools.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + JoinPools clone() => JoinPools()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + JoinPools copyWith(void Function(JoinPools) updates) => super.copyWith((message) => updates(message as JoinPools)) as JoinPools; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static JoinPools create() => JoinPools._(); + JoinPools createEmptyInstance() => create(); + static $pb.PbList<JoinPools> createRepeated() => $pb.PbList<JoinPools>(); + @$core.pragma('dart2js:noInline') + static JoinPools getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<JoinPools>(create); + static JoinPools? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$fixnum.Int64> get tiers => $_getList(0); + + @$pb.TagNumber(2) + $core.List<JoinPools_PoolTag> get tags => $_getList(1); +} + +class TierStatusUpdate_TierStatus extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TierStatusUpdate.TierStatus', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'players', $pb.PbFieldType.OU3) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'minPlayers', $pb.PbFieldType.OU3) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'maxPlayers', $pb.PbFieldType.OU3) + ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeRemaining', $pb.PbFieldType.OU3) + ..hasRequiredFields = false + ; + + TierStatusUpdate_TierStatus._() : super(); + factory TierStatusUpdate_TierStatus({ + $core.int? players, + $core.int? minPlayers, + $core.int? maxPlayers, + $core.int? timeRemaining, + }) { + final _result = create(); + if (players != null) { + _result.players = players; + } + if (minPlayers != null) { + _result.minPlayers = minPlayers; + } + if (maxPlayers != null) { + _result.maxPlayers = maxPlayers; + } + if (timeRemaining != null) { + _result.timeRemaining = timeRemaining; + } + return _result; + } + factory TierStatusUpdate_TierStatus.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TierStatusUpdate_TierStatus.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TierStatusUpdate_TierStatus clone() => TierStatusUpdate_TierStatus()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TierStatusUpdate_TierStatus copyWith(void Function(TierStatusUpdate_TierStatus) updates) => super.copyWith((message) => updates(message as TierStatusUpdate_TierStatus)) as TierStatusUpdate_TierStatus; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TierStatusUpdate_TierStatus create() => TierStatusUpdate_TierStatus._(); + TierStatusUpdate_TierStatus createEmptyInstance() => create(); + static $pb.PbList<TierStatusUpdate_TierStatus> createRepeated() => $pb.PbList<TierStatusUpdate_TierStatus>(); + @$core.pragma('dart2js:noInline') + static TierStatusUpdate_TierStatus getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TierStatusUpdate_TierStatus>(create); + static TierStatusUpdate_TierStatus? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get players => $_getIZ(0); + @$pb.TagNumber(1) + set players($core.int v) { $_setUnsignedInt32(0, v); } + @$pb.TagNumber(1) + $core.bool hasPlayers() => $_has(0); + @$pb.TagNumber(1) + void clearPlayers() => clearField(1); + + @$pb.TagNumber(2) + $core.int get minPlayers => $_getIZ(1); + @$pb.TagNumber(2) + set minPlayers($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasMinPlayers() => $_has(1); + @$pb.TagNumber(2) + void clearMinPlayers() => clearField(2); + + @$pb.TagNumber(3) + $core.int get maxPlayers => $_getIZ(2); + @$pb.TagNumber(3) + set maxPlayers($core.int v) { $_setUnsignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasMaxPlayers() => $_has(2); + @$pb.TagNumber(3) + void clearMaxPlayers() => clearField(3); + + @$pb.TagNumber(4) + $core.int get timeRemaining => $_getIZ(3); + @$pb.TagNumber(4) + set timeRemaining($core.int v) { $_setUnsignedInt32(3, v); } + @$pb.TagNumber(4) + $core.bool hasTimeRemaining() => $_has(3); + @$pb.TagNumber(4) + void clearTimeRemaining() => clearField(4); +} + +class TierStatusUpdate extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TierStatusUpdate', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..m<$fixnum.Int64, TierStatusUpdate_TierStatus>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'statuses', entryClassName: 'TierStatusUpdate.StatusesEntry', keyFieldType: $pb.PbFieldType.OU6, valueFieldType: $pb.PbFieldType.OM, valueCreator: TierStatusUpdate_TierStatus.create, packageName: const $pb.PackageName('fusion')) + ..hasRequiredFields = false + ; + + TierStatusUpdate._() : super(); + factory TierStatusUpdate({ + $core.Map<$fixnum.Int64, TierStatusUpdate_TierStatus>? statuses, + }) { + final _result = create(); + if (statuses != null) { + _result.statuses.addAll(statuses); + } + return _result; + } + factory TierStatusUpdate.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TierStatusUpdate.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TierStatusUpdate clone() => TierStatusUpdate()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TierStatusUpdate copyWith(void Function(TierStatusUpdate) updates) => super.copyWith((message) => updates(message as TierStatusUpdate)) as TierStatusUpdate; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TierStatusUpdate create() => TierStatusUpdate._(); + TierStatusUpdate createEmptyInstance() => create(); + static $pb.PbList<TierStatusUpdate> createRepeated() => $pb.PbList<TierStatusUpdate>(); + @$core.pragma('dart2js:noInline') + static TierStatusUpdate getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TierStatusUpdate>(create); + static TierStatusUpdate? _defaultInstance; + + @$pb.TagNumber(1) + $core.Map<$fixnum.Int64, TierStatusUpdate_TierStatus> get statuses => $_getMap(0); +} + +class FusionBegin extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FusionBegin', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tier', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertDomain', $pb.PbFieldType.QY) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertPort', $pb.PbFieldType.QU3) + ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertSsl') + ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverTime', $pb.PbFieldType.QF6, defaultOrMaker: $fixnum.Int64.ZERO) + ; + + FusionBegin._() : super(); + factory FusionBegin({ + $fixnum.Int64? tier, + $core.List<$core.int>? covertDomain, + $core.int? covertPort, + $core.bool? covertSsl, + $fixnum.Int64? serverTime, + }) { + final _result = create(); + if (tier != null) { + _result.tier = tier; + } + if (covertDomain != null) { + _result.covertDomain = covertDomain; + } + if (covertPort != null) { + _result.covertPort = covertPort; + } + if (covertSsl != null) { + _result.covertSsl = covertSsl; + } + if (serverTime != null) { + _result.serverTime = serverTime; + } + return _result; + } + factory FusionBegin.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FusionBegin.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + FusionBegin clone() => FusionBegin()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + FusionBegin copyWith(void Function(FusionBegin) updates) => super.copyWith((message) => updates(message as FusionBegin)) as FusionBegin; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static FusionBegin create() => FusionBegin._(); + FusionBegin createEmptyInstance() => create(); + static $pb.PbList<FusionBegin> createRepeated() => $pb.PbList<FusionBegin>(); + @$core.pragma('dart2js:noInline') + static FusionBegin getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FusionBegin>(create); + static FusionBegin? _defaultInstance; + + @$pb.TagNumber(1) + $fixnum.Int64 get tier => $_getI64(0); + @$pb.TagNumber(1) + set tier($fixnum.Int64 v) { $_setInt64(0, v); } + @$pb.TagNumber(1) + $core.bool hasTier() => $_has(0); + @$pb.TagNumber(1) + void clearTier() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get covertDomain => $_getN(1); + @$pb.TagNumber(2) + set covertDomain($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasCovertDomain() => $_has(1); + @$pb.TagNumber(2) + void clearCovertDomain() => clearField(2); + + @$pb.TagNumber(3) + $core.int get covertPort => $_getIZ(2); + @$pb.TagNumber(3) + set covertPort($core.int v) { $_setUnsignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasCovertPort() => $_has(2); + @$pb.TagNumber(3) + void clearCovertPort() => clearField(3); + + @$pb.TagNumber(4) + $core.bool get covertSsl => $_getBF(3); + @$pb.TagNumber(4) + set covertSsl($core.bool v) { $_setBool(3, v); } + @$pb.TagNumber(4) + $core.bool hasCovertSsl() => $_has(3); + @$pb.TagNumber(4) + void clearCovertSsl() => clearField(4); + + @$pb.TagNumber(5) + $fixnum.Int64 get serverTime => $_getI64(4); + @$pb.TagNumber(5) + set serverTime($fixnum.Int64 v) { $_setInt64(4, v); } + @$pb.TagNumber(5) + $core.bool hasServerTime() => $_has(4); + @$pb.TagNumber(5) + void clearServerTime() => clearField(5); +} + +class StartRound extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'StartRound', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.QY) + ..p<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindNoncePoints', $pb.PbFieldType.PY) + ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverTime', $pb.PbFieldType.QF6, defaultOrMaker: $fixnum.Int64.ZERO) + ; + + StartRound._() : super(); + factory StartRound({ + $core.List<$core.int>? roundPubkey, + $core.Iterable<$core.List<$core.int>>? blindNoncePoints, + $fixnum.Int64? serverTime, + }) { + final _result = create(); + if (roundPubkey != null) { + _result.roundPubkey = roundPubkey; + } + if (blindNoncePoints != null) { + _result.blindNoncePoints.addAll(blindNoncePoints); + } + if (serverTime != null) { + _result.serverTime = serverTime; + } + return _result; + } + factory StartRound.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory StartRound.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + StartRound clone() => StartRound()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + StartRound copyWith(void Function(StartRound) updates) => super.copyWith((message) => updates(message as StartRound)) as StartRound; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static StartRound create() => StartRound._(); + StartRound createEmptyInstance() => create(); + static $pb.PbList<StartRound> createRepeated() => $pb.PbList<StartRound>(); + @$core.pragma('dart2js:noInline') + static StartRound getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<StartRound>(create); + static StartRound? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get roundPubkey => $_getN(0); + @$pb.TagNumber(1) + set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasRoundPubkey() => $_has(0); + @$pb.TagNumber(1) + void clearRoundPubkey() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.List<$core.int>> get blindNoncePoints => $_getList(1); + + @$pb.TagNumber(5) + $fixnum.Int64 get serverTime => $_getI64(2); + @$pb.TagNumber(5) + set serverTime($fixnum.Int64 v) { $_setInt64(2, v); } + @$pb.TagNumber(5) + $core.bool hasServerTime() => $_has(2); + @$pb.TagNumber(5) + void clearServerTime() => clearField(5); +} + +class PlayerCommit extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'PlayerCommit', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'initialCommitments', $pb.PbFieldType.PY) + ..a<$fixnum.Int64>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'excessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pedersenTotalNonce', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'randomNumberCommitment', $pb.PbFieldType.QY) + ..p<$core.List<$core.int>>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindSigRequests', $pb.PbFieldType.PY) + ; + + PlayerCommit._() : super(); + factory PlayerCommit({ + $core.Iterable<$core.List<$core.int>>? initialCommitments, + $fixnum.Int64? excessFee, + $core.List<$core.int>? pedersenTotalNonce, + $core.List<$core.int>? randomNumberCommitment, + $core.Iterable<$core.List<$core.int>>? blindSigRequests, + }) { + final _result = create(); + if (initialCommitments != null) { + _result.initialCommitments.addAll(initialCommitments); + } + if (excessFee != null) { + _result.excessFee = excessFee; + } + if (pedersenTotalNonce != null) { + _result.pedersenTotalNonce = pedersenTotalNonce; + } + if (randomNumberCommitment != null) { + _result.randomNumberCommitment = randomNumberCommitment; + } + if (blindSigRequests != null) { + _result.blindSigRequests.addAll(blindSigRequests); + } + return _result; + } + factory PlayerCommit.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory PlayerCommit.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + PlayerCommit clone() => PlayerCommit()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + PlayerCommit copyWith(void Function(PlayerCommit) updates) => super.copyWith((message) => updates(message as PlayerCommit)) as PlayerCommit; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static PlayerCommit create() => PlayerCommit._(); + PlayerCommit createEmptyInstance() => create(); + static $pb.PbList<PlayerCommit> createRepeated() => $pb.PbList<PlayerCommit>(); + @$core.pragma('dart2js:noInline') + static PlayerCommit getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<PlayerCommit>(create); + static PlayerCommit? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.List<$core.int>> get initialCommitments => $_getList(0); + + @$pb.TagNumber(2) + $fixnum.Int64 get excessFee => $_getI64(1); + @$pb.TagNumber(2) + set excessFee($fixnum.Int64 v) { $_setInt64(1, v); } + @$pb.TagNumber(2) + $core.bool hasExcessFee() => $_has(1); + @$pb.TagNumber(2) + void clearExcessFee() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get pedersenTotalNonce => $_getN(2); + @$pb.TagNumber(3) + set pedersenTotalNonce($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasPedersenTotalNonce() => $_has(2); + @$pb.TagNumber(3) + void clearPedersenTotalNonce() => clearField(3); + + @$pb.TagNumber(4) + $core.List<$core.int> get randomNumberCommitment => $_getN(3); + @$pb.TagNumber(4) + set randomNumberCommitment($core.List<$core.int> v) { $_setBytes(3, v); } + @$pb.TagNumber(4) + $core.bool hasRandomNumberCommitment() => $_has(3); + @$pb.TagNumber(4) + void clearRandomNumberCommitment() => clearField(4); + + @$pb.TagNumber(5) + $core.List<$core.List<$core.int>> get blindSigRequests => $_getList(4); +} + +class BlindSigResponses extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlindSigResponses', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scalars', $pb.PbFieldType.PY) + ..hasRequiredFields = false + ; + + BlindSigResponses._() : super(); + factory BlindSigResponses({ + $core.Iterable<$core.List<$core.int>>? scalars, + }) { + final _result = create(); + if (scalars != null) { + _result.scalars.addAll(scalars); + } + return _result; + } + factory BlindSigResponses.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory BlindSigResponses.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + BlindSigResponses clone() => BlindSigResponses()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + BlindSigResponses copyWith(void Function(BlindSigResponses) updates) => super.copyWith((message) => updates(message as BlindSigResponses)) as BlindSigResponses; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static BlindSigResponses create() => BlindSigResponses._(); + BlindSigResponses createEmptyInstance() => create(); + static $pb.PbList<BlindSigResponses> createRepeated() => $pb.PbList<BlindSigResponses>(); + @$core.pragma('dart2js:noInline') + static BlindSigResponses getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BlindSigResponses>(create); + static BlindSigResponses? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.List<$core.int>> get scalars => $_getList(0); +} + +class AllCommitments extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AllCommitments', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'initialCommitments', $pb.PbFieldType.PY) + ..hasRequiredFields = false + ; + + AllCommitments._() : super(); + factory AllCommitments({ + $core.Iterable<$core.List<$core.int>>? initialCommitments, + }) { + final _result = create(); + if (initialCommitments != null) { + _result.initialCommitments.addAll(initialCommitments); + } + return _result; + } + factory AllCommitments.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory AllCommitments.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + AllCommitments clone() => AllCommitments()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + AllCommitments copyWith(void Function(AllCommitments) updates) => super.copyWith((message) => updates(message as AllCommitments)) as AllCommitments; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static AllCommitments create() => AllCommitments._(); + AllCommitments createEmptyInstance() => create(); + static $pb.PbList<AllCommitments> createRepeated() => $pb.PbList<AllCommitments>(); + @$core.pragma('dart2js:noInline') + static AllCommitments getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AllCommitments>(create); + static AllCommitments? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.List<$core.int>> get initialCommitments => $_getList(0); +} + +class CovertComponent extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.OY) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signature', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'component', $pb.PbFieldType.QY) + ; + + CovertComponent._() : super(); + factory CovertComponent({ + $core.List<$core.int>? roundPubkey, + $core.List<$core.int>? signature, + $core.List<$core.int>? component, + }) { + final _result = create(); + if (roundPubkey != null) { + _result.roundPubkey = roundPubkey; + } + if (signature != null) { + _result.signature = signature; + } + if (component != null) { + _result.component = component; + } + return _result; + } + factory CovertComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CovertComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CovertComponent clone() => CovertComponent()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CovertComponent copyWith(void Function(CovertComponent) updates) => super.copyWith((message) => updates(message as CovertComponent)) as CovertComponent; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CovertComponent create() => CovertComponent._(); + CovertComponent createEmptyInstance() => create(); + static $pb.PbList<CovertComponent> createRepeated() => $pb.PbList<CovertComponent>(); + @$core.pragma('dart2js:noInline') + static CovertComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertComponent>(create); + static CovertComponent? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get roundPubkey => $_getN(0); + @$pb.TagNumber(1) + set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasRoundPubkey() => $_has(0); + @$pb.TagNumber(1) + void clearRoundPubkey() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get signature => $_getN(1); + @$pb.TagNumber(2) + set signature($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasSignature() => $_has(1); + @$pb.TagNumber(2) + void clearSignature() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get component => $_getN(2); + @$pb.TagNumber(3) + set component($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasComponent() => $_has(2); + @$pb.TagNumber(3) + void clearComponent() => clearField(3); +} + +class ShareCovertComponents extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ShareCovertComponents', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$core.List<$core.int>>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'components', $pb.PbFieldType.PY) + ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'skipSignatures') + ..a<$core.List<$core.int>>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sessionHash', $pb.PbFieldType.OY) + ..hasRequiredFields = false + ; + + ShareCovertComponents._() : super(); + factory ShareCovertComponents({ + $core.Iterable<$core.List<$core.int>>? components, + $core.bool? skipSignatures, + $core.List<$core.int>? sessionHash, + }) { + final _result = create(); + if (components != null) { + _result.components.addAll(components); + } + if (skipSignatures != null) { + _result.skipSignatures = skipSignatures; + } + if (sessionHash != null) { + _result.sessionHash = sessionHash; + } + return _result; + } + factory ShareCovertComponents.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ShareCovertComponents.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ShareCovertComponents clone() => ShareCovertComponents()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ShareCovertComponents copyWith(void Function(ShareCovertComponents) updates) => super.copyWith((message) => updates(message as ShareCovertComponents)) as ShareCovertComponents; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ShareCovertComponents create() => ShareCovertComponents._(); + ShareCovertComponents createEmptyInstance() => create(); + static $pb.PbList<ShareCovertComponents> createRepeated() => $pb.PbList<ShareCovertComponents>(); + @$core.pragma('dart2js:noInline') + static ShareCovertComponents getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ShareCovertComponents>(create); + static ShareCovertComponents? _defaultInstance; + + @$pb.TagNumber(4) + $core.List<$core.List<$core.int>> get components => $_getList(0); + + @$pb.TagNumber(5) + $core.bool get skipSignatures => $_getBF(1); + @$pb.TagNumber(5) + set skipSignatures($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(5) + $core.bool hasSkipSignatures() => $_has(1); + @$pb.TagNumber(5) + void clearSkipSignatures() => clearField(5); + + @$pb.TagNumber(6) + $core.List<$core.int> get sessionHash => $_getN(2); + @$pb.TagNumber(6) + set sessionHash($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(6) + $core.bool hasSessionHash() => $_has(2); + @$pb.TagNumber(6) + void clearSessionHash() => clearField(6); +} + +class CovertTransactionSignature extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertTransactionSignature', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.OY) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'whichInput', $pb.PbFieldType.QU3) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'txsignature', $pb.PbFieldType.QY) + ; + + CovertTransactionSignature._() : super(); + factory CovertTransactionSignature({ + $core.List<$core.int>? roundPubkey, + $core.int? whichInput, + $core.List<$core.int>? txsignature, + }) { + final _result = create(); + if (roundPubkey != null) { + _result.roundPubkey = roundPubkey; + } + if (whichInput != null) { + _result.whichInput = whichInput; + } + if (txsignature != null) { + _result.txsignature = txsignature; + } + return _result; + } + factory CovertTransactionSignature.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CovertTransactionSignature.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CovertTransactionSignature clone() => CovertTransactionSignature()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CovertTransactionSignature copyWith(void Function(CovertTransactionSignature) updates) => super.copyWith((message) => updates(message as CovertTransactionSignature)) as CovertTransactionSignature; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CovertTransactionSignature create() => CovertTransactionSignature._(); + CovertTransactionSignature createEmptyInstance() => create(); + static $pb.PbList<CovertTransactionSignature> createRepeated() => $pb.PbList<CovertTransactionSignature>(); + @$core.pragma('dart2js:noInline') + static CovertTransactionSignature getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertTransactionSignature>(create); + static CovertTransactionSignature? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get roundPubkey => $_getN(0); + @$pb.TagNumber(1) + set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasRoundPubkey() => $_has(0); + @$pb.TagNumber(1) + void clearRoundPubkey() => clearField(1); + + @$pb.TagNumber(2) + $core.int get whichInput => $_getIZ(1); + @$pb.TagNumber(2) + set whichInput($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasWhichInput() => $_has(1); + @$pb.TagNumber(2) + void clearWhichInput() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get txsignature => $_getN(2); + @$pb.TagNumber(3) + set txsignature($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasTxsignature() => $_has(2); + @$pb.TagNumber(3) + void clearTxsignature() => clearField(3); +} + +class FusionResult extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FusionResult', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.bool>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ok', $pb.PbFieldType.QB) + ..p<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'txsignatures', $pb.PbFieldType.PY) + ..p<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'badComponents', $pb.PbFieldType.PU3) + ; + + FusionResult._() : super(); + factory FusionResult({ + $core.bool? ok, + $core.Iterable<$core.List<$core.int>>? txsignatures, + $core.Iterable<$core.int>? badComponents, + }) { + final _result = create(); + if (ok != null) { + _result.ok = ok; + } + if (txsignatures != null) { + _result.txsignatures.addAll(txsignatures); + } + if (badComponents != null) { + _result.badComponents.addAll(badComponents); + } + return _result; + } + factory FusionResult.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FusionResult.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + FusionResult clone() => FusionResult()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + FusionResult copyWith(void Function(FusionResult) updates) => super.copyWith((message) => updates(message as FusionResult)) as FusionResult; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static FusionResult create() => FusionResult._(); + FusionResult createEmptyInstance() => create(); + static $pb.PbList<FusionResult> createRepeated() => $pb.PbList<FusionResult>(); + @$core.pragma('dart2js:noInline') + static FusionResult getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FusionResult>(create); + static FusionResult? _defaultInstance; + + @$pb.TagNumber(1) + $core.bool get ok => $_getBF(0); + @$pb.TagNumber(1) + set ok($core.bool v) { $_setBool(0, v); } + @$pb.TagNumber(1) + $core.bool hasOk() => $_has(0); + @$pb.TagNumber(1) + void clearOk() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.List<$core.int>> get txsignatures => $_getList(1); + + @$pb.TagNumber(3) + $core.List<$core.int> get badComponents => $_getList(2); +} + +class MyProofsList extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MyProofsList', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'encryptedProofs', $pb.PbFieldType.PY) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'randomNumber', $pb.PbFieldType.QY) + ; + + MyProofsList._() : super(); + factory MyProofsList({ + $core.Iterable<$core.List<$core.int>>? encryptedProofs, + $core.List<$core.int>? randomNumber, + }) { + final _result = create(); + if (encryptedProofs != null) { + _result.encryptedProofs.addAll(encryptedProofs); + } + if (randomNumber != null) { + _result.randomNumber = randomNumber; + } + return _result; + } + factory MyProofsList.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory MyProofsList.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + MyProofsList clone() => MyProofsList()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + MyProofsList copyWith(void Function(MyProofsList) updates) => super.copyWith((message) => updates(message as MyProofsList)) as MyProofsList; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static MyProofsList create() => MyProofsList._(); + MyProofsList createEmptyInstance() => create(); + static $pb.PbList<MyProofsList> createRepeated() => $pb.PbList<MyProofsList>(); + @$core.pragma('dart2js:noInline') + static MyProofsList getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<MyProofsList>(create); + static MyProofsList? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.List<$core.int>> get encryptedProofs => $_getList(0); + + @$pb.TagNumber(2) + $core.List<$core.int> get randomNumber => $_getN(1); + @$pb.TagNumber(2) + set randomNumber($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasRandomNumber() => $_has(1); + @$pb.TagNumber(2) + void clearRandomNumber() => clearField(2); +} + +class TheirProofsList_RelayedProof extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TheirProofsList.RelayedProof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'encryptedProof', $pb.PbFieldType.QY) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'srcCommitmentIdx', $pb.PbFieldType.QU3) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dstKeyIdx', $pb.PbFieldType.QU3) + ; + + TheirProofsList_RelayedProof._() : super(); + factory TheirProofsList_RelayedProof({ + $core.List<$core.int>? encryptedProof, + $core.int? srcCommitmentIdx, + $core.int? dstKeyIdx, + }) { + final _result = create(); + if (encryptedProof != null) { + _result.encryptedProof = encryptedProof; + } + if (srcCommitmentIdx != null) { + _result.srcCommitmentIdx = srcCommitmentIdx; + } + if (dstKeyIdx != null) { + _result.dstKeyIdx = dstKeyIdx; + } + return _result; + } + factory TheirProofsList_RelayedProof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TheirProofsList_RelayedProof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TheirProofsList_RelayedProof clone() => TheirProofsList_RelayedProof()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TheirProofsList_RelayedProof copyWith(void Function(TheirProofsList_RelayedProof) updates) => super.copyWith((message) => updates(message as TheirProofsList_RelayedProof)) as TheirProofsList_RelayedProof; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TheirProofsList_RelayedProof create() => TheirProofsList_RelayedProof._(); + TheirProofsList_RelayedProof createEmptyInstance() => create(); + static $pb.PbList<TheirProofsList_RelayedProof> createRepeated() => $pb.PbList<TheirProofsList_RelayedProof>(); + @$core.pragma('dart2js:noInline') + static TheirProofsList_RelayedProof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TheirProofsList_RelayedProof>(create); + static TheirProofsList_RelayedProof? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get encryptedProof => $_getN(0); + @$pb.TagNumber(1) + set encryptedProof($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasEncryptedProof() => $_has(0); + @$pb.TagNumber(1) + void clearEncryptedProof() => clearField(1); + + @$pb.TagNumber(2) + $core.int get srcCommitmentIdx => $_getIZ(1); + @$pb.TagNumber(2) + set srcCommitmentIdx($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasSrcCommitmentIdx() => $_has(1); + @$pb.TagNumber(2) + void clearSrcCommitmentIdx() => clearField(2); + + @$pb.TagNumber(3) + $core.int get dstKeyIdx => $_getIZ(2); + @$pb.TagNumber(3) + set dstKeyIdx($core.int v) { $_setUnsignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasDstKeyIdx() => $_has(2); + @$pb.TagNumber(3) + void clearDstKeyIdx() => clearField(3); +} + +class TheirProofsList extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TheirProofsList', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..pc<TheirProofsList_RelayedProof>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'proofs', $pb.PbFieldType.PM, subBuilder: TheirProofsList_RelayedProof.create) + ; + + TheirProofsList._() : super(); + factory TheirProofsList({ + $core.Iterable<TheirProofsList_RelayedProof>? proofs, + }) { + final _result = create(); + if (proofs != null) { + _result.proofs.addAll(proofs); + } + return _result; + } + factory TheirProofsList.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TheirProofsList.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TheirProofsList clone() => TheirProofsList()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TheirProofsList copyWith(void Function(TheirProofsList) updates) => super.copyWith((message) => updates(message as TheirProofsList)) as TheirProofsList; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TheirProofsList create() => TheirProofsList._(); + TheirProofsList createEmptyInstance() => create(); + static $pb.PbList<TheirProofsList> createRepeated() => $pb.PbList<TheirProofsList>(); + @$core.pragma('dart2js:noInline') + static TheirProofsList getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TheirProofsList>(create); + static TheirProofsList? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<TheirProofsList_RelayedProof> get proofs => $_getList(0); +} + +enum Blames_BlameProof_Decrypter { + sessionKey, + privkey, + notSet +} + +class Blames_BlameProof extends $pb.GeneratedMessage { + static const $core.Map<$core.int, Blames_BlameProof_Decrypter> _Blames_BlameProof_DecrypterByTag = { + 2 : Blames_BlameProof_Decrypter.sessionKey, + 3 : Blames_BlameProof_Decrypter.privkey, + 0 : Blames_BlameProof_Decrypter.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Blames.BlameProof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [2, 3]) + ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'whichProof', $pb.PbFieldType.QU3) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sessionKey', $pb.PbFieldType.OY) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'privkey', $pb.PbFieldType.OY) + ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'needLookupBlockchain') + ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blameReason') + ; + + Blames_BlameProof._() : super(); + factory Blames_BlameProof({ + $core.int? whichProof, + $core.List<$core.int>? sessionKey, + $core.List<$core.int>? privkey, + $core.bool? needLookupBlockchain, + $core.String? blameReason, + }) { + final _result = create(); + if (whichProof != null) { + _result.whichProof = whichProof; + } + if (sessionKey != null) { + _result.sessionKey = sessionKey; + } + if (privkey != null) { + _result.privkey = privkey; + } + if (needLookupBlockchain != null) { + _result.needLookupBlockchain = needLookupBlockchain; + } + if (blameReason != null) { + _result.blameReason = blameReason; + } + return _result; + } + factory Blames_BlameProof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Blames_BlameProof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Blames_BlameProof clone() => Blames_BlameProof()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Blames_BlameProof copyWith(void Function(Blames_BlameProof) updates) => super.copyWith((message) => updates(message as Blames_BlameProof)) as Blames_BlameProof; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Blames_BlameProof create() => Blames_BlameProof._(); + Blames_BlameProof createEmptyInstance() => create(); + static $pb.PbList<Blames_BlameProof> createRepeated() => $pb.PbList<Blames_BlameProof>(); + @$core.pragma('dart2js:noInline') + static Blames_BlameProof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Blames_BlameProof>(create); + static Blames_BlameProof? _defaultInstance; + + Blames_BlameProof_Decrypter whichDecrypter() => _Blames_BlameProof_DecrypterByTag[$_whichOneof(0)]!; + void clearDecrypter() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.int get whichProof => $_getIZ(0); + @$pb.TagNumber(1) + set whichProof($core.int v) { $_setUnsignedInt32(0, v); } + @$pb.TagNumber(1) + $core.bool hasWhichProof() => $_has(0); + @$pb.TagNumber(1) + void clearWhichProof() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get sessionKey => $_getN(1); + @$pb.TagNumber(2) + set sessionKey($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasSessionKey() => $_has(1); + @$pb.TagNumber(2) + void clearSessionKey() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get privkey => $_getN(2); + @$pb.TagNumber(3) + set privkey($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasPrivkey() => $_has(2); + @$pb.TagNumber(3) + void clearPrivkey() => clearField(3); + + @$pb.TagNumber(4) + $core.bool get needLookupBlockchain => $_getBF(3); + @$pb.TagNumber(4) + set needLookupBlockchain($core.bool v) { $_setBool(3, v); } + @$pb.TagNumber(4) + $core.bool hasNeedLookupBlockchain() => $_has(3); + @$pb.TagNumber(4) + void clearNeedLookupBlockchain() => clearField(4); + + @$pb.TagNumber(5) + $core.String get blameReason => $_getSZ(4); + @$pb.TagNumber(5) + set blameReason($core.String v) { $_setString(4, v); } + @$pb.TagNumber(5) + $core.bool hasBlameReason() => $_has(4); + @$pb.TagNumber(5) + void clearBlameReason() => clearField(5); +} + +class Blames extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Blames', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..pc<Blames_BlameProof>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blames', $pb.PbFieldType.PM, subBuilder: Blames_BlameProof.create) + ; + + Blames._() : super(); + factory Blames({ + $core.Iterable<Blames_BlameProof>? blames, + }) { + final _result = create(); + if (blames != null) { + _result.blames.addAll(blames); + } + return _result; + } + factory Blames.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Blames.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Blames clone() => Blames()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Blames copyWith(void Function(Blames) updates) => super.copyWith((message) => updates(message as Blames)) as Blames; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Blames create() => Blames._(); + Blames createEmptyInstance() => create(); + static $pb.PbList<Blames> createRepeated() => $pb.PbList<Blames>(); + @$core.pragma('dart2js:noInline') + static Blames getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Blames>(create); + static Blames? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<Blames_BlameProof> get blames => $_getList(0); +} + +class RestartRound extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RestartRound', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..hasRequiredFields = false + ; + + RestartRound._() : super(); + factory RestartRound() => create(); + factory RestartRound.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RestartRound.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RestartRound clone() => RestartRound()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RestartRound copyWith(void Function(RestartRound) updates) => super.copyWith((message) => updates(message as RestartRound)) as RestartRound; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RestartRound create() => RestartRound._(); + RestartRound createEmptyInstance() => create(); + static $pb.PbList<RestartRound> createRepeated() => $pb.PbList<RestartRound>(); + @$core.pragma('dart2js:noInline') + static RestartRound getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RestartRound>(create); + static RestartRound? _defaultInstance; +} + +class Error extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Error', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'message') + ..hasRequiredFields = false + ; + + Error._() : super(); + factory Error({ + $core.String? message, + }) { + final _result = create(); + if (message != null) { + _result.message = message; + } + return _result; + } + factory Error.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Error.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Error clone() => Error()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Error copyWith(void Function(Error) updates) => super.copyWith((message) => updates(message as Error)) as Error; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Error create() => Error._(); + Error createEmptyInstance() => create(); + static $pb.PbList<Error> createRepeated() => $pb.PbList<Error>(); + @$core.pragma('dart2js:noInline') + static Error getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Error>(create); + static Error? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get message => $_getSZ(0); + @$pb.TagNumber(1) + set message($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasMessage() => $_has(0); + @$pb.TagNumber(1) + void clearMessage() => clearField(1); +} + +class Ping extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Ping', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..hasRequiredFields = false + ; + + Ping._() : super(); + factory Ping() => create(); + factory Ping.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Ping.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Ping clone() => Ping()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Ping copyWith(void Function(Ping) updates) => super.copyWith((message) => updates(message as Ping)) as Ping; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Ping create() => Ping._(); + Ping createEmptyInstance() => create(); + static $pb.PbList<Ping> createRepeated() => $pb.PbList<Ping>(); + @$core.pragma('dart2js:noInline') + static Ping getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Ping>(create); + static Ping? _defaultInstance; +} + +class OK extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'OK', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..hasRequiredFields = false + ; + + OK._() : super(); + factory OK() => create(); + factory OK.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory OK.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + OK clone() => OK()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + OK copyWith(void Function(OK) updates) => super.copyWith((message) => updates(message as OK)) as OK; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static OK create() => OK._(); + OK createEmptyInstance() => create(); + static $pb.PbList<OK> createRepeated() => $pb.PbList<OK>(); + @$core.pragma('dart2js:noInline') + static OK getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OK>(create); + static OK? _defaultInstance; +} + +enum ClientMessage_Msg { + clienthello, + joinpools, + playercommit, + myproofslist, + blames, + notSet +} + +class ClientMessage extends $pb.GeneratedMessage { + static const $core.Map<$core.int, ClientMessage_Msg> _ClientMessage_MsgByTag = { + 1 : ClientMessage_Msg.clienthello, + 2 : ClientMessage_Msg.joinpools, + 3 : ClientMessage_Msg.playercommit, + 5 : ClientMessage_Msg.myproofslist, + 6 : ClientMessage_Msg.blames, + 0 : ClientMessage_Msg.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ClientMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [1, 2, 3, 5, 6]) + ..aOM<ClientHello>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'clienthello', subBuilder: ClientHello.create) + ..aOM<JoinPools>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'joinpools', subBuilder: JoinPools.create) + ..aOM<PlayerCommit>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'playercommit', subBuilder: PlayerCommit.create) + ..aOM<MyProofsList>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'myproofslist', subBuilder: MyProofsList.create) + ..aOM<Blames>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blames', subBuilder: Blames.create) + ; + + ClientMessage._() : super(); + factory ClientMessage({ + ClientHello? clienthello, + JoinPools? joinpools, + PlayerCommit? playercommit, + MyProofsList? myproofslist, + Blames? blames, + }) { + final _result = create(); + if (clienthello != null) { + _result.clienthello = clienthello; + } + if (joinpools != null) { + _result.joinpools = joinpools; + } + if (playercommit != null) { + _result.playercommit = playercommit; + } + if (myproofslist != null) { + _result.myproofslist = myproofslist; + } + if (blames != null) { + _result.blames = blames; + } + return _result; + } + factory ClientMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ClientMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ClientMessage clone() => ClientMessage()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ClientMessage copyWith(void Function(ClientMessage) updates) => super.copyWith((message) => updates(message as ClientMessage)) as ClientMessage; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ClientMessage create() => ClientMessage._(); + ClientMessage createEmptyInstance() => create(); + static $pb.PbList<ClientMessage> createRepeated() => $pb.PbList<ClientMessage>(); + @$core.pragma('dart2js:noInline') + static ClientMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ClientMessage>(create); + static ClientMessage? _defaultInstance; + + ClientMessage_Msg whichMsg() => _ClientMessage_MsgByTag[$_whichOneof(0)]!; + void clearMsg() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + ClientHello get clienthello => $_getN(0); + @$pb.TagNumber(1) + set clienthello(ClientHello v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasClienthello() => $_has(0); + @$pb.TagNumber(1) + void clearClienthello() => clearField(1); + @$pb.TagNumber(1) + ClientHello ensureClienthello() => $_ensure(0); + + @$pb.TagNumber(2) + JoinPools get joinpools => $_getN(1); + @$pb.TagNumber(2) + set joinpools(JoinPools v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasJoinpools() => $_has(1); + @$pb.TagNumber(2) + void clearJoinpools() => clearField(2); + @$pb.TagNumber(2) + JoinPools ensureJoinpools() => $_ensure(1); + + @$pb.TagNumber(3) + PlayerCommit get playercommit => $_getN(2); + @$pb.TagNumber(3) + set playercommit(PlayerCommit v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasPlayercommit() => $_has(2); + @$pb.TagNumber(3) + void clearPlayercommit() => clearField(3); + @$pb.TagNumber(3) + PlayerCommit ensurePlayercommit() => $_ensure(2); + + @$pb.TagNumber(5) + MyProofsList get myproofslist => $_getN(3); + @$pb.TagNumber(5) + set myproofslist(MyProofsList v) { setField(5, v); } + @$pb.TagNumber(5) + $core.bool hasMyproofslist() => $_has(3); + @$pb.TagNumber(5) + void clearMyproofslist() => clearField(5); + @$pb.TagNumber(5) + MyProofsList ensureMyproofslist() => $_ensure(3); + + @$pb.TagNumber(6) + Blames get blames => $_getN(4); + @$pb.TagNumber(6) + set blames(Blames v) { setField(6, v); } + @$pb.TagNumber(6) + $core.bool hasBlames() => $_has(4); + @$pb.TagNumber(6) + void clearBlames() => clearField(6); + @$pb.TagNumber(6) + Blames ensureBlames() => $_ensure(4); +} + +enum ServerMessage_Msg { + serverhello, + tierstatusupdate, + fusionbegin, + startround, + blindsigresponses, + allcommitments, + sharecovertcomponents, + fusionresult, + theirproofslist, + restartround, + error, + notSet +} + +class ServerMessage extends $pb.GeneratedMessage { + static const $core.Map<$core.int, ServerMessage_Msg> _ServerMessage_MsgByTag = { + 1 : ServerMessage_Msg.serverhello, + 2 : ServerMessage_Msg.tierstatusupdate, + 3 : ServerMessage_Msg.fusionbegin, + 4 : ServerMessage_Msg.startround, + 5 : ServerMessage_Msg.blindsigresponses, + 6 : ServerMessage_Msg.allcommitments, + 7 : ServerMessage_Msg.sharecovertcomponents, + 8 : ServerMessage_Msg.fusionresult, + 9 : ServerMessage_Msg.theirproofslist, + 14 : ServerMessage_Msg.restartround, + 15 : ServerMessage_Msg.error, + 0 : ServerMessage_Msg.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ServerMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15]) + ..aOM<ServerHello>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverhello', subBuilder: ServerHello.create) + ..aOM<TierStatusUpdate>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tierstatusupdate', subBuilder: TierStatusUpdate.create) + ..aOM<FusionBegin>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fusionbegin', subBuilder: FusionBegin.create) + ..aOM<StartRound>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startround', subBuilder: StartRound.create) + ..aOM<BlindSigResponses>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindsigresponses', subBuilder: BlindSigResponses.create) + ..aOM<AllCommitments>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'allcommitments', subBuilder: AllCommitments.create) + ..aOM<ShareCovertComponents>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sharecovertcomponents', subBuilder: ShareCovertComponents.create) + ..aOM<FusionResult>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fusionresult', subBuilder: FusionResult.create) + ..aOM<TheirProofsList>(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'theirproofslist', subBuilder: TheirProofsList.create) + ..aOM<RestartRound>(14, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'restartround', subBuilder: RestartRound.create) + ..aOM<Error>(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'error', subBuilder: Error.create) + ; + + ServerMessage._() : super(); + factory ServerMessage({ + ServerHello? serverhello, + TierStatusUpdate? tierstatusupdate, + FusionBegin? fusionbegin, + StartRound? startround, + BlindSigResponses? blindsigresponses, + AllCommitments? allcommitments, + ShareCovertComponents? sharecovertcomponents, + FusionResult? fusionresult, + TheirProofsList? theirproofslist, + RestartRound? restartround, + Error? error, + }) { + final _result = create(); + if (serverhello != null) { + _result.serverhello = serverhello; + } + if (tierstatusupdate != null) { + _result.tierstatusupdate = tierstatusupdate; + } + if (fusionbegin != null) { + _result.fusionbegin = fusionbegin; + } + if (startround != null) { + _result.startround = startround; + } + if (blindsigresponses != null) { + _result.blindsigresponses = blindsigresponses; + } + if (allcommitments != null) { + _result.allcommitments = allcommitments; + } + if (sharecovertcomponents != null) { + _result.sharecovertcomponents = sharecovertcomponents; + } + if (fusionresult != null) { + _result.fusionresult = fusionresult; + } + if (theirproofslist != null) { + _result.theirproofslist = theirproofslist; + } + if (restartround != null) { + _result.restartround = restartround; + } + if (error != null) { + _result.error = error; + } + return _result; + } + factory ServerMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ServerMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ServerMessage clone() => ServerMessage()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ServerMessage copyWith(void Function(ServerMessage) updates) => super.copyWith((message) => updates(message as ServerMessage)) as ServerMessage; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ServerMessage create() => ServerMessage._(); + ServerMessage createEmptyInstance() => create(); + static $pb.PbList<ServerMessage> createRepeated() => $pb.PbList<ServerMessage>(); + @$core.pragma('dart2js:noInline') + static ServerMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ServerMessage>(create); + static ServerMessage? _defaultInstance; + + ServerMessage_Msg whichMsg() => _ServerMessage_MsgByTag[$_whichOneof(0)]!; + void clearMsg() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + ServerHello get serverhello => $_getN(0); + @$pb.TagNumber(1) + set serverhello(ServerHello v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasServerhello() => $_has(0); + @$pb.TagNumber(1) + void clearServerhello() => clearField(1); + @$pb.TagNumber(1) + ServerHello ensureServerhello() => $_ensure(0); + + @$pb.TagNumber(2) + TierStatusUpdate get tierstatusupdate => $_getN(1); + @$pb.TagNumber(2) + set tierstatusupdate(TierStatusUpdate v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasTierstatusupdate() => $_has(1); + @$pb.TagNumber(2) + void clearTierstatusupdate() => clearField(2); + @$pb.TagNumber(2) + TierStatusUpdate ensureTierstatusupdate() => $_ensure(1); + + @$pb.TagNumber(3) + FusionBegin get fusionbegin => $_getN(2); + @$pb.TagNumber(3) + set fusionbegin(FusionBegin v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasFusionbegin() => $_has(2); + @$pb.TagNumber(3) + void clearFusionbegin() => clearField(3); + @$pb.TagNumber(3) + FusionBegin ensureFusionbegin() => $_ensure(2); + + @$pb.TagNumber(4) + StartRound get startround => $_getN(3); + @$pb.TagNumber(4) + set startround(StartRound v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasStartround() => $_has(3); + @$pb.TagNumber(4) + void clearStartround() => clearField(4); + @$pb.TagNumber(4) + StartRound ensureStartround() => $_ensure(3); + + @$pb.TagNumber(5) + BlindSigResponses get blindsigresponses => $_getN(4); + @$pb.TagNumber(5) + set blindsigresponses(BlindSigResponses v) { setField(5, v); } + @$pb.TagNumber(5) + $core.bool hasBlindsigresponses() => $_has(4); + @$pb.TagNumber(5) + void clearBlindsigresponses() => clearField(5); + @$pb.TagNumber(5) + BlindSigResponses ensureBlindsigresponses() => $_ensure(4); + + @$pb.TagNumber(6) + AllCommitments get allcommitments => $_getN(5); + @$pb.TagNumber(6) + set allcommitments(AllCommitments v) { setField(6, v); } + @$pb.TagNumber(6) + $core.bool hasAllcommitments() => $_has(5); + @$pb.TagNumber(6) + void clearAllcommitments() => clearField(6); + @$pb.TagNumber(6) + AllCommitments ensureAllcommitments() => $_ensure(5); + + @$pb.TagNumber(7) + ShareCovertComponents get sharecovertcomponents => $_getN(6); + @$pb.TagNumber(7) + set sharecovertcomponents(ShareCovertComponents v) { setField(7, v); } + @$pb.TagNumber(7) + $core.bool hasSharecovertcomponents() => $_has(6); + @$pb.TagNumber(7) + void clearSharecovertcomponents() => clearField(7); + @$pb.TagNumber(7) + ShareCovertComponents ensureSharecovertcomponents() => $_ensure(6); + + @$pb.TagNumber(8) + FusionResult get fusionresult => $_getN(7); + @$pb.TagNumber(8) + set fusionresult(FusionResult v) { setField(8, v); } + @$pb.TagNumber(8) + $core.bool hasFusionresult() => $_has(7); + @$pb.TagNumber(8) + void clearFusionresult() => clearField(8); + @$pb.TagNumber(8) + FusionResult ensureFusionresult() => $_ensure(7); + + @$pb.TagNumber(9) + TheirProofsList get theirproofslist => $_getN(8); + @$pb.TagNumber(9) + set theirproofslist(TheirProofsList v) { setField(9, v); } + @$pb.TagNumber(9) + $core.bool hasTheirproofslist() => $_has(8); + @$pb.TagNumber(9) + void clearTheirproofslist() => clearField(9); + @$pb.TagNumber(9) + TheirProofsList ensureTheirproofslist() => $_ensure(8); + + @$pb.TagNumber(14) + RestartRound get restartround => $_getN(9); + @$pb.TagNumber(14) + set restartround(RestartRound v) { setField(14, v); } + @$pb.TagNumber(14) + $core.bool hasRestartround() => $_has(9); + @$pb.TagNumber(14) + void clearRestartround() => clearField(14); + @$pb.TagNumber(14) + RestartRound ensureRestartround() => $_ensure(9); + + @$pb.TagNumber(15) + Error get error => $_getN(10); + @$pb.TagNumber(15) + set error(Error v) { setField(15, v); } + @$pb.TagNumber(15) + $core.bool hasError() => $_has(10); + @$pb.TagNumber(15) + void clearError() => clearField(15); + @$pb.TagNumber(15) + Error ensureError() => $_ensure(10); +} + +enum CovertMessage_Msg { + component, + signature, + ping, + notSet +} + +class CovertMessage extends $pb.GeneratedMessage { + static const $core.Map<$core.int, CovertMessage_Msg> _CovertMessage_MsgByTag = { + 1 : CovertMessage_Msg.component, + 2 : CovertMessage_Msg.signature, + 3 : CovertMessage_Msg.ping, + 0 : CovertMessage_Msg.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [1, 2, 3]) + ..aOM<CovertComponent>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'component', subBuilder: CovertComponent.create) + ..aOM<CovertTransactionSignature>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signature', subBuilder: CovertTransactionSignature.create) + ..aOM<Ping>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ping', subBuilder: Ping.create) + ; + + CovertMessage._() : super(); + factory CovertMessage({ + CovertComponent? component, + CovertTransactionSignature? signature, + Ping? ping, + }) { + final _result = create(); + if (component != null) { + _result.component = component; + } + if (signature != null) { + _result.signature = signature; + } + if (ping != null) { + _result.ping = ping; + } + return _result; + } + factory CovertMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CovertMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CovertMessage clone() => CovertMessage()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CovertMessage copyWith(void Function(CovertMessage) updates) => super.copyWith((message) => updates(message as CovertMessage)) as CovertMessage; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CovertMessage create() => CovertMessage._(); + CovertMessage createEmptyInstance() => create(); + static $pb.PbList<CovertMessage> createRepeated() => $pb.PbList<CovertMessage>(); + @$core.pragma('dart2js:noInline') + static CovertMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertMessage>(create); + static CovertMessage? _defaultInstance; + + CovertMessage_Msg whichMsg() => _CovertMessage_MsgByTag[$_whichOneof(0)]!; + void clearMsg() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + CovertComponent get component => $_getN(0); + @$pb.TagNumber(1) + set component(CovertComponent v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasComponent() => $_has(0); + @$pb.TagNumber(1) + void clearComponent() => clearField(1); + @$pb.TagNumber(1) + CovertComponent ensureComponent() => $_ensure(0); + + @$pb.TagNumber(2) + CovertTransactionSignature get signature => $_getN(1); + @$pb.TagNumber(2) + set signature(CovertTransactionSignature v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasSignature() => $_has(1); + @$pb.TagNumber(2) + void clearSignature() => clearField(2); + @$pb.TagNumber(2) + CovertTransactionSignature ensureSignature() => $_ensure(1); + + @$pb.TagNumber(3) + Ping get ping => $_getN(2); + @$pb.TagNumber(3) + set ping(Ping v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasPing() => $_has(2); + @$pb.TagNumber(3) + void clearPing() => clearField(3); + @$pb.TagNumber(3) + Ping ensurePing() => $_ensure(2); +} + +enum CovertResponse_Msg { + ok, + error, + notSet +} + +class CovertResponse extends $pb.GeneratedMessage { + static const $core.Map<$core.int, CovertResponse_Msg> _CovertResponse_MsgByTag = { + 1 : CovertResponse_Msg.ok, + 15 : CovertResponse_Msg.error, + 0 : CovertResponse_Msg.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [1, 15]) + ..aOM<OK>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ok', subBuilder: OK.create) + ..aOM<Error>(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'error', subBuilder: Error.create) + ..hasRequiredFields = false + ; + + CovertResponse._() : super(); + factory CovertResponse({ + OK? ok, + Error? error, + }) { + final _result = create(); + if (ok != null) { + _result.ok = ok; + } + if (error != null) { + _result.error = error; + } + return _result; + } + factory CovertResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CovertResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CovertResponse clone() => CovertResponse()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CovertResponse copyWith(void Function(CovertResponse) updates) => super.copyWith((message) => updates(message as CovertResponse)) as CovertResponse; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CovertResponse create() => CovertResponse._(); + CovertResponse createEmptyInstance() => create(); + static $pb.PbList<CovertResponse> createRepeated() => $pb.PbList<CovertResponse>(); + @$core.pragma('dart2js:noInline') + static CovertResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertResponse>(create); + static CovertResponse? _defaultInstance; + + CovertResponse_Msg whichMsg() => _CovertResponse_MsgByTag[$_whichOneof(0)]!; + void clearMsg() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + OK get ok => $_getN(0); + @$pb.TagNumber(1) + set ok(OK v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasOk() => $_has(0); + @$pb.TagNumber(1) + void clearOk() => clearField(1); + @$pb.TagNumber(1) + OK ensureOk() => $_ensure(0); + + @$pb.TagNumber(15) + Error get error => $_getN(1); + @$pb.TagNumber(15) + set error(Error v) { setField(15, v); } + @$pb.TagNumber(15) + $core.bool hasError() => $_has(1); + @$pb.TagNumber(15) + void clearError() => clearField(15); + @$pb.TagNumber(15) + Error ensureError() => $_ensure(1); +} + diff --git a/lib/services/cashfusion/main.dart b/lib/services/cashfusion/main.dart new file mode 100644 index 000000000..0f6218bbb --- /dev/null +++ b/lib/services/cashfusion/main.dart @@ -0,0 +1,122 @@ +import 'package:flutter/material.dart'; +import 'fusion.dart'; +import 'pedersen.dart'; +import 'encrypt.dart'; +import 'validation.dart'; + +void main() { + + Fusion.foo(); + + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + // This is the theme of your application. + // + // Try running your application with "flutter run". You'll see the + // application has a blue toolbar. Then, without quitting the app, try + // changing the primarySwatch below to Colors.green and then invoke + // "hot reload" (press "r" in the console where you ran "flutter run", + // or simply save your changes to "hot reload" in a Flutter IDE). + // Notice that the counter didn't reset back to zero; the application + // is not restarted. + primarySwatch: Colors.blue, + ), + home: const MyHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key, required this.title}); + + // This widget is the home page of your application. It is stateful, meaning + // that it has a State object (defined below) that contains fields that affect + // how it looks. + + // This class is the configuration for the state. It holds the values (in this + // case the title) provided by the parent (in this case the App widget) and + // used by the build method of the State. Fields in a Widget subclass are + // always marked "final". + + final String title; + + @override + State<MyHomePage> createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State<MyHomePage> { + int _counter = 0; + + void _incrementCounter() { + setState(() { + // This call to setState tells the Flutter framework that something has + // changed in this State, which causes it to rerun the build method below + // so that the display can reflect the updated values. If we changed + // _counter without calling setState(), then the build method would not be + // called again, and so nothing would appear to happen. + _counter++; + }); + } + + @override + Widget build(BuildContext context) { + // This method is rerun every time setState is called, for instance as done + // by the _incrementCounter method above. + // + // The Flutter framework has been optimized to make rerunning build methods + // fast, so that you can just rebuild anything that needs updating rather + // than having to individually change instances of widgets. + return Scaffold( + appBar: AppBar( + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text(widget.title), + ), + body: Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: Column( + // Column is also a layout widget. It takes a list of children and + // arranges them vertically. By default, it sizes itself to fit its + // children horizontally, and tries to be as tall as its parent. + // + // Invoke "debug painting" (press "p" in the console, choose the + // "Toggle Debug Paint" action from the Flutter Inspector in Android + // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) + // to see the wireframe for each widget. + // + // Column has various properties to control how it sizes itself and + // how it positions its children. Here we use mainAxisAlignment to + // center the children vertically; the main axis here is the vertical + // axis because Columns are vertical (the cross axis would be + // horizontal). + mainAxisAlignment: MainAxisAlignment.center, + children: <Widget>[ + const Text( + 'You have pushed the button this many times:', + ), + Text( + '$_counter', + style: Theme.of(context).textTheme.headlineMedium, + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: _incrementCounter, + tooltip: 'Increment', + child: const Icon(Icons.add), + ), // This trailing comma makes auto-formatting nicer for build methods. + ); + } +} diff --git a/lib/services/cashfusion/pedersen.dart b/lib/services/cashfusion/pedersen.dart new file mode 100644 index 000000000..df9bbfc18 --- /dev/null +++ b/lib/services/cashfusion/pedersen.dart @@ -0,0 +1,187 @@ +import 'package:pointycastle/ecc/api.dart'; +import 'util.dart'; +import 'dart:math'; +import 'dart:typed_data'; + +ECDomainParameters getDefaultParams() { + return ECDomainParameters("secp256k1"); +} + +class NullPointError implements Exception { + String errMsg() => 'NullPointError: Either Hpoint or HGpoint is null.'; +} + + +class NonceRangeError implements Exception { + final String message; + NonceRangeError([this.message = "Nonce value must be in the range 0 < nonce < order"]); + String toString() => "NonceRangeError: $message"; +} + +class ResultAtInfinity implements Exception { + final String message; + ResultAtInfinity([this.message = "Result is at infinity"]); + String toString() => "ResultAtInfinity: $message"; +} + +class InsecureHPoint implements Exception { + final String message; + InsecureHPoint([this.message = "The H point has a known discrete logarithm, which means the commitment setup is broken"]); + String toString() => "InsecureHPoint: $message"; +} + + + +class PedersenSetup { + late ECPoint _H; + late ECPoint _HG; + late ECDomainParameters _params; + ECDomainParameters get params => _params; + + PedersenSetup(this._H) { + _params = new ECDomainParameters("secp256k1"); + // validate H point + if (!Util.isPointOnCurve(_H, _params.curve)) { + throw Exception('H is not a valid point on the curve'); + } + _HG = Util.combinePubKeys([_H, _params.G]); + } + + Uint8List get H => _H.getEncoded(false); + Uint8List get HG => _HG.getEncoded(false); + + Commitment commit(BigInt amount, {BigInt? nonce, Uint8List? PUncompressed}) { + return Commitment(this, amount, nonce: nonce, PUncompressed: PUncompressed); + } + +} + +class Commitment { + late PedersenSetup setup; // Added setup property to Commitment class + late BigInt amountMod; + late BigInt nonce; + late Uint8List PUncompressed; + + + Commitment(this.setup, BigInt amount, {BigInt? nonce, Uint8List? PUncompressed}) { + this.nonce = nonce ?? Util.secureRandomBigInt(setup.params.n.bitLength); + amountMod = amount % setup.params.n; + + if (this.nonce <= BigInt.zero || this.nonce >= setup.params.n) { + throw NonceRangeError(); + } + + ECPoint? Hpoint = setup._H; + ECPoint? HGpoint = setup._HG; + + if (Hpoint == null || HGpoint == null) { + throw NullPointError(); + } + + BigInt multiplier1 = (amountMod - this.nonce) % setup.params.n; + BigInt multiplier2 = this.nonce; + + ECPoint? HpointMultiplied = Hpoint * multiplier1; + ECPoint? HGpointMultiplied = HGpoint * multiplier2; + + ECPoint? Ppoint = HpointMultiplied != null && HGpointMultiplied != null ? HpointMultiplied + HGpointMultiplied : null; + + if (Ppoint == setup.params.curve.infinity) { + throw ResultAtInfinity(); + } + + this.PUncompressed = PUncompressed ?? Ppoint?.getEncoded(false) ?? Uint8List(0); + } + + void calcInitial(PedersenSetup setup, BigInt amount) { + amountMod = amount % setup.params.n; + nonce = Util.secureRandomBigInt(setup.params.n.bitLength); + + ECPoint? Hpoint = setup._H; + ECPoint? HGpoint = setup._HG; + + if (nonce <= BigInt.zero || nonce >= setup.params.n) { + throw NonceRangeError(); + } + + if (Hpoint == null || HGpoint == null) { + throw NullPointError(); + } + + BigInt multiplier1 = amountMod; + BigInt multiplier2 = nonce; + + ECPoint? HpointMultiplied = Hpoint * multiplier1; + ECPoint? HGpointMultiplied = HGpoint * multiplier2; + + ECPoint? Ppoint = HpointMultiplied != null && HGpointMultiplied != null ? HpointMultiplied + HGpointMultiplied : null; + + if (Ppoint == setup.params.curve.infinity) { + throw ResultAtInfinity(); + } + + PUncompressed = Ppoint?.getEncoded(false) ?? Uint8List(0); + } + + static Uint8List add_points(Iterable<Uint8List> pointsIterable) { + ECDomainParameters params = getDefaultParams(); // Using helper function here + var pointList = pointsIterable.map((pser) => Util.ser_to_point(pser, params)).toList(); + + if (pointList.isEmpty) { + throw ArgumentError('Empty list'); + } + + ECPoint pSum = pointList.first; // Initialize pSum with the first point in the list + + for (var i = 1; i < pointList.length; i++) { + pSum = (pSum + pointList[i])!; + } + + if (pSum == params.curve.infinity) { + throw Exception('Result is at infinity'); + } + + return Util.point_to_ser(pSum, false); + } + + + Commitment addCommitments(Iterable<Commitment> commitmentIterable) { + BigInt ktotal = BigInt.zero; // Changed to BigInt from int + BigInt atotal = BigInt.zero; // Changed to BigInt from int + List<Uint8List> points = []; + List<PedersenSetup> setups = []; // Changed Setup to PedersenSetup + for (Commitment c in commitmentIterable) { + ktotal += c.nonce; + atotal += c.amountMod; // Changed from amount to amountMod + points.add(c.PUncompressed); + setups.add(c.setup); + } + + if (points.isEmpty) { + throw ArgumentError('Empty list'); + } + + PedersenSetup setup = setups[0]; // Changed Setup to PedersenSetup + if (!setups.every((s) => s == setup)) { + throw ArgumentError('Mismatched setups'); + } + + ktotal = ktotal % setup.params.n; // Changed order to setup.params.n + + if (ktotal == BigInt.zero) { // Changed comparison from 0 to BigInt.zero + throw Exception('Nonce range error'); + } + + Uint8List? PUncompressed; + if (points.length < 512) { + try { + PUncompressed = add_points(points); + } on Exception { + PUncompressed = null; + } + } else { + PUncompressed = null; + } + return Commitment(setup, atotal, nonce: ktotal, PUncompressed: PUncompressed); + } +} diff --git a/lib/services/cashfusion/protobuf/build-proto-fusion.sh b/lib/services/cashfusion/protobuf/build-proto-fusion.sh new file mode 100644 index 000000000..75be9ab37 --- /dev/null +++ b/lib/services/cashfusion/protobuf/build-proto-fusion.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# This script will build the dart files based on fusion.proto. Navigate to the protobuf directory where the fusion.proto is and run this, then copy the needed files to lib. + +# The path to your .proto file. Adjust this if necessary. +PROTO_FILE="fusion.proto" + +# Run the protoc command. +protoc --dart_out=grpc:. $PROTO_FILE + +# After this, You should manually copy any needed dart files that were generated to the lib folder. diff --git a/lib/services/cashfusion/protobuf/fusion.pb.dart b/lib/services/cashfusion/protobuf/fusion.pb.dart new file mode 100644 index 000000000..dac659f95 --- /dev/null +++ b/lib/services/cashfusion/protobuf/fusion.pb.dart @@ -0,0 +1,2501 @@ +/// +// Generated code. Do not modify. +// source: fusion.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name + +import 'dart:core' as $core; + +import 'package:fixnum/fixnum.dart' as $fixnum; +import 'package:protobuf/protobuf.dart' as $pb; + +class InputComponent extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'InputComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'prevTxid', $pb.PbFieldType.QY) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'prevIndex', $pb.PbFieldType.QU3) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pubkey', $pb.PbFieldType.QY) + ..a<$fixnum.Int64>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amount', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ; + + InputComponent._() : super(); + factory InputComponent({ + $core.List<$core.int>? prevTxid, + $core.int? prevIndex, + $core.List<$core.int>? pubkey, + $fixnum.Int64? amount, + }) { + final _result = create(); + if (prevTxid != null) { + _result.prevTxid = prevTxid; + } + if (prevIndex != null) { + _result.prevIndex = prevIndex; + } + if (pubkey != null) { + _result.pubkey = pubkey; + } + if (amount != null) { + _result.amount = amount; + } + return _result; + } + factory InputComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory InputComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + InputComponent clone() => InputComponent()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + InputComponent copyWith(void Function(InputComponent) updates) => super.copyWith((message) => updates(message as InputComponent)) as InputComponent; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static InputComponent create() => InputComponent._(); + InputComponent createEmptyInstance() => create(); + static $pb.PbList<InputComponent> createRepeated() => $pb.PbList<InputComponent>(); + @$core.pragma('dart2js:noInline') + static InputComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<InputComponent>(create); + static InputComponent? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get prevTxid => $_getN(0); + @$pb.TagNumber(1) + set prevTxid($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasPrevTxid() => $_has(0); + @$pb.TagNumber(1) + void clearPrevTxid() => clearField(1); + + @$pb.TagNumber(2) + $core.int get prevIndex => $_getIZ(1); + @$pb.TagNumber(2) + set prevIndex($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasPrevIndex() => $_has(1); + @$pb.TagNumber(2) + void clearPrevIndex() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get pubkey => $_getN(2); + @$pb.TagNumber(3) + set pubkey($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasPubkey() => $_has(2); + @$pb.TagNumber(3) + void clearPubkey() => clearField(3); + + @$pb.TagNumber(4) + $fixnum.Int64 get amount => $_getI64(3); + @$pb.TagNumber(4) + set amount($fixnum.Int64 v) { $_setInt64(3, v); } + @$pb.TagNumber(4) + $core.bool hasAmount() => $_has(3); + @$pb.TagNumber(4) + void clearAmount() => clearField(4); +} + +class OutputComponent extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'OutputComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scriptpubkey', $pb.PbFieldType.QY) + ..a<$fixnum.Int64>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amount', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ; + + OutputComponent._() : super(); + factory OutputComponent({ + $core.List<$core.int>? scriptpubkey, + $fixnum.Int64? amount, + }) { + final _result = create(); + if (scriptpubkey != null) { + _result.scriptpubkey = scriptpubkey; + } + if (amount != null) { + _result.amount = amount; + } + return _result; + } + factory OutputComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory OutputComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + OutputComponent clone() => OutputComponent()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + OutputComponent copyWith(void Function(OutputComponent) updates) => super.copyWith((message) => updates(message as OutputComponent)) as OutputComponent; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static OutputComponent create() => OutputComponent._(); + OutputComponent createEmptyInstance() => create(); + static $pb.PbList<OutputComponent> createRepeated() => $pb.PbList<OutputComponent>(); + @$core.pragma('dart2js:noInline') + static OutputComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OutputComponent>(create); + static OutputComponent? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get scriptpubkey => $_getN(0); + @$pb.TagNumber(1) + set scriptpubkey($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasScriptpubkey() => $_has(0); + @$pb.TagNumber(1) + void clearScriptpubkey() => clearField(1); + + @$pb.TagNumber(2) + $fixnum.Int64 get amount => $_getI64(1); + @$pb.TagNumber(2) + set amount($fixnum.Int64 v) { $_setInt64(1, v); } + @$pb.TagNumber(2) + $core.bool hasAmount() => $_has(1); + @$pb.TagNumber(2) + void clearAmount() => clearField(2); +} + +class BlankComponent extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlankComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..hasRequiredFields = false + ; + + BlankComponent._() : super(); + factory BlankComponent() => create(); + factory BlankComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory BlankComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + BlankComponent clone() => BlankComponent()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + BlankComponent copyWith(void Function(BlankComponent) updates) => super.copyWith((message) => updates(message as BlankComponent)) as BlankComponent; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static BlankComponent create() => BlankComponent._(); + BlankComponent createEmptyInstance() => create(); + static $pb.PbList<BlankComponent> createRepeated() => $pb.PbList<BlankComponent>(); + @$core.pragma('dart2js:noInline') + static BlankComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BlankComponent>(create); + static BlankComponent? _defaultInstance; +} + +enum Component_Component { + input, + output, + blank, + notSet +} + +class Component extends $pb.GeneratedMessage { + static const $core.Map<$core.int, Component_Component> _Component_ComponentByTag = { + 2 : Component_Component.input, + 3 : Component_Component.output, + 4 : Component_Component.blank, + 0 : Component_Component.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Component', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [2, 3, 4]) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'saltCommitment', $pb.PbFieldType.QY) + ..aOM<InputComponent>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'input', subBuilder: InputComponent.create) + ..aOM<OutputComponent>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'output', subBuilder: OutputComponent.create) + ..aOM<BlankComponent>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blank', subBuilder: BlankComponent.create) + ; + + Component._() : super(); + factory Component({ + $core.List<$core.int>? saltCommitment, + InputComponent? input, + OutputComponent? output, + BlankComponent? blank, + }) { + final _result = create(); + if (saltCommitment != null) { + _result.saltCommitment = saltCommitment; + } + if (input != null) { + _result.input = input; + } + if (output != null) { + _result.output = output; + } + if (blank != null) { + _result.blank = blank; + } + return _result; + } + factory Component.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Component.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Component clone() => Component()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Component copyWith(void Function(Component) updates) => super.copyWith((message) => updates(message as Component)) as Component; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Component create() => Component._(); + Component createEmptyInstance() => create(); + static $pb.PbList<Component> createRepeated() => $pb.PbList<Component>(); + @$core.pragma('dart2js:noInline') + static Component getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Component>(create); + static Component? _defaultInstance; + + Component_Component whichComponent() => _Component_ComponentByTag[$_whichOneof(0)]!; + void clearComponent() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.List<$core.int> get saltCommitment => $_getN(0); + @$pb.TagNumber(1) + set saltCommitment($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasSaltCommitment() => $_has(0); + @$pb.TagNumber(1) + void clearSaltCommitment() => clearField(1); + + @$pb.TagNumber(2) + InputComponent get input => $_getN(1); + @$pb.TagNumber(2) + set input(InputComponent v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasInput() => $_has(1); + @$pb.TagNumber(2) + void clearInput() => clearField(2); + @$pb.TagNumber(2) + InputComponent ensureInput() => $_ensure(1); + + @$pb.TagNumber(3) + OutputComponent get output => $_getN(2); + @$pb.TagNumber(3) + set output(OutputComponent v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasOutput() => $_has(2); + @$pb.TagNumber(3) + void clearOutput() => clearField(3); + @$pb.TagNumber(3) + OutputComponent ensureOutput() => $_ensure(2); + + @$pb.TagNumber(4) + BlankComponent get blank => $_getN(3); + @$pb.TagNumber(4) + set blank(BlankComponent v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasBlank() => $_has(3); + @$pb.TagNumber(4) + void clearBlank() => clearField(4); + @$pb.TagNumber(4) + BlankComponent ensureBlank() => $_ensure(3); +} + +class InitialCommitment extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'InitialCommitment', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'saltedComponentHash', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amountCommitment', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'communicationKey', $pb.PbFieldType.QY) + ; + + InitialCommitment._() : super(); + factory InitialCommitment({ + $core.List<$core.int>? saltedComponentHash, + $core.List<$core.int>? amountCommitment, + $core.List<$core.int>? communicationKey, + }) { + final _result = create(); + if (saltedComponentHash != null) { + _result.saltedComponentHash = saltedComponentHash; + } + if (amountCommitment != null) { + _result.amountCommitment = amountCommitment; + } + if (communicationKey != null) { + _result.communicationKey = communicationKey; + } + return _result; + } + factory InitialCommitment.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory InitialCommitment.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + InitialCommitment clone() => InitialCommitment()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + InitialCommitment copyWith(void Function(InitialCommitment) updates) => super.copyWith((message) => updates(message as InitialCommitment)) as InitialCommitment; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static InitialCommitment create() => InitialCommitment._(); + InitialCommitment createEmptyInstance() => create(); + static $pb.PbList<InitialCommitment> createRepeated() => $pb.PbList<InitialCommitment>(); + @$core.pragma('dart2js:noInline') + static InitialCommitment getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<InitialCommitment>(create); + static InitialCommitment? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get saltedComponentHash => $_getN(0); + @$pb.TagNumber(1) + set saltedComponentHash($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasSaltedComponentHash() => $_has(0); + @$pb.TagNumber(1) + void clearSaltedComponentHash() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get amountCommitment => $_getN(1); + @$pb.TagNumber(2) + set amountCommitment($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasAmountCommitment() => $_has(1); + @$pb.TagNumber(2) + void clearAmountCommitment() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get communicationKey => $_getN(2); + @$pb.TagNumber(3) + set communicationKey($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasCommunicationKey() => $_has(2); + @$pb.TagNumber(3) + void clearCommunicationKey() => clearField(3); +} + +class Proof extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Proof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'componentIdx', $pb.PbFieldType.QF3) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'salt', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pedersenNonce', $pb.PbFieldType.QY) + ; + + Proof._() : super(); + factory Proof({ + $core.int? componentIdx, + $core.List<$core.int>? salt, + $core.List<$core.int>? pedersenNonce, + }) { + final _result = create(); + if (componentIdx != null) { + _result.componentIdx = componentIdx; + } + if (salt != null) { + _result.salt = salt; + } + if (pedersenNonce != null) { + _result.pedersenNonce = pedersenNonce; + } + return _result; + } + factory Proof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Proof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Proof clone() => Proof()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Proof copyWith(void Function(Proof) updates) => super.copyWith((message) => updates(message as Proof)) as Proof; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Proof create() => Proof._(); + Proof createEmptyInstance() => create(); + static $pb.PbList<Proof> createRepeated() => $pb.PbList<Proof>(); + @$core.pragma('dart2js:noInline') + static Proof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Proof>(create); + static Proof? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get componentIdx => $_getIZ(0); + @$pb.TagNumber(1) + set componentIdx($core.int v) { $_setUnsignedInt32(0, v); } + @$pb.TagNumber(1) + $core.bool hasComponentIdx() => $_has(0); + @$pb.TagNumber(1) + void clearComponentIdx() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get salt => $_getN(1); + @$pb.TagNumber(2) + set salt($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasSalt() => $_has(1); + @$pb.TagNumber(2) + void clearSalt() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get pedersenNonce => $_getN(2); + @$pb.TagNumber(3) + set pedersenNonce($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasPedersenNonce() => $_has(2); + @$pb.TagNumber(3) + void clearPedersenNonce() => clearField(3); +} + +class ClientHello extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ClientHello', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'version', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'genesisHash', $pb.PbFieldType.OY) + ; + + ClientHello._() : super(); + factory ClientHello({ + $core.List<$core.int>? version, + $core.List<$core.int>? genesisHash, + }) { + final _result = create(); + if (version != null) { + _result.version = version; + } + if (genesisHash != null) { + _result.genesisHash = genesisHash; + } + return _result; + } + factory ClientHello.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ClientHello.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ClientHello clone() => ClientHello()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ClientHello copyWith(void Function(ClientHello) updates) => super.copyWith((message) => updates(message as ClientHello)) as ClientHello; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ClientHello create() => ClientHello._(); + ClientHello createEmptyInstance() => create(); + static $pb.PbList<ClientHello> createRepeated() => $pb.PbList<ClientHello>(); + @$core.pragma('dart2js:noInline') + static ClientHello getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ClientHello>(create); + static ClientHello? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get version => $_getN(0); + @$pb.TagNumber(1) + set version($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasVersion() => $_has(0); + @$pb.TagNumber(1) + void clearVersion() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get genesisHash => $_getN(1); + @$pb.TagNumber(2) + set genesisHash($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasGenesisHash() => $_has(1); + @$pb.TagNumber(2) + void clearGenesisHash() => clearField(2); +} + +class ServerHello extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ServerHello', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tiers', $pb.PbFieldType.PU6) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'numComponents', $pb.PbFieldType.QU3) + ..a<$fixnum.Int64>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'componentFeerate', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'minExcessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ..a<$fixnum.Int64>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'maxExcessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ..aOS(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'donationAddress') + ; + + ServerHello._() : super(); + factory ServerHello({ + $core.Iterable<$fixnum.Int64>? tiers, + $core.int? numComponents, + $fixnum.Int64? componentFeerate, + $fixnum.Int64? minExcessFee, + $fixnum.Int64? maxExcessFee, + $core.String? donationAddress, + }) { + final _result = create(); + if (tiers != null) { + _result.tiers.addAll(tiers); + } + if (numComponents != null) { + _result.numComponents = numComponents; + } + if (componentFeerate != null) { + _result.componentFeerate = componentFeerate; + } + if (minExcessFee != null) { + _result.minExcessFee = minExcessFee; + } + if (maxExcessFee != null) { + _result.maxExcessFee = maxExcessFee; + } + if (donationAddress != null) { + _result.donationAddress = donationAddress; + } + return _result; + } + factory ServerHello.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ServerHello.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ServerHello clone() => ServerHello()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ServerHello copyWith(void Function(ServerHello) updates) => super.copyWith((message) => updates(message as ServerHello)) as ServerHello; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ServerHello create() => ServerHello._(); + ServerHello createEmptyInstance() => create(); + static $pb.PbList<ServerHello> createRepeated() => $pb.PbList<ServerHello>(); + @$core.pragma('dart2js:noInline') + static ServerHello getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ServerHello>(create); + static ServerHello? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$fixnum.Int64> get tiers => $_getList(0); + + @$pb.TagNumber(2) + $core.int get numComponents => $_getIZ(1); + @$pb.TagNumber(2) + set numComponents($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasNumComponents() => $_has(1); + @$pb.TagNumber(2) + void clearNumComponents() => clearField(2); + + @$pb.TagNumber(4) + $fixnum.Int64 get componentFeerate => $_getI64(2); + @$pb.TagNumber(4) + set componentFeerate($fixnum.Int64 v) { $_setInt64(2, v); } + @$pb.TagNumber(4) + $core.bool hasComponentFeerate() => $_has(2); + @$pb.TagNumber(4) + void clearComponentFeerate() => clearField(4); + + @$pb.TagNumber(5) + $fixnum.Int64 get minExcessFee => $_getI64(3); + @$pb.TagNumber(5) + set minExcessFee($fixnum.Int64 v) { $_setInt64(3, v); } + @$pb.TagNumber(5) + $core.bool hasMinExcessFee() => $_has(3); + @$pb.TagNumber(5) + void clearMinExcessFee() => clearField(5); + + @$pb.TagNumber(6) + $fixnum.Int64 get maxExcessFee => $_getI64(4); + @$pb.TagNumber(6) + set maxExcessFee($fixnum.Int64 v) { $_setInt64(4, v); } + @$pb.TagNumber(6) + $core.bool hasMaxExcessFee() => $_has(4); + @$pb.TagNumber(6) + void clearMaxExcessFee() => clearField(6); + + @$pb.TagNumber(15) + $core.String get donationAddress => $_getSZ(5); + @$pb.TagNumber(15) + set donationAddress($core.String v) { $_setString(5, v); } + @$pb.TagNumber(15) + $core.bool hasDonationAddress() => $_has(5); + @$pb.TagNumber(15) + void clearDonationAddress() => clearField(15); +} + +class JoinPools_PoolTag extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'JoinPools.PoolTag', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id', $pb.PbFieldType.QY) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'limit', $pb.PbFieldType.QU3) + ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'noIp') + ; + + JoinPools_PoolTag._() : super(); + factory JoinPools_PoolTag({ + $core.List<$core.int>? id, + $core.int? limit, + $core.bool? noIp, + }) { + final _result = create(); + if (id != null) { + _result.id = id; + } + if (limit != null) { + _result.limit = limit; + } + if (noIp != null) { + _result.noIp = noIp; + } + return _result; + } + factory JoinPools_PoolTag.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory JoinPools_PoolTag.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + JoinPools_PoolTag clone() => JoinPools_PoolTag()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + JoinPools_PoolTag copyWith(void Function(JoinPools_PoolTag) updates) => super.copyWith((message) => updates(message as JoinPools_PoolTag)) as JoinPools_PoolTag; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static JoinPools_PoolTag create() => JoinPools_PoolTag._(); + JoinPools_PoolTag createEmptyInstance() => create(); + static $pb.PbList<JoinPools_PoolTag> createRepeated() => $pb.PbList<JoinPools_PoolTag>(); + @$core.pragma('dart2js:noInline') + static JoinPools_PoolTag getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<JoinPools_PoolTag>(create); + static JoinPools_PoolTag? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get id => $_getN(0); + @$pb.TagNumber(1) + set id($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasId() => $_has(0); + @$pb.TagNumber(1) + void clearId() => clearField(1); + + @$pb.TagNumber(2) + $core.int get limit => $_getIZ(1); + @$pb.TagNumber(2) + set limit($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasLimit() => $_has(1); + @$pb.TagNumber(2) + void clearLimit() => clearField(2); + + @$pb.TagNumber(3) + $core.bool get noIp => $_getBF(2); + @$pb.TagNumber(3) + set noIp($core.bool v) { $_setBool(2, v); } + @$pb.TagNumber(3) + $core.bool hasNoIp() => $_has(2); + @$pb.TagNumber(3) + void clearNoIp() => clearField(3); +} + +class JoinPools extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'JoinPools', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tiers', $pb.PbFieldType.PU6) + ..pc<JoinPools_PoolTag>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tags', $pb.PbFieldType.PM, subBuilder: JoinPools_PoolTag.create) + ; + + JoinPools._() : super(); + factory JoinPools({ + $core.Iterable<$fixnum.Int64>? tiers, + $core.Iterable<JoinPools_PoolTag>? tags, + }) { + final _result = create(); + if (tiers != null) { + _result.tiers.addAll(tiers); + } + if (tags != null) { + _result.tags.addAll(tags); + } + return _result; + } + factory JoinPools.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory JoinPools.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + JoinPools clone() => JoinPools()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + JoinPools copyWith(void Function(JoinPools) updates) => super.copyWith((message) => updates(message as JoinPools)) as JoinPools; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static JoinPools create() => JoinPools._(); + JoinPools createEmptyInstance() => create(); + static $pb.PbList<JoinPools> createRepeated() => $pb.PbList<JoinPools>(); + @$core.pragma('dart2js:noInline') + static JoinPools getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<JoinPools>(create); + static JoinPools? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$fixnum.Int64> get tiers => $_getList(0); + + @$pb.TagNumber(2) + $core.List<JoinPools_PoolTag> get tags => $_getList(1); +} + +class TierStatusUpdate_TierStatus extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TierStatusUpdate.TierStatus', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'players', $pb.PbFieldType.OU3) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'minPlayers', $pb.PbFieldType.OU3) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'maxPlayers', $pb.PbFieldType.OU3) + ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeRemaining', $pb.PbFieldType.OU3) + ..hasRequiredFields = false + ; + + TierStatusUpdate_TierStatus._() : super(); + factory TierStatusUpdate_TierStatus({ + $core.int? players, + $core.int? minPlayers, + $core.int? maxPlayers, + $core.int? timeRemaining, + }) { + final _result = create(); + if (players != null) { + _result.players = players; + } + if (minPlayers != null) { + _result.minPlayers = minPlayers; + } + if (maxPlayers != null) { + _result.maxPlayers = maxPlayers; + } + if (timeRemaining != null) { + _result.timeRemaining = timeRemaining; + } + return _result; + } + factory TierStatusUpdate_TierStatus.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TierStatusUpdate_TierStatus.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TierStatusUpdate_TierStatus clone() => TierStatusUpdate_TierStatus()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TierStatusUpdate_TierStatus copyWith(void Function(TierStatusUpdate_TierStatus) updates) => super.copyWith((message) => updates(message as TierStatusUpdate_TierStatus)) as TierStatusUpdate_TierStatus; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TierStatusUpdate_TierStatus create() => TierStatusUpdate_TierStatus._(); + TierStatusUpdate_TierStatus createEmptyInstance() => create(); + static $pb.PbList<TierStatusUpdate_TierStatus> createRepeated() => $pb.PbList<TierStatusUpdate_TierStatus>(); + @$core.pragma('dart2js:noInline') + static TierStatusUpdate_TierStatus getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TierStatusUpdate_TierStatus>(create); + static TierStatusUpdate_TierStatus? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get players => $_getIZ(0); + @$pb.TagNumber(1) + set players($core.int v) { $_setUnsignedInt32(0, v); } + @$pb.TagNumber(1) + $core.bool hasPlayers() => $_has(0); + @$pb.TagNumber(1) + void clearPlayers() => clearField(1); + + @$pb.TagNumber(2) + $core.int get minPlayers => $_getIZ(1); + @$pb.TagNumber(2) + set minPlayers($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasMinPlayers() => $_has(1); + @$pb.TagNumber(2) + void clearMinPlayers() => clearField(2); + + @$pb.TagNumber(3) + $core.int get maxPlayers => $_getIZ(2); + @$pb.TagNumber(3) + set maxPlayers($core.int v) { $_setUnsignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasMaxPlayers() => $_has(2); + @$pb.TagNumber(3) + void clearMaxPlayers() => clearField(3); + + @$pb.TagNumber(4) + $core.int get timeRemaining => $_getIZ(3); + @$pb.TagNumber(4) + set timeRemaining($core.int v) { $_setUnsignedInt32(3, v); } + @$pb.TagNumber(4) + $core.bool hasTimeRemaining() => $_has(3); + @$pb.TagNumber(4) + void clearTimeRemaining() => clearField(4); +} + +class TierStatusUpdate extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TierStatusUpdate', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..m<$fixnum.Int64, TierStatusUpdate_TierStatus>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'statuses', entryClassName: 'TierStatusUpdate.StatusesEntry', keyFieldType: $pb.PbFieldType.OU6, valueFieldType: $pb.PbFieldType.OM, valueCreator: TierStatusUpdate_TierStatus.create, packageName: const $pb.PackageName('fusion')) + ..hasRequiredFields = false + ; + + TierStatusUpdate._() : super(); + factory TierStatusUpdate({ + $core.Map<$fixnum.Int64, TierStatusUpdate_TierStatus>? statuses, + }) { + final _result = create(); + if (statuses != null) { + _result.statuses.addAll(statuses); + } + return _result; + } + factory TierStatusUpdate.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TierStatusUpdate.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TierStatusUpdate clone() => TierStatusUpdate()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TierStatusUpdate copyWith(void Function(TierStatusUpdate) updates) => super.copyWith((message) => updates(message as TierStatusUpdate)) as TierStatusUpdate; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TierStatusUpdate create() => TierStatusUpdate._(); + TierStatusUpdate createEmptyInstance() => create(); + static $pb.PbList<TierStatusUpdate> createRepeated() => $pb.PbList<TierStatusUpdate>(); + @$core.pragma('dart2js:noInline') + static TierStatusUpdate getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TierStatusUpdate>(create); + static TierStatusUpdate? _defaultInstance; + + @$pb.TagNumber(1) + $core.Map<$fixnum.Int64, TierStatusUpdate_TierStatus> get statuses => $_getMap(0); +} + +class FusionBegin extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FusionBegin', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tier', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertDomain', $pb.PbFieldType.QY) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertPort', $pb.PbFieldType.QU3) + ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertSsl') + ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverTime', $pb.PbFieldType.QF6, defaultOrMaker: $fixnum.Int64.ZERO) + ; + + FusionBegin._() : super(); + factory FusionBegin({ + $fixnum.Int64? tier, + $core.List<$core.int>? covertDomain, + $core.int? covertPort, + $core.bool? covertSsl, + $fixnum.Int64? serverTime, + }) { + final _result = create(); + if (tier != null) { + _result.tier = tier; + } + if (covertDomain != null) { + _result.covertDomain = covertDomain; + } + if (covertPort != null) { + _result.covertPort = covertPort; + } + if (covertSsl != null) { + _result.covertSsl = covertSsl; + } + if (serverTime != null) { + _result.serverTime = serverTime; + } + return _result; + } + factory FusionBegin.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FusionBegin.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + FusionBegin clone() => FusionBegin()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + FusionBegin copyWith(void Function(FusionBegin) updates) => super.copyWith((message) => updates(message as FusionBegin)) as FusionBegin; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static FusionBegin create() => FusionBegin._(); + FusionBegin createEmptyInstance() => create(); + static $pb.PbList<FusionBegin> createRepeated() => $pb.PbList<FusionBegin>(); + @$core.pragma('dart2js:noInline') + static FusionBegin getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FusionBegin>(create); + static FusionBegin? _defaultInstance; + + @$pb.TagNumber(1) + $fixnum.Int64 get tier => $_getI64(0); + @$pb.TagNumber(1) + set tier($fixnum.Int64 v) { $_setInt64(0, v); } + @$pb.TagNumber(1) + $core.bool hasTier() => $_has(0); + @$pb.TagNumber(1) + void clearTier() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get covertDomain => $_getN(1); + @$pb.TagNumber(2) + set covertDomain($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasCovertDomain() => $_has(1); + @$pb.TagNumber(2) + void clearCovertDomain() => clearField(2); + + @$pb.TagNumber(3) + $core.int get covertPort => $_getIZ(2); + @$pb.TagNumber(3) + set covertPort($core.int v) { $_setUnsignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasCovertPort() => $_has(2); + @$pb.TagNumber(3) + void clearCovertPort() => clearField(3); + + @$pb.TagNumber(4) + $core.bool get covertSsl => $_getBF(3); + @$pb.TagNumber(4) + set covertSsl($core.bool v) { $_setBool(3, v); } + @$pb.TagNumber(4) + $core.bool hasCovertSsl() => $_has(3); + @$pb.TagNumber(4) + void clearCovertSsl() => clearField(4); + + @$pb.TagNumber(5) + $fixnum.Int64 get serverTime => $_getI64(4); + @$pb.TagNumber(5) + set serverTime($fixnum.Int64 v) { $_setInt64(4, v); } + @$pb.TagNumber(5) + $core.bool hasServerTime() => $_has(4); + @$pb.TagNumber(5) + void clearServerTime() => clearField(5); +} + +class StartRound extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'StartRound', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.QY) + ..p<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindNoncePoints', $pb.PbFieldType.PY) + ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverTime', $pb.PbFieldType.QF6, defaultOrMaker: $fixnum.Int64.ZERO) + ; + + StartRound._() : super(); + factory StartRound({ + $core.List<$core.int>? roundPubkey, + $core.Iterable<$core.List<$core.int>>? blindNoncePoints, + $fixnum.Int64? serverTime, + }) { + final _result = create(); + if (roundPubkey != null) { + _result.roundPubkey = roundPubkey; + } + if (blindNoncePoints != null) { + _result.blindNoncePoints.addAll(blindNoncePoints); + } + if (serverTime != null) { + _result.serverTime = serverTime; + } + return _result; + } + factory StartRound.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory StartRound.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + StartRound clone() => StartRound()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + StartRound copyWith(void Function(StartRound) updates) => super.copyWith((message) => updates(message as StartRound)) as StartRound; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static StartRound create() => StartRound._(); + StartRound createEmptyInstance() => create(); + static $pb.PbList<StartRound> createRepeated() => $pb.PbList<StartRound>(); + @$core.pragma('dart2js:noInline') + static StartRound getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<StartRound>(create); + static StartRound? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get roundPubkey => $_getN(0); + @$pb.TagNumber(1) + set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasRoundPubkey() => $_has(0); + @$pb.TagNumber(1) + void clearRoundPubkey() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.List<$core.int>> get blindNoncePoints => $_getList(1); + + @$pb.TagNumber(5) + $fixnum.Int64 get serverTime => $_getI64(2); + @$pb.TagNumber(5) + set serverTime($fixnum.Int64 v) { $_setInt64(2, v); } + @$pb.TagNumber(5) + $core.bool hasServerTime() => $_has(2); + @$pb.TagNumber(5) + void clearServerTime() => clearField(5); +} + +class PlayerCommit extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'PlayerCommit', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'initialCommitments', $pb.PbFieldType.PY) + ..a<$fixnum.Int64>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'excessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pedersenTotalNonce', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'randomNumberCommitment', $pb.PbFieldType.QY) + ..p<$core.List<$core.int>>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindSigRequests', $pb.PbFieldType.PY) + ; + + PlayerCommit._() : super(); + factory PlayerCommit({ + $core.Iterable<$core.List<$core.int>>? initialCommitments, + $fixnum.Int64? excessFee, + $core.List<$core.int>? pedersenTotalNonce, + $core.List<$core.int>? randomNumberCommitment, + $core.Iterable<$core.List<$core.int>>? blindSigRequests, + }) { + final _result = create(); + if (initialCommitments != null) { + _result.initialCommitments.addAll(initialCommitments); + } + if (excessFee != null) { + _result.excessFee = excessFee; + } + if (pedersenTotalNonce != null) { + _result.pedersenTotalNonce = pedersenTotalNonce; + } + if (randomNumberCommitment != null) { + _result.randomNumberCommitment = randomNumberCommitment; + } + if (blindSigRequests != null) { + _result.blindSigRequests.addAll(blindSigRequests); + } + return _result; + } + factory PlayerCommit.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory PlayerCommit.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + PlayerCommit clone() => PlayerCommit()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + PlayerCommit copyWith(void Function(PlayerCommit) updates) => super.copyWith((message) => updates(message as PlayerCommit)) as PlayerCommit; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static PlayerCommit create() => PlayerCommit._(); + PlayerCommit createEmptyInstance() => create(); + static $pb.PbList<PlayerCommit> createRepeated() => $pb.PbList<PlayerCommit>(); + @$core.pragma('dart2js:noInline') + static PlayerCommit getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<PlayerCommit>(create); + static PlayerCommit? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.List<$core.int>> get initialCommitments => $_getList(0); + + @$pb.TagNumber(2) + $fixnum.Int64 get excessFee => $_getI64(1); + @$pb.TagNumber(2) + set excessFee($fixnum.Int64 v) { $_setInt64(1, v); } + @$pb.TagNumber(2) + $core.bool hasExcessFee() => $_has(1); + @$pb.TagNumber(2) + void clearExcessFee() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get pedersenTotalNonce => $_getN(2); + @$pb.TagNumber(3) + set pedersenTotalNonce($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasPedersenTotalNonce() => $_has(2); + @$pb.TagNumber(3) + void clearPedersenTotalNonce() => clearField(3); + + @$pb.TagNumber(4) + $core.List<$core.int> get randomNumberCommitment => $_getN(3); + @$pb.TagNumber(4) + set randomNumberCommitment($core.List<$core.int> v) { $_setBytes(3, v); } + @$pb.TagNumber(4) + $core.bool hasRandomNumberCommitment() => $_has(3); + @$pb.TagNumber(4) + void clearRandomNumberCommitment() => clearField(4); + + @$pb.TagNumber(5) + $core.List<$core.List<$core.int>> get blindSigRequests => $_getList(4); +} + +class BlindSigResponses extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlindSigResponses', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scalars', $pb.PbFieldType.PY) + ..hasRequiredFields = false + ; + + BlindSigResponses._() : super(); + factory BlindSigResponses({ + $core.Iterable<$core.List<$core.int>>? scalars, + }) { + final _result = create(); + if (scalars != null) { + _result.scalars.addAll(scalars); + } + return _result; + } + factory BlindSigResponses.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory BlindSigResponses.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + BlindSigResponses clone() => BlindSigResponses()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + BlindSigResponses copyWith(void Function(BlindSigResponses) updates) => super.copyWith((message) => updates(message as BlindSigResponses)) as BlindSigResponses; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static BlindSigResponses create() => BlindSigResponses._(); + BlindSigResponses createEmptyInstance() => create(); + static $pb.PbList<BlindSigResponses> createRepeated() => $pb.PbList<BlindSigResponses>(); + @$core.pragma('dart2js:noInline') + static BlindSigResponses getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BlindSigResponses>(create); + static BlindSigResponses? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.List<$core.int>> get scalars => $_getList(0); +} + +class AllCommitments extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AllCommitments', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'initialCommitments', $pb.PbFieldType.PY) + ..hasRequiredFields = false + ; + + AllCommitments._() : super(); + factory AllCommitments({ + $core.Iterable<$core.List<$core.int>>? initialCommitments, + }) { + final _result = create(); + if (initialCommitments != null) { + _result.initialCommitments.addAll(initialCommitments); + } + return _result; + } + factory AllCommitments.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory AllCommitments.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + AllCommitments clone() => AllCommitments()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + AllCommitments copyWith(void Function(AllCommitments) updates) => super.copyWith((message) => updates(message as AllCommitments)) as AllCommitments; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static AllCommitments create() => AllCommitments._(); + AllCommitments createEmptyInstance() => create(); + static $pb.PbList<AllCommitments> createRepeated() => $pb.PbList<AllCommitments>(); + @$core.pragma('dart2js:noInline') + static AllCommitments getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AllCommitments>(create); + static AllCommitments? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.List<$core.int>> get initialCommitments => $_getList(0); +} + +class CovertComponent extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.OY) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signature', $pb.PbFieldType.QY) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'component', $pb.PbFieldType.QY) + ; + + CovertComponent._() : super(); + factory CovertComponent({ + $core.List<$core.int>? roundPubkey, + $core.List<$core.int>? signature, + $core.List<$core.int>? component, + }) { + final _result = create(); + if (roundPubkey != null) { + _result.roundPubkey = roundPubkey; + } + if (signature != null) { + _result.signature = signature; + } + if (component != null) { + _result.component = component; + } + return _result; + } + factory CovertComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CovertComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CovertComponent clone() => CovertComponent()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CovertComponent copyWith(void Function(CovertComponent) updates) => super.copyWith((message) => updates(message as CovertComponent)) as CovertComponent; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CovertComponent create() => CovertComponent._(); + CovertComponent createEmptyInstance() => create(); + static $pb.PbList<CovertComponent> createRepeated() => $pb.PbList<CovertComponent>(); + @$core.pragma('dart2js:noInline') + static CovertComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertComponent>(create); + static CovertComponent? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get roundPubkey => $_getN(0); + @$pb.TagNumber(1) + set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasRoundPubkey() => $_has(0); + @$pb.TagNumber(1) + void clearRoundPubkey() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get signature => $_getN(1); + @$pb.TagNumber(2) + set signature($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasSignature() => $_has(1); + @$pb.TagNumber(2) + void clearSignature() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get component => $_getN(2); + @$pb.TagNumber(3) + set component($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasComponent() => $_has(2); + @$pb.TagNumber(3) + void clearComponent() => clearField(3); +} + +class ShareCovertComponents extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ShareCovertComponents', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$core.List<$core.int>>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'components', $pb.PbFieldType.PY) + ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'skipSignatures') + ..a<$core.List<$core.int>>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sessionHash', $pb.PbFieldType.OY) + ..hasRequiredFields = false + ; + + ShareCovertComponents._() : super(); + factory ShareCovertComponents({ + $core.Iterable<$core.List<$core.int>>? components, + $core.bool? skipSignatures, + $core.List<$core.int>? sessionHash, + }) { + final _result = create(); + if (components != null) { + _result.components.addAll(components); + } + if (skipSignatures != null) { + _result.skipSignatures = skipSignatures; + } + if (sessionHash != null) { + _result.sessionHash = sessionHash; + } + return _result; + } + factory ShareCovertComponents.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ShareCovertComponents.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ShareCovertComponents clone() => ShareCovertComponents()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ShareCovertComponents copyWith(void Function(ShareCovertComponents) updates) => super.copyWith((message) => updates(message as ShareCovertComponents)) as ShareCovertComponents; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ShareCovertComponents create() => ShareCovertComponents._(); + ShareCovertComponents createEmptyInstance() => create(); + static $pb.PbList<ShareCovertComponents> createRepeated() => $pb.PbList<ShareCovertComponents>(); + @$core.pragma('dart2js:noInline') + static ShareCovertComponents getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ShareCovertComponents>(create); + static ShareCovertComponents? _defaultInstance; + + @$pb.TagNumber(4) + $core.List<$core.List<$core.int>> get components => $_getList(0); + + @$pb.TagNumber(5) + $core.bool get skipSignatures => $_getBF(1); + @$pb.TagNumber(5) + set skipSignatures($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(5) + $core.bool hasSkipSignatures() => $_has(1); + @$pb.TagNumber(5) + void clearSkipSignatures() => clearField(5); + + @$pb.TagNumber(6) + $core.List<$core.int> get sessionHash => $_getN(2); + @$pb.TagNumber(6) + set sessionHash($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(6) + $core.bool hasSessionHash() => $_has(2); + @$pb.TagNumber(6) + void clearSessionHash() => clearField(6); +} + +class CovertTransactionSignature extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertTransactionSignature', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.OY) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'whichInput', $pb.PbFieldType.QU3) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'txsignature', $pb.PbFieldType.QY) + ; + + CovertTransactionSignature._() : super(); + factory CovertTransactionSignature({ + $core.List<$core.int>? roundPubkey, + $core.int? whichInput, + $core.List<$core.int>? txsignature, + }) { + final _result = create(); + if (roundPubkey != null) { + _result.roundPubkey = roundPubkey; + } + if (whichInput != null) { + _result.whichInput = whichInput; + } + if (txsignature != null) { + _result.txsignature = txsignature; + } + return _result; + } + factory CovertTransactionSignature.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CovertTransactionSignature.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CovertTransactionSignature clone() => CovertTransactionSignature()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CovertTransactionSignature copyWith(void Function(CovertTransactionSignature) updates) => super.copyWith((message) => updates(message as CovertTransactionSignature)) as CovertTransactionSignature; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CovertTransactionSignature create() => CovertTransactionSignature._(); + CovertTransactionSignature createEmptyInstance() => create(); + static $pb.PbList<CovertTransactionSignature> createRepeated() => $pb.PbList<CovertTransactionSignature>(); + @$core.pragma('dart2js:noInline') + static CovertTransactionSignature getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertTransactionSignature>(create); + static CovertTransactionSignature? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get roundPubkey => $_getN(0); + @$pb.TagNumber(1) + set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasRoundPubkey() => $_has(0); + @$pb.TagNumber(1) + void clearRoundPubkey() => clearField(1); + + @$pb.TagNumber(2) + $core.int get whichInput => $_getIZ(1); + @$pb.TagNumber(2) + set whichInput($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasWhichInput() => $_has(1); + @$pb.TagNumber(2) + void clearWhichInput() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get txsignature => $_getN(2); + @$pb.TagNumber(3) + set txsignature($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasTxsignature() => $_has(2); + @$pb.TagNumber(3) + void clearTxsignature() => clearField(3); +} + +class FusionResult extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FusionResult', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.bool>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ok', $pb.PbFieldType.QB) + ..p<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'txsignatures', $pb.PbFieldType.PY) + ..p<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'badComponents', $pb.PbFieldType.PU3) + ; + + FusionResult._() : super(); + factory FusionResult({ + $core.bool? ok, + $core.Iterable<$core.List<$core.int>>? txsignatures, + $core.Iterable<$core.int>? badComponents, + }) { + final _result = create(); + if (ok != null) { + _result.ok = ok; + } + if (txsignatures != null) { + _result.txsignatures.addAll(txsignatures); + } + if (badComponents != null) { + _result.badComponents.addAll(badComponents); + } + return _result; + } + factory FusionResult.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory FusionResult.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + FusionResult clone() => FusionResult()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + FusionResult copyWith(void Function(FusionResult) updates) => super.copyWith((message) => updates(message as FusionResult)) as FusionResult; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static FusionResult create() => FusionResult._(); + FusionResult createEmptyInstance() => create(); + static $pb.PbList<FusionResult> createRepeated() => $pb.PbList<FusionResult>(); + @$core.pragma('dart2js:noInline') + static FusionResult getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FusionResult>(create); + static FusionResult? _defaultInstance; + + @$pb.TagNumber(1) + $core.bool get ok => $_getBF(0); + @$pb.TagNumber(1) + set ok($core.bool v) { $_setBool(0, v); } + @$pb.TagNumber(1) + $core.bool hasOk() => $_has(0); + @$pb.TagNumber(1) + void clearOk() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.List<$core.int>> get txsignatures => $_getList(1); + + @$pb.TagNumber(3) + $core.List<$core.int> get badComponents => $_getList(2); +} + +class MyProofsList extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MyProofsList', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'encryptedProofs', $pb.PbFieldType.PY) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'randomNumber', $pb.PbFieldType.QY) + ; + + MyProofsList._() : super(); + factory MyProofsList({ + $core.Iterable<$core.List<$core.int>>? encryptedProofs, + $core.List<$core.int>? randomNumber, + }) { + final _result = create(); + if (encryptedProofs != null) { + _result.encryptedProofs.addAll(encryptedProofs); + } + if (randomNumber != null) { + _result.randomNumber = randomNumber; + } + return _result; + } + factory MyProofsList.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory MyProofsList.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + MyProofsList clone() => MyProofsList()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + MyProofsList copyWith(void Function(MyProofsList) updates) => super.copyWith((message) => updates(message as MyProofsList)) as MyProofsList; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static MyProofsList create() => MyProofsList._(); + MyProofsList createEmptyInstance() => create(); + static $pb.PbList<MyProofsList> createRepeated() => $pb.PbList<MyProofsList>(); + @$core.pragma('dart2js:noInline') + static MyProofsList getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<MyProofsList>(create); + static MyProofsList? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.List<$core.int>> get encryptedProofs => $_getList(0); + + @$pb.TagNumber(2) + $core.List<$core.int> get randomNumber => $_getN(1); + @$pb.TagNumber(2) + set randomNumber($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasRandomNumber() => $_has(1); + @$pb.TagNumber(2) + void clearRandomNumber() => clearField(2); +} + +class TheirProofsList_RelayedProof extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TheirProofsList.RelayedProof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'encryptedProof', $pb.PbFieldType.QY) + ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'srcCommitmentIdx', $pb.PbFieldType.QU3) + ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dstKeyIdx', $pb.PbFieldType.QU3) + ; + + TheirProofsList_RelayedProof._() : super(); + factory TheirProofsList_RelayedProof({ + $core.List<$core.int>? encryptedProof, + $core.int? srcCommitmentIdx, + $core.int? dstKeyIdx, + }) { + final _result = create(); + if (encryptedProof != null) { + _result.encryptedProof = encryptedProof; + } + if (srcCommitmentIdx != null) { + _result.srcCommitmentIdx = srcCommitmentIdx; + } + if (dstKeyIdx != null) { + _result.dstKeyIdx = dstKeyIdx; + } + return _result; + } + factory TheirProofsList_RelayedProof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TheirProofsList_RelayedProof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TheirProofsList_RelayedProof clone() => TheirProofsList_RelayedProof()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TheirProofsList_RelayedProof copyWith(void Function(TheirProofsList_RelayedProof) updates) => super.copyWith((message) => updates(message as TheirProofsList_RelayedProof)) as TheirProofsList_RelayedProof; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TheirProofsList_RelayedProof create() => TheirProofsList_RelayedProof._(); + TheirProofsList_RelayedProof createEmptyInstance() => create(); + static $pb.PbList<TheirProofsList_RelayedProof> createRepeated() => $pb.PbList<TheirProofsList_RelayedProof>(); + @$core.pragma('dart2js:noInline') + static TheirProofsList_RelayedProof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TheirProofsList_RelayedProof>(create); + static TheirProofsList_RelayedProof? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<$core.int> get encryptedProof => $_getN(0); + @$pb.TagNumber(1) + set encryptedProof($core.List<$core.int> v) { $_setBytes(0, v); } + @$pb.TagNumber(1) + $core.bool hasEncryptedProof() => $_has(0); + @$pb.TagNumber(1) + void clearEncryptedProof() => clearField(1); + + @$pb.TagNumber(2) + $core.int get srcCommitmentIdx => $_getIZ(1); + @$pb.TagNumber(2) + set srcCommitmentIdx($core.int v) { $_setUnsignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasSrcCommitmentIdx() => $_has(1); + @$pb.TagNumber(2) + void clearSrcCommitmentIdx() => clearField(2); + + @$pb.TagNumber(3) + $core.int get dstKeyIdx => $_getIZ(2); + @$pb.TagNumber(3) + set dstKeyIdx($core.int v) { $_setUnsignedInt32(2, v); } + @$pb.TagNumber(3) + $core.bool hasDstKeyIdx() => $_has(2); + @$pb.TagNumber(3) + void clearDstKeyIdx() => clearField(3); +} + +class TheirProofsList extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TheirProofsList', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..pc<TheirProofsList_RelayedProof>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'proofs', $pb.PbFieldType.PM, subBuilder: TheirProofsList_RelayedProof.create) + ; + + TheirProofsList._() : super(); + factory TheirProofsList({ + $core.Iterable<TheirProofsList_RelayedProof>? proofs, + }) { + final _result = create(); + if (proofs != null) { + _result.proofs.addAll(proofs); + } + return _result; + } + factory TheirProofsList.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory TheirProofsList.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + TheirProofsList clone() => TheirProofsList()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + TheirProofsList copyWith(void Function(TheirProofsList) updates) => super.copyWith((message) => updates(message as TheirProofsList)) as TheirProofsList; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static TheirProofsList create() => TheirProofsList._(); + TheirProofsList createEmptyInstance() => create(); + static $pb.PbList<TheirProofsList> createRepeated() => $pb.PbList<TheirProofsList>(); + @$core.pragma('dart2js:noInline') + static TheirProofsList getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TheirProofsList>(create); + static TheirProofsList? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<TheirProofsList_RelayedProof> get proofs => $_getList(0); +} + +enum Blames_BlameProof_Decrypter { + sessionKey, + privkey, + notSet +} + +class Blames_BlameProof extends $pb.GeneratedMessage { + static const $core.Map<$core.int, Blames_BlameProof_Decrypter> _Blames_BlameProof_DecrypterByTag = { + 2 : Blames_BlameProof_Decrypter.sessionKey, + 3 : Blames_BlameProof_Decrypter.privkey, + 0 : Blames_BlameProof_Decrypter.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Blames.BlameProof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [2, 3]) + ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'whichProof', $pb.PbFieldType.QU3) + ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sessionKey', $pb.PbFieldType.OY) + ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'privkey', $pb.PbFieldType.OY) + ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'needLookupBlockchain') + ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blameReason') + ; + + Blames_BlameProof._() : super(); + factory Blames_BlameProof({ + $core.int? whichProof, + $core.List<$core.int>? sessionKey, + $core.List<$core.int>? privkey, + $core.bool? needLookupBlockchain, + $core.String? blameReason, + }) { + final _result = create(); + if (whichProof != null) { + _result.whichProof = whichProof; + } + if (sessionKey != null) { + _result.sessionKey = sessionKey; + } + if (privkey != null) { + _result.privkey = privkey; + } + if (needLookupBlockchain != null) { + _result.needLookupBlockchain = needLookupBlockchain; + } + if (blameReason != null) { + _result.blameReason = blameReason; + } + return _result; + } + factory Blames_BlameProof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Blames_BlameProof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Blames_BlameProof clone() => Blames_BlameProof()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Blames_BlameProof copyWith(void Function(Blames_BlameProof) updates) => super.copyWith((message) => updates(message as Blames_BlameProof)) as Blames_BlameProof; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Blames_BlameProof create() => Blames_BlameProof._(); + Blames_BlameProof createEmptyInstance() => create(); + static $pb.PbList<Blames_BlameProof> createRepeated() => $pb.PbList<Blames_BlameProof>(); + @$core.pragma('dart2js:noInline') + static Blames_BlameProof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Blames_BlameProof>(create); + static Blames_BlameProof? _defaultInstance; + + Blames_BlameProof_Decrypter whichDecrypter() => _Blames_BlameProof_DecrypterByTag[$_whichOneof(0)]!; + void clearDecrypter() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + $core.int get whichProof => $_getIZ(0); + @$pb.TagNumber(1) + set whichProof($core.int v) { $_setUnsignedInt32(0, v); } + @$pb.TagNumber(1) + $core.bool hasWhichProof() => $_has(0); + @$pb.TagNumber(1) + void clearWhichProof() => clearField(1); + + @$pb.TagNumber(2) + $core.List<$core.int> get sessionKey => $_getN(1); + @$pb.TagNumber(2) + set sessionKey($core.List<$core.int> v) { $_setBytes(1, v); } + @$pb.TagNumber(2) + $core.bool hasSessionKey() => $_has(1); + @$pb.TagNumber(2) + void clearSessionKey() => clearField(2); + + @$pb.TagNumber(3) + $core.List<$core.int> get privkey => $_getN(2); + @$pb.TagNumber(3) + set privkey($core.List<$core.int> v) { $_setBytes(2, v); } + @$pb.TagNumber(3) + $core.bool hasPrivkey() => $_has(2); + @$pb.TagNumber(3) + void clearPrivkey() => clearField(3); + + @$pb.TagNumber(4) + $core.bool get needLookupBlockchain => $_getBF(3); + @$pb.TagNumber(4) + set needLookupBlockchain($core.bool v) { $_setBool(3, v); } + @$pb.TagNumber(4) + $core.bool hasNeedLookupBlockchain() => $_has(3); + @$pb.TagNumber(4) + void clearNeedLookupBlockchain() => clearField(4); + + @$pb.TagNumber(5) + $core.String get blameReason => $_getSZ(4); + @$pb.TagNumber(5) + set blameReason($core.String v) { $_setString(4, v); } + @$pb.TagNumber(5) + $core.bool hasBlameReason() => $_has(4); + @$pb.TagNumber(5) + void clearBlameReason() => clearField(5); +} + +class Blames extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Blames', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..pc<Blames_BlameProof>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blames', $pb.PbFieldType.PM, subBuilder: Blames_BlameProof.create) + ; + + Blames._() : super(); + factory Blames({ + $core.Iterable<Blames_BlameProof>? blames, + }) { + final _result = create(); + if (blames != null) { + _result.blames.addAll(blames); + } + return _result; + } + factory Blames.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Blames.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Blames clone() => Blames()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Blames copyWith(void Function(Blames) updates) => super.copyWith((message) => updates(message as Blames)) as Blames; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Blames create() => Blames._(); + Blames createEmptyInstance() => create(); + static $pb.PbList<Blames> createRepeated() => $pb.PbList<Blames>(); + @$core.pragma('dart2js:noInline') + static Blames getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Blames>(create); + static Blames? _defaultInstance; + + @$pb.TagNumber(1) + $core.List<Blames_BlameProof> get blames => $_getList(0); +} + +class RestartRound extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RestartRound', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..hasRequiredFields = false + ; + + RestartRound._() : super(); + factory RestartRound() => create(); + factory RestartRound.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory RestartRound.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + RestartRound clone() => RestartRound()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + RestartRound copyWith(void Function(RestartRound) updates) => super.copyWith((message) => updates(message as RestartRound)) as RestartRound; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static RestartRound create() => RestartRound._(); + RestartRound createEmptyInstance() => create(); + static $pb.PbList<RestartRound> createRepeated() => $pb.PbList<RestartRound>(); + @$core.pragma('dart2js:noInline') + static RestartRound getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RestartRound>(create); + static RestartRound? _defaultInstance; +} + +class Error extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Error', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'message') + ..hasRequiredFields = false + ; + + Error._() : super(); + factory Error({ + $core.String? message, + }) { + final _result = create(); + if (message != null) { + _result.message = message; + } + return _result; + } + factory Error.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Error.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Error clone() => Error()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Error copyWith(void Function(Error) updates) => super.copyWith((message) => updates(message as Error)) as Error; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Error create() => Error._(); + Error createEmptyInstance() => create(); + static $pb.PbList<Error> createRepeated() => $pb.PbList<Error>(); + @$core.pragma('dart2js:noInline') + static Error getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Error>(create); + static Error? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get message => $_getSZ(0); + @$pb.TagNumber(1) + set message($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasMessage() => $_has(0); + @$pb.TagNumber(1) + void clearMessage() => clearField(1); +} + +class Ping extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Ping', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..hasRequiredFields = false + ; + + Ping._() : super(); + factory Ping() => create(); + factory Ping.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Ping.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Ping clone() => Ping()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Ping copyWith(void Function(Ping) updates) => super.copyWith((message) => updates(message as Ping)) as Ping; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static Ping create() => Ping._(); + Ping createEmptyInstance() => create(); + static $pb.PbList<Ping> createRepeated() => $pb.PbList<Ping>(); + @$core.pragma('dart2js:noInline') + static Ping getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Ping>(create); + static Ping? _defaultInstance; +} + +class OK extends $pb.GeneratedMessage { + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'OK', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..hasRequiredFields = false + ; + + OK._() : super(); + factory OK() => create(); + factory OK.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory OK.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + OK clone() => OK()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + OK copyWith(void Function(OK) updates) => super.copyWith((message) => updates(message as OK)) as OK; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static OK create() => OK._(); + OK createEmptyInstance() => create(); + static $pb.PbList<OK> createRepeated() => $pb.PbList<OK>(); + @$core.pragma('dart2js:noInline') + static OK getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OK>(create); + static OK? _defaultInstance; +} + +enum ClientMessage_Msg { + clienthello, + joinpools, + playercommit, + myproofslist, + blames, + notSet +} + +class ClientMessage extends $pb.GeneratedMessage { + static const $core.Map<$core.int, ClientMessage_Msg> _ClientMessage_MsgByTag = { + 1 : ClientMessage_Msg.clienthello, + 2 : ClientMessage_Msg.joinpools, + 3 : ClientMessage_Msg.playercommit, + 5 : ClientMessage_Msg.myproofslist, + 6 : ClientMessage_Msg.blames, + 0 : ClientMessage_Msg.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ClientMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [1, 2, 3, 5, 6]) + ..aOM<ClientHello>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'clienthello', subBuilder: ClientHello.create) + ..aOM<JoinPools>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'joinpools', subBuilder: JoinPools.create) + ..aOM<PlayerCommit>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'playercommit', subBuilder: PlayerCommit.create) + ..aOM<MyProofsList>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'myproofslist', subBuilder: MyProofsList.create) + ..aOM<Blames>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blames', subBuilder: Blames.create) + ; + + ClientMessage._() : super(); + factory ClientMessage({ + ClientHello? clienthello, + JoinPools? joinpools, + PlayerCommit? playercommit, + MyProofsList? myproofslist, + Blames? blames, + }) { + final _result = create(); + if (clienthello != null) { + _result.clienthello = clienthello; + } + if (joinpools != null) { + _result.joinpools = joinpools; + } + if (playercommit != null) { + _result.playercommit = playercommit; + } + if (myproofslist != null) { + _result.myproofslist = myproofslist; + } + if (blames != null) { + _result.blames = blames; + } + return _result; + } + factory ClientMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ClientMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ClientMessage clone() => ClientMessage()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ClientMessage copyWith(void Function(ClientMessage) updates) => super.copyWith((message) => updates(message as ClientMessage)) as ClientMessage; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ClientMessage create() => ClientMessage._(); + ClientMessage createEmptyInstance() => create(); + static $pb.PbList<ClientMessage> createRepeated() => $pb.PbList<ClientMessage>(); + @$core.pragma('dart2js:noInline') + static ClientMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ClientMessage>(create); + static ClientMessage? _defaultInstance; + + ClientMessage_Msg whichMsg() => _ClientMessage_MsgByTag[$_whichOneof(0)]!; + void clearMsg() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + ClientHello get clienthello => $_getN(0); + @$pb.TagNumber(1) + set clienthello(ClientHello v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasClienthello() => $_has(0); + @$pb.TagNumber(1) + void clearClienthello() => clearField(1); + @$pb.TagNumber(1) + ClientHello ensureClienthello() => $_ensure(0); + + @$pb.TagNumber(2) + JoinPools get joinpools => $_getN(1); + @$pb.TagNumber(2) + set joinpools(JoinPools v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasJoinpools() => $_has(1); + @$pb.TagNumber(2) + void clearJoinpools() => clearField(2); + @$pb.TagNumber(2) + JoinPools ensureJoinpools() => $_ensure(1); + + @$pb.TagNumber(3) + PlayerCommit get playercommit => $_getN(2); + @$pb.TagNumber(3) + set playercommit(PlayerCommit v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasPlayercommit() => $_has(2); + @$pb.TagNumber(3) + void clearPlayercommit() => clearField(3); + @$pb.TagNumber(3) + PlayerCommit ensurePlayercommit() => $_ensure(2); + + @$pb.TagNumber(5) + MyProofsList get myproofslist => $_getN(3); + @$pb.TagNumber(5) + set myproofslist(MyProofsList v) { setField(5, v); } + @$pb.TagNumber(5) + $core.bool hasMyproofslist() => $_has(3); + @$pb.TagNumber(5) + void clearMyproofslist() => clearField(5); + @$pb.TagNumber(5) + MyProofsList ensureMyproofslist() => $_ensure(3); + + @$pb.TagNumber(6) + Blames get blames => $_getN(4); + @$pb.TagNumber(6) + set blames(Blames v) { setField(6, v); } + @$pb.TagNumber(6) + $core.bool hasBlames() => $_has(4); + @$pb.TagNumber(6) + void clearBlames() => clearField(6); + @$pb.TagNumber(6) + Blames ensureBlames() => $_ensure(4); +} + +enum ServerMessage_Msg { + serverhello, + tierstatusupdate, + fusionbegin, + startround, + blindsigresponses, + allcommitments, + sharecovertcomponents, + fusionresult, + theirproofslist, + restartround, + error, + notSet +} + +class ServerMessage extends $pb.GeneratedMessage { + static const $core.Map<$core.int, ServerMessage_Msg> _ServerMessage_MsgByTag = { + 1 : ServerMessage_Msg.serverhello, + 2 : ServerMessage_Msg.tierstatusupdate, + 3 : ServerMessage_Msg.fusionbegin, + 4 : ServerMessage_Msg.startround, + 5 : ServerMessage_Msg.blindsigresponses, + 6 : ServerMessage_Msg.allcommitments, + 7 : ServerMessage_Msg.sharecovertcomponents, + 8 : ServerMessage_Msg.fusionresult, + 9 : ServerMessage_Msg.theirproofslist, + 14 : ServerMessage_Msg.restartround, + 15 : ServerMessage_Msg.error, + 0 : ServerMessage_Msg.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ServerMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15]) + ..aOM<ServerHello>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverhello', subBuilder: ServerHello.create) + ..aOM<TierStatusUpdate>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tierstatusupdate', subBuilder: TierStatusUpdate.create) + ..aOM<FusionBegin>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fusionbegin', subBuilder: FusionBegin.create) + ..aOM<StartRound>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startround', subBuilder: StartRound.create) + ..aOM<BlindSigResponses>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindsigresponses', subBuilder: BlindSigResponses.create) + ..aOM<AllCommitments>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'allcommitments', subBuilder: AllCommitments.create) + ..aOM<ShareCovertComponents>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sharecovertcomponents', subBuilder: ShareCovertComponents.create) + ..aOM<FusionResult>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fusionresult', subBuilder: FusionResult.create) + ..aOM<TheirProofsList>(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'theirproofslist', subBuilder: TheirProofsList.create) + ..aOM<RestartRound>(14, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'restartround', subBuilder: RestartRound.create) + ..aOM<Error>(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'error', subBuilder: Error.create) + ; + + ServerMessage._() : super(); + factory ServerMessage({ + ServerHello? serverhello, + TierStatusUpdate? tierstatusupdate, + FusionBegin? fusionbegin, + StartRound? startround, + BlindSigResponses? blindsigresponses, + AllCommitments? allcommitments, + ShareCovertComponents? sharecovertcomponents, + FusionResult? fusionresult, + TheirProofsList? theirproofslist, + RestartRound? restartround, + Error? error, + }) { + final _result = create(); + if (serverhello != null) { + _result.serverhello = serverhello; + } + if (tierstatusupdate != null) { + _result.tierstatusupdate = tierstatusupdate; + } + if (fusionbegin != null) { + _result.fusionbegin = fusionbegin; + } + if (startround != null) { + _result.startround = startround; + } + if (blindsigresponses != null) { + _result.blindsigresponses = blindsigresponses; + } + if (allcommitments != null) { + _result.allcommitments = allcommitments; + } + if (sharecovertcomponents != null) { + _result.sharecovertcomponents = sharecovertcomponents; + } + if (fusionresult != null) { + _result.fusionresult = fusionresult; + } + if (theirproofslist != null) { + _result.theirproofslist = theirproofslist; + } + if (restartround != null) { + _result.restartround = restartround; + } + if (error != null) { + _result.error = error; + } + return _result; + } + factory ServerMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ServerMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ServerMessage clone() => ServerMessage()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ServerMessage copyWith(void Function(ServerMessage) updates) => super.copyWith((message) => updates(message as ServerMessage)) as ServerMessage; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static ServerMessage create() => ServerMessage._(); + ServerMessage createEmptyInstance() => create(); + static $pb.PbList<ServerMessage> createRepeated() => $pb.PbList<ServerMessage>(); + @$core.pragma('dart2js:noInline') + static ServerMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ServerMessage>(create); + static ServerMessage? _defaultInstance; + + ServerMessage_Msg whichMsg() => _ServerMessage_MsgByTag[$_whichOneof(0)]!; + void clearMsg() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + ServerHello get serverhello => $_getN(0); + @$pb.TagNumber(1) + set serverhello(ServerHello v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasServerhello() => $_has(0); + @$pb.TagNumber(1) + void clearServerhello() => clearField(1); + @$pb.TagNumber(1) + ServerHello ensureServerhello() => $_ensure(0); + + @$pb.TagNumber(2) + TierStatusUpdate get tierstatusupdate => $_getN(1); + @$pb.TagNumber(2) + set tierstatusupdate(TierStatusUpdate v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasTierstatusupdate() => $_has(1); + @$pb.TagNumber(2) + void clearTierstatusupdate() => clearField(2); + @$pb.TagNumber(2) + TierStatusUpdate ensureTierstatusupdate() => $_ensure(1); + + @$pb.TagNumber(3) + FusionBegin get fusionbegin => $_getN(2); + @$pb.TagNumber(3) + set fusionbegin(FusionBegin v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasFusionbegin() => $_has(2); + @$pb.TagNumber(3) + void clearFusionbegin() => clearField(3); + @$pb.TagNumber(3) + FusionBegin ensureFusionbegin() => $_ensure(2); + + @$pb.TagNumber(4) + StartRound get startround => $_getN(3); + @$pb.TagNumber(4) + set startround(StartRound v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasStartround() => $_has(3); + @$pb.TagNumber(4) + void clearStartround() => clearField(4); + @$pb.TagNumber(4) + StartRound ensureStartround() => $_ensure(3); + + @$pb.TagNumber(5) + BlindSigResponses get blindsigresponses => $_getN(4); + @$pb.TagNumber(5) + set blindsigresponses(BlindSigResponses v) { setField(5, v); } + @$pb.TagNumber(5) + $core.bool hasBlindsigresponses() => $_has(4); + @$pb.TagNumber(5) + void clearBlindsigresponses() => clearField(5); + @$pb.TagNumber(5) + BlindSigResponses ensureBlindsigresponses() => $_ensure(4); + + @$pb.TagNumber(6) + AllCommitments get allcommitments => $_getN(5); + @$pb.TagNumber(6) + set allcommitments(AllCommitments v) { setField(6, v); } + @$pb.TagNumber(6) + $core.bool hasAllcommitments() => $_has(5); + @$pb.TagNumber(6) + void clearAllcommitments() => clearField(6); + @$pb.TagNumber(6) + AllCommitments ensureAllcommitments() => $_ensure(5); + + @$pb.TagNumber(7) + ShareCovertComponents get sharecovertcomponents => $_getN(6); + @$pb.TagNumber(7) + set sharecovertcomponents(ShareCovertComponents v) { setField(7, v); } + @$pb.TagNumber(7) + $core.bool hasSharecovertcomponents() => $_has(6); + @$pb.TagNumber(7) + void clearSharecovertcomponents() => clearField(7); + @$pb.TagNumber(7) + ShareCovertComponents ensureSharecovertcomponents() => $_ensure(6); + + @$pb.TagNumber(8) + FusionResult get fusionresult => $_getN(7); + @$pb.TagNumber(8) + set fusionresult(FusionResult v) { setField(8, v); } + @$pb.TagNumber(8) + $core.bool hasFusionresult() => $_has(7); + @$pb.TagNumber(8) + void clearFusionresult() => clearField(8); + @$pb.TagNumber(8) + FusionResult ensureFusionresult() => $_ensure(7); + + @$pb.TagNumber(9) + TheirProofsList get theirproofslist => $_getN(8); + @$pb.TagNumber(9) + set theirproofslist(TheirProofsList v) { setField(9, v); } + @$pb.TagNumber(9) + $core.bool hasTheirproofslist() => $_has(8); + @$pb.TagNumber(9) + void clearTheirproofslist() => clearField(9); + @$pb.TagNumber(9) + TheirProofsList ensureTheirproofslist() => $_ensure(8); + + @$pb.TagNumber(14) + RestartRound get restartround => $_getN(9); + @$pb.TagNumber(14) + set restartround(RestartRound v) { setField(14, v); } + @$pb.TagNumber(14) + $core.bool hasRestartround() => $_has(9); + @$pb.TagNumber(14) + void clearRestartround() => clearField(14); + @$pb.TagNumber(14) + RestartRound ensureRestartround() => $_ensure(9); + + @$pb.TagNumber(15) + Error get error => $_getN(10); + @$pb.TagNumber(15) + set error(Error v) { setField(15, v); } + @$pb.TagNumber(15) + $core.bool hasError() => $_has(10); + @$pb.TagNumber(15) + void clearError() => clearField(15); + @$pb.TagNumber(15) + Error ensureError() => $_ensure(10); +} + +enum CovertMessage_Msg { + component, + signature, + ping, + notSet +} + +class CovertMessage extends $pb.GeneratedMessage { + static const $core.Map<$core.int, CovertMessage_Msg> _CovertMessage_MsgByTag = { + 1 : CovertMessage_Msg.component, + 2 : CovertMessage_Msg.signature, + 3 : CovertMessage_Msg.ping, + 0 : CovertMessage_Msg.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [1, 2, 3]) + ..aOM<CovertComponent>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'component', subBuilder: CovertComponent.create) + ..aOM<CovertTransactionSignature>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signature', subBuilder: CovertTransactionSignature.create) + ..aOM<Ping>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ping', subBuilder: Ping.create) + ; + + CovertMessage._() : super(); + factory CovertMessage({ + CovertComponent? component, + CovertTransactionSignature? signature, + Ping? ping, + }) { + final _result = create(); + if (component != null) { + _result.component = component; + } + if (signature != null) { + _result.signature = signature; + } + if (ping != null) { + _result.ping = ping; + } + return _result; + } + factory CovertMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CovertMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CovertMessage clone() => CovertMessage()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CovertMessage copyWith(void Function(CovertMessage) updates) => super.copyWith((message) => updates(message as CovertMessage)) as CovertMessage; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CovertMessage create() => CovertMessage._(); + CovertMessage createEmptyInstance() => create(); + static $pb.PbList<CovertMessage> createRepeated() => $pb.PbList<CovertMessage>(); + @$core.pragma('dart2js:noInline') + static CovertMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertMessage>(create); + static CovertMessage? _defaultInstance; + + CovertMessage_Msg whichMsg() => _CovertMessage_MsgByTag[$_whichOneof(0)]!; + void clearMsg() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + CovertComponent get component => $_getN(0); + @$pb.TagNumber(1) + set component(CovertComponent v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasComponent() => $_has(0); + @$pb.TagNumber(1) + void clearComponent() => clearField(1); + @$pb.TagNumber(1) + CovertComponent ensureComponent() => $_ensure(0); + + @$pb.TagNumber(2) + CovertTransactionSignature get signature => $_getN(1); + @$pb.TagNumber(2) + set signature(CovertTransactionSignature v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasSignature() => $_has(1); + @$pb.TagNumber(2) + void clearSignature() => clearField(2); + @$pb.TagNumber(2) + CovertTransactionSignature ensureSignature() => $_ensure(1); + + @$pb.TagNumber(3) + Ping get ping => $_getN(2); + @$pb.TagNumber(3) + set ping(Ping v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasPing() => $_has(2); + @$pb.TagNumber(3) + void clearPing() => clearField(3); + @$pb.TagNumber(3) + Ping ensurePing() => $_ensure(2); +} + +enum CovertResponse_Msg { + ok, + error, + notSet +} + +class CovertResponse extends $pb.GeneratedMessage { + static const $core.Map<$core.int, CovertResponse_Msg> _CovertResponse_MsgByTag = { + 1 : CovertResponse_Msg.ok, + 15 : CovertResponse_Msg.error, + 0 : CovertResponse_Msg.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) + ..oo(0, [1, 15]) + ..aOM<OK>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ok', subBuilder: OK.create) + ..aOM<Error>(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'error', subBuilder: Error.create) + ..hasRequiredFields = false + ; + + CovertResponse._() : super(); + factory CovertResponse({ + OK? ok, + Error? error, + }) { + final _result = create(); + if (ok != null) { + _result.ok = ok; + } + if (error != null) { + _result.error = error; + } + return _result; + } + factory CovertResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory CovertResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + CovertResponse clone() => CovertResponse()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + CovertResponse copyWith(void Function(CovertResponse) updates) => super.copyWith((message) => updates(message as CovertResponse)) as CovertResponse; // ignore: deprecated_member_use + $pb.BuilderInfo get info_ => _i; + @$core.pragma('dart2js:noInline') + static CovertResponse create() => CovertResponse._(); + CovertResponse createEmptyInstance() => create(); + static $pb.PbList<CovertResponse> createRepeated() => $pb.PbList<CovertResponse>(); + @$core.pragma('dart2js:noInline') + static CovertResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertResponse>(create); + static CovertResponse? _defaultInstance; + + CovertResponse_Msg whichMsg() => _CovertResponse_MsgByTag[$_whichOneof(0)]!; + void clearMsg() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + OK get ok => $_getN(0); + @$pb.TagNumber(1) + set ok(OK v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasOk() => $_has(0); + @$pb.TagNumber(1) + void clearOk() => clearField(1); + @$pb.TagNumber(1) + OK ensureOk() => $_ensure(0); + + @$pb.TagNumber(15) + Error get error => $_getN(1); + @$pb.TagNumber(15) + set error(Error v) { setField(15, v); } + @$pb.TagNumber(15) + $core.bool hasError() => $_has(1); + @$pb.TagNumber(15) + void clearError() => clearField(15); + @$pb.TagNumber(15) + Error ensureError() => $_ensure(1); +} + diff --git a/lib/services/cashfusion/protobuf/fusion.pbenum.dart b/lib/services/cashfusion/protobuf/fusion.pbenum.dart new file mode 100644 index 000000000..fb5c0d734 --- /dev/null +++ b/lib/services/cashfusion/protobuf/fusion.pbenum.dart @@ -0,0 +1,7 @@ +/// +// Generated code. Do not modify. +// source: fusion.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name + diff --git a/lib/services/cashfusion/protobuf/fusion.pbjson.dart b/lib/services/cashfusion/protobuf/fusion.pbjson.dart new file mode 100644 index 000000000..7735f5acf --- /dev/null +++ b/lib/services/cashfusion/protobuf/fusion.pbjson.dart @@ -0,0 +1,427 @@ +/// +// Generated code. Do not modify. +// source: fusion.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use inputComponentDescriptor instead') +const InputComponent$json = const { + '1': 'InputComponent', + '2': const [ + const {'1': 'prev_txid', '3': 1, '4': 2, '5': 12, '10': 'prevTxid'}, + const {'1': 'prev_index', '3': 2, '4': 2, '5': 13, '10': 'prevIndex'}, + const {'1': 'pubkey', '3': 3, '4': 2, '5': 12, '10': 'pubkey'}, + const {'1': 'amount', '3': 4, '4': 2, '5': 4, '10': 'amount'}, + ], +}; + +/// Descriptor for `InputComponent`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List inputComponentDescriptor = $convert.base64Decode('Cg5JbnB1dENvbXBvbmVudBIbCglwcmV2X3R4aWQYASACKAxSCHByZXZUeGlkEh0KCnByZXZfaW5kZXgYAiACKA1SCXByZXZJbmRleBIWCgZwdWJrZXkYAyACKAxSBnB1YmtleRIWCgZhbW91bnQYBCACKARSBmFtb3VudA=='); +@$core.Deprecated('Use outputComponentDescriptor instead') +const OutputComponent$json = const { + '1': 'OutputComponent', + '2': const [ + const {'1': 'scriptpubkey', '3': 1, '4': 2, '5': 12, '10': 'scriptpubkey'}, + const {'1': 'amount', '3': 2, '4': 2, '5': 4, '10': 'amount'}, + ], +}; + +/// Descriptor for `OutputComponent`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List outputComponentDescriptor = $convert.base64Decode('Cg9PdXRwdXRDb21wb25lbnQSIgoMc2NyaXB0cHVia2V5GAEgAigMUgxzY3JpcHRwdWJrZXkSFgoGYW1vdW50GAIgAigEUgZhbW91bnQ='); +@$core.Deprecated('Use blankComponentDescriptor instead') +const BlankComponent$json = const { + '1': 'BlankComponent', +}; + +/// Descriptor for `BlankComponent`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List blankComponentDescriptor = $convert.base64Decode('Cg5CbGFua0NvbXBvbmVudA=='); +@$core.Deprecated('Use componentDescriptor instead') +const Component$json = const { + '1': 'Component', + '2': const [ + const {'1': 'salt_commitment', '3': 1, '4': 2, '5': 12, '10': 'saltCommitment'}, + const {'1': 'input', '3': 2, '4': 1, '5': 11, '6': '.fusion.InputComponent', '9': 0, '10': 'input'}, + const {'1': 'output', '3': 3, '4': 1, '5': 11, '6': '.fusion.OutputComponent', '9': 0, '10': 'output'}, + const {'1': 'blank', '3': 4, '4': 1, '5': 11, '6': '.fusion.BlankComponent', '9': 0, '10': 'blank'}, + ], + '8': const [ + const {'1': 'component'}, + ], +}; + +/// Descriptor for `Component`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List componentDescriptor = $convert.base64Decode('CglDb21wb25lbnQSJwoPc2FsdF9jb21taXRtZW50GAEgAigMUg5zYWx0Q29tbWl0bWVudBIuCgVpbnB1dBgCIAEoCzIWLmZ1c2lvbi5JbnB1dENvbXBvbmVudEgAUgVpbnB1dBIxCgZvdXRwdXQYAyABKAsyFy5mdXNpb24uT3V0cHV0Q29tcG9uZW50SABSBm91dHB1dBIuCgVibGFuaxgEIAEoCzIWLmZ1c2lvbi5CbGFua0NvbXBvbmVudEgAUgVibGFua0ILCgljb21wb25lbnQ='); +@$core.Deprecated('Use initialCommitmentDescriptor instead') +const InitialCommitment$json = const { + '1': 'InitialCommitment', + '2': const [ + const {'1': 'salted_component_hash', '3': 1, '4': 2, '5': 12, '10': 'saltedComponentHash'}, + const {'1': 'amount_commitment', '3': 2, '4': 2, '5': 12, '10': 'amountCommitment'}, + const {'1': 'communication_key', '3': 3, '4': 2, '5': 12, '10': 'communicationKey'}, + ], +}; + +/// Descriptor for `InitialCommitment`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List initialCommitmentDescriptor = $convert.base64Decode('ChFJbml0aWFsQ29tbWl0bWVudBIyChVzYWx0ZWRfY29tcG9uZW50X2hhc2gYASACKAxSE3NhbHRlZENvbXBvbmVudEhhc2gSKwoRYW1vdW50X2NvbW1pdG1lbnQYAiACKAxSEGFtb3VudENvbW1pdG1lbnQSKwoRY29tbXVuaWNhdGlvbl9rZXkYAyACKAxSEGNvbW11bmljYXRpb25LZXk='); +@$core.Deprecated('Use proofDescriptor instead') +const Proof$json = const { + '1': 'Proof', + '2': const [ + const {'1': 'component_idx', '3': 1, '4': 2, '5': 7, '10': 'componentIdx'}, + const {'1': 'salt', '3': 2, '4': 2, '5': 12, '10': 'salt'}, + const {'1': 'pedersen_nonce', '3': 3, '4': 2, '5': 12, '10': 'pedersenNonce'}, + ], +}; + +/// Descriptor for `Proof`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List proofDescriptor = $convert.base64Decode('CgVQcm9vZhIjCg1jb21wb25lbnRfaWR4GAEgAigHUgxjb21wb25lbnRJZHgSEgoEc2FsdBgCIAIoDFIEc2FsdBIlCg5wZWRlcnNlbl9ub25jZRgDIAIoDFINcGVkZXJzZW5Ob25jZQ=='); +@$core.Deprecated('Use clientHelloDescriptor instead') +const ClientHello$json = const { + '1': 'ClientHello', + '2': const [ + const {'1': 'version', '3': 1, '4': 2, '5': 12, '10': 'version'}, + const {'1': 'genesis_hash', '3': 2, '4': 1, '5': 12, '10': 'genesisHash'}, + ], +}; + +/// Descriptor for `ClientHello`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List clientHelloDescriptor = $convert.base64Decode('CgtDbGllbnRIZWxsbxIYCgd2ZXJzaW9uGAEgAigMUgd2ZXJzaW9uEiEKDGdlbmVzaXNfaGFzaBgCIAEoDFILZ2VuZXNpc0hhc2g='); +@$core.Deprecated('Use serverHelloDescriptor instead') +const ServerHello$json = const { + '1': 'ServerHello', + '2': const [ + const {'1': 'tiers', '3': 1, '4': 3, '5': 4, '10': 'tiers'}, + const {'1': 'num_components', '3': 2, '4': 2, '5': 13, '10': 'numComponents'}, + const {'1': 'component_feerate', '3': 4, '4': 2, '5': 4, '10': 'componentFeerate'}, + const {'1': 'min_excess_fee', '3': 5, '4': 2, '5': 4, '10': 'minExcessFee'}, + const {'1': 'max_excess_fee', '3': 6, '4': 2, '5': 4, '10': 'maxExcessFee'}, + const {'1': 'donation_address', '3': 15, '4': 1, '5': 9, '10': 'donationAddress'}, + ], +}; + +/// Descriptor for `ServerHello`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List serverHelloDescriptor = $convert.base64Decode('CgtTZXJ2ZXJIZWxsbxIUCgV0aWVycxgBIAMoBFIFdGllcnMSJQoObnVtX2NvbXBvbmVudHMYAiACKA1SDW51bUNvbXBvbmVudHMSKwoRY29tcG9uZW50X2ZlZXJhdGUYBCACKARSEGNvbXBvbmVudEZlZXJhdGUSJAoObWluX2V4Y2Vzc19mZWUYBSACKARSDG1pbkV4Y2Vzc0ZlZRIkCg5tYXhfZXhjZXNzX2ZlZRgGIAIoBFIMbWF4RXhjZXNzRmVlEikKEGRvbmF0aW9uX2FkZHJlc3MYDyABKAlSD2RvbmF0aW9uQWRkcmVzcw=='); +@$core.Deprecated('Use joinPoolsDescriptor instead') +const JoinPools$json = const { + '1': 'JoinPools', + '2': const [ + const {'1': 'tiers', '3': 1, '4': 3, '5': 4, '10': 'tiers'}, + const {'1': 'tags', '3': 2, '4': 3, '5': 11, '6': '.fusion.JoinPools.PoolTag', '10': 'tags'}, + ], + '3': const [JoinPools_PoolTag$json], +}; + +@$core.Deprecated('Use joinPoolsDescriptor instead') +const JoinPools_PoolTag$json = const { + '1': 'PoolTag', + '2': const [ + const {'1': 'id', '3': 1, '4': 2, '5': 12, '10': 'id'}, + const {'1': 'limit', '3': 2, '4': 2, '5': 13, '10': 'limit'}, + const {'1': 'no_ip', '3': 3, '4': 1, '5': 8, '10': 'noIp'}, + ], +}; + +/// Descriptor for `JoinPools`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List joinPoolsDescriptor = $convert.base64Decode('CglKb2luUG9vbHMSFAoFdGllcnMYASADKARSBXRpZXJzEi0KBHRhZ3MYAiADKAsyGS5mdXNpb24uSm9pblBvb2xzLlBvb2xUYWdSBHRhZ3MaRAoHUG9vbFRhZxIOCgJpZBgBIAIoDFICaWQSFAoFbGltaXQYAiACKA1SBWxpbWl0EhMKBW5vX2lwGAMgASgIUgRub0lw'); +@$core.Deprecated('Use tierStatusUpdateDescriptor instead') +const TierStatusUpdate$json = const { + '1': 'TierStatusUpdate', + '2': const [ + const {'1': 'statuses', '3': 1, '4': 3, '5': 11, '6': '.fusion.TierStatusUpdate.StatusesEntry', '10': 'statuses'}, + ], + '3': const [TierStatusUpdate_TierStatus$json, TierStatusUpdate_StatusesEntry$json], +}; + +@$core.Deprecated('Use tierStatusUpdateDescriptor instead') +const TierStatusUpdate_TierStatus$json = const { + '1': 'TierStatus', + '2': const [ + const {'1': 'players', '3': 1, '4': 1, '5': 13, '10': 'players'}, + const {'1': 'min_players', '3': 2, '4': 1, '5': 13, '10': 'minPlayers'}, + const {'1': 'max_players', '3': 3, '4': 1, '5': 13, '10': 'maxPlayers'}, + const {'1': 'time_remaining', '3': 4, '4': 1, '5': 13, '10': 'timeRemaining'}, + ], +}; + +@$core.Deprecated('Use tierStatusUpdateDescriptor instead') +const TierStatusUpdate_StatusesEntry$json = const { + '1': 'StatusesEntry', + '2': const [ + const {'1': 'key', '3': 1, '4': 1, '5': 4, '10': 'key'}, + const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.fusion.TierStatusUpdate.TierStatus', '10': 'value'}, + ], + '7': const {'7': true}, +}; + +/// Descriptor for `TierStatusUpdate`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List tierStatusUpdateDescriptor = $convert.base64Decode('ChBUaWVyU3RhdHVzVXBkYXRlEkIKCHN0YXR1c2VzGAEgAygLMiYuZnVzaW9uLlRpZXJTdGF0dXNVcGRhdGUuU3RhdHVzZXNFbnRyeVIIc3RhdHVzZXMajwEKClRpZXJTdGF0dXMSGAoHcGxheWVycxgBIAEoDVIHcGxheWVycxIfCgttaW5fcGxheWVycxgCIAEoDVIKbWluUGxheWVycxIfCgttYXhfcGxheWVycxgDIAEoDVIKbWF4UGxheWVycxIlCg50aW1lX3JlbWFpbmluZxgEIAEoDVINdGltZVJlbWFpbmluZxpgCg1TdGF0dXNlc0VudHJ5EhAKA2tleRgBIAEoBFIDa2V5EjkKBXZhbHVlGAIgASgLMiMuZnVzaW9uLlRpZXJTdGF0dXNVcGRhdGUuVGllclN0YXR1c1IFdmFsdWU6AjgB'); +@$core.Deprecated('Use fusionBeginDescriptor instead') +const FusionBegin$json = const { + '1': 'FusionBegin', + '2': const [ + const {'1': 'tier', '3': 1, '4': 2, '5': 4, '10': 'tier'}, + const {'1': 'covert_domain', '3': 2, '4': 2, '5': 12, '10': 'covertDomain'}, + const {'1': 'covert_port', '3': 3, '4': 2, '5': 13, '10': 'covertPort'}, + const {'1': 'covert_ssl', '3': 4, '4': 1, '5': 8, '10': 'covertSsl'}, + const {'1': 'server_time', '3': 5, '4': 2, '5': 6, '10': 'serverTime'}, + ], +}; + +/// Descriptor for `FusionBegin`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fusionBeginDescriptor = $convert.base64Decode('CgtGdXNpb25CZWdpbhISCgR0aWVyGAEgAigEUgR0aWVyEiMKDWNvdmVydF9kb21haW4YAiACKAxSDGNvdmVydERvbWFpbhIfCgtjb3ZlcnRfcG9ydBgDIAIoDVIKY292ZXJ0UG9ydBIdCgpjb3ZlcnRfc3NsGAQgASgIUgljb3ZlcnRTc2wSHwoLc2VydmVyX3RpbWUYBSACKAZSCnNlcnZlclRpbWU='); +@$core.Deprecated('Use startRoundDescriptor instead') +const StartRound$json = const { + '1': 'StartRound', + '2': const [ + const {'1': 'round_pubkey', '3': 1, '4': 2, '5': 12, '10': 'roundPubkey'}, + const {'1': 'blind_nonce_points', '3': 2, '4': 3, '5': 12, '10': 'blindNoncePoints'}, + const {'1': 'server_time', '3': 5, '4': 2, '5': 6, '10': 'serverTime'}, + ], +}; + +/// Descriptor for `StartRound`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List startRoundDescriptor = $convert.base64Decode('CgpTdGFydFJvdW5kEiEKDHJvdW5kX3B1YmtleRgBIAIoDFILcm91bmRQdWJrZXkSLAoSYmxpbmRfbm9uY2VfcG9pbnRzGAIgAygMUhBibGluZE5vbmNlUG9pbnRzEh8KC3NlcnZlcl90aW1lGAUgAigGUgpzZXJ2ZXJUaW1l'); +@$core.Deprecated('Use playerCommitDescriptor instead') +const PlayerCommit$json = const { + '1': 'PlayerCommit', + '2': const [ + const {'1': 'initial_commitments', '3': 1, '4': 3, '5': 12, '10': 'initialCommitments'}, + const {'1': 'excess_fee', '3': 2, '4': 2, '5': 4, '10': 'excessFee'}, + const {'1': 'pedersen_total_nonce', '3': 3, '4': 2, '5': 12, '10': 'pedersenTotalNonce'}, + const {'1': 'random_number_commitment', '3': 4, '4': 2, '5': 12, '10': 'randomNumberCommitment'}, + const {'1': 'blind_sig_requests', '3': 5, '4': 3, '5': 12, '10': 'blindSigRequests'}, + ], +}; + +/// Descriptor for `PlayerCommit`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List playerCommitDescriptor = $convert.base64Decode('CgxQbGF5ZXJDb21taXQSLwoTaW5pdGlhbF9jb21taXRtZW50cxgBIAMoDFISaW5pdGlhbENvbW1pdG1lbnRzEh0KCmV4Y2Vzc19mZWUYAiACKARSCWV4Y2Vzc0ZlZRIwChRwZWRlcnNlbl90b3RhbF9ub25jZRgDIAIoDFIScGVkZXJzZW5Ub3RhbE5vbmNlEjgKGHJhbmRvbV9udW1iZXJfY29tbWl0bWVudBgEIAIoDFIWcmFuZG9tTnVtYmVyQ29tbWl0bWVudBIsChJibGluZF9zaWdfcmVxdWVzdHMYBSADKAxSEGJsaW5kU2lnUmVxdWVzdHM='); +@$core.Deprecated('Use blindSigResponsesDescriptor instead') +const BlindSigResponses$json = const { + '1': 'BlindSigResponses', + '2': const [ + const {'1': 'scalars', '3': 1, '4': 3, '5': 12, '10': 'scalars'}, + ], +}; + +/// Descriptor for `BlindSigResponses`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List blindSigResponsesDescriptor = $convert.base64Decode('ChFCbGluZFNpZ1Jlc3BvbnNlcxIYCgdzY2FsYXJzGAEgAygMUgdzY2FsYXJz'); +@$core.Deprecated('Use allCommitmentsDescriptor instead') +const AllCommitments$json = const { + '1': 'AllCommitments', + '2': const [ + const {'1': 'initial_commitments', '3': 1, '4': 3, '5': 12, '10': 'initialCommitments'}, + ], +}; + +/// Descriptor for `AllCommitments`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List allCommitmentsDescriptor = $convert.base64Decode('Cg5BbGxDb21taXRtZW50cxIvChNpbml0aWFsX2NvbW1pdG1lbnRzGAEgAygMUhJpbml0aWFsQ29tbWl0bWVudHM='); +@$core.Deprecated('Use covertComponentDescriptor instead') +const CovertComponent$json = const { + '1': 'CovertComponent', + '2': const [ + const {'1': 'round_pubkey', '3': 1, '4': 1, '5': 12, '10': 'roundPubkey'}, + const {'1': 'signature', '3': 2, '4': 2, '5': 12, '10': 'signature'}, + const {'1': 'component', '3': 3, '4': 2, '5': 12, '10': 'component'}, + ], +}; + +/// Descriptor for `CovertComponent`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List covertComponentDescriptor = $convert.base64Decode('Cg9Db3ZlcnRDb21wb25lbnQSIQoMcm91bmRfcHVia2V5GAEgASgMUgtyb3VuZFB1YmtleRIcCglzaWduYXR1cmUYAiACKAxSCXNpZ25hdHVyZRIcCgljb21wb25lbnQYAyACKAxSCWNvbXBvbmVudA=='); +@$core.Deprecated('Use shareCovertComponentsDescriptor instead') +const ShareCovertComponents$json = const { + '1': 'ShareCovertComponents', + '2': const [ + const {'1': 'components', '3': 4, '4': 3, '5': 12, '10': 'components'}, + const {'1': 'skip_signatures', '3': 5, '4': 1, '5': 8, '10': 'skipSignatures'}, + const {'1': 'session_hash', '3': 6, '4': 1, '5': 12, '10': 'sessionHash'}, + ], +}; + +/// Descriptor for `ShareCovertComponents`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List shareCovertComponentsDescriptor = $convert.base64Decode('ChVTaGFyZUNvdmVydENvbXBvbmVudHMSHgoKY29tcG9uZW50cxgEIAMoDFIKY29tcG9uZW50cxInCg9za2lwX3NpZ25hdHVyZXMYBSABKAhSDnNraXBTaWduYXR1cmVzEiEKDHNlc3Npb25faGFzaBgGIAEoDFILc2Vzc2lvbkhhc2g='); +@$core.Deprecated('Use covertTransactionSignatureDescriptor instead') +const CovertTransactionSignature$json = const { + '1': 'CovertTransactionSignature', + '2': const [ + const {'1': 'round_pubkey', '3': 1, '4': 1, '5': 12, '10': 'roundPubkey'}, + const {'1': 'which_input', '3': 2, '4': 2, '5': 13, '10': 'whichInput'}, + const {'1': 'txsignature', '3': 3, '4': 2, '5': 12, '10': 'txsignature'}, + ], +}; + +/// Descriptor for `CovertTransactionSignature`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List covertTransactionSignatureDescriptor = $convert.base64Decode('ChpDb3ZlcnRUcmFuc2FjdGlvblNpZ25hdHVyZRIhCgxyb3VuZF9wdWJrZXkYASABKAxSC3JvdW5kUHVia2V5Eh8KC3doaWNoX2lucHV0GAIgAigNUgp3aGljaElucHV0EiAKC3R4c2lnbmF0dXJlGAMgAigMUgt0eHNpZ25hdHVyZQ=='); +@$core.Deprecated('Use fusionResultDescriptor instead') +const FusionResult$json = const { + '1': 'FusionResult', + '2': const [ + const {'1': 'ok', '3': 1, '4': 2, '5': 8, '10': 'ok'}, + const {'1': 'txsignatures', '3': 2, '4': 3, '5': 12, '10': 'txsignatures'}, + const {'1': 'bad_components', '3': 3, '4': 3, '5': 13, '10': 'badComponents'}, + ], +}; + +/// Descriptor for `FusionResult`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List fusionResultDescriptor = $convert.base64Decode('CgxGdXNpb25SZXN1bHQSDgoCb2sYASACKAhSAm9rEiIKDHR4c2lnbmF0dXJlcxgCIAMoDFIMdHhzaWduYXR1cmVzEiUKDmJhZF9jb21wb25lbnRzGAMgAygNUg1iYWRDb21wb25lbnRz'); +@$core.Deprecated('Use myProofsListDescriptor instead') +const MyProofsList$json = const { + '1': 'MyProofsList', + '2': const [ + const {'1': 'encrypted_proofs', '3': 1, '4': 3, '5': 12, '10': 'encryptedProofs'}, + const {'1': 'random_number', '3': 2, '4': 2, '5': 12, '10': 'randomNumber'}, + ], +}; + +/// Descriptor for `MyProofsList`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List myProofsListDescriptor = $convert.base64Decode('CgxNeVByb29mc0xpc3QSKQoQZW5jcnlwdGVkX3Byb29mcxgBIAMoDFIPZW5jcnlwdGVkUHJvb2ZzEiMKDXJhbmRvbV9udW1iZXIYAiACKAxSDHJhbmRvbU51bWJlcg=='); +@$core.Deprecated('Use theirProofsListDescriptor instead') +const TheirProofsList$json = const { + '1': 'TheirProofsList', + '2': const [ + const {'1': 'proofs', '3': 1, '4': 3, '5': 11, '6': '.fusion.TheirProofsList.RelayedProof', '10': 'proofs'}, + ], + '3': const [TheirProofsList_RelayedProof$json], +}; + +@$core.Deprecated('Use theirProofsListDescriptor instead') +const TheirProofsList_RelayedProof$json = const { + '1': 'RelayedProof', + '2': const [ + const {'1': 'encrypted_proof', '3': 1, '4': 2, '5': 12, '10': 'encryptedProof'}, + const {'1': 'src_commitment_idx', '3': 2, '4': 2, '5': 13, '10': 'srcCommitmentIdx'}, + const {'1': 'dst_key_idx', '3': 3, '4': 2, '5': 13, '10': 'dstKeyIdx'}, + ], +}; + +/// Descriptor for `TheirProofsList`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List theirProofsListDescriptor = $convert.base64Decode('Cg9UaGVpclByb29mc0xpc3QSPAoGcHJvb2ZzGAEgAygLMiQuZnVzaW9uLlRoZWlyUHJvb2ZzTGlzdC5SZWxheWVkUHJvb2ZSBnByb29mcxqFAQoMUmVsYXllZFByb29mEicKD2VuY3J5cHRlZF9wcm9vZhgBIAIoDFIOZW5jcnlwdGVkUHJvb2YSLAoSc3JjX2NvbW1pdG1lbnRfaWR4GAIgAigNUhBzcmNDb21taXRtZW50SWR4Eh4KC2RzdF9rZXlfaWR4GAMgAigNUglkc3RLZXlJZHg='); +@$core.Deprecated('Use blamesDescriptor instead') +const Blames$json = const { + '1': 'Blames', + '2': const [ + const {'1': 'blames', '3': 1, '4': 3, '5': 11, '6': '.fusion.Blames.BlameProof', '10': 'blames'}, + ], + '3': const [Blames_BlameProof$json], +}; + +@$core.Deprecated('Use blamesDescriptor instead') +const Blames_BlameProof$json = const { + '1': 'BlameProof', + '2': const [ + const {'1': 'which_proof', '3': 1, '4': 2, '5': 13, '10': 'whichProof'}, + const {'1': 'session_key', '3': 2, '4': 1, '5': 12, '9': 0, '10': 'sessionKey'}, + const {'1': 'privkey', '3': 3, '4': 1, '5': 12, '9': 0, '10': 'privkey'}, + const {'1': 'need_lookup_blockchain', '3': 4, '4': 1, '5': 8, '10': 'needLookupBlockchain'}, + const {'1': 'blame_reason', '3': 5, '4': 1, '5': 9, '10': 'blameReason'}, + ], + '8': const [ + const {'1': 'decrypter'}, + ], +}; + +/// Descriptor for `Blames`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List blamesDescriptor = $convert.base64Decode('CgZCbGFtZXMSMQoGYmxhbWVzGAEgAygLMhkuZnVzaW9uLkJsYW1lcy5CbGFtZVByb29mUgZibGFtZXMa0gEKCkJsYW1lUHJvb2YSHwoLd2hpY2hfcHJvb2YYASACKA1SCndoaWNoUHJvb2YSIQoLc2Vzc2lvbl9rZXkYAiABKAxIAFIKc2Vzc2lvbktleRIaCgdwcml2a2V5GAMgASgMSABSB3ByaXZrZXkSNAoWbmVlZF9sb29rdXBfYmxvY2tjaGFpbhgEIAEoCFIUbmVlZExvb2t1cEJsb2NrY2hhaW4SIQoMYmxhbWVfcmVhc29uGAUgASgJUgtibGFtZVJlYXNvbkILCglkZWNyeXB0ZXI='); +@$core.Deprecated('Use restartRoundDescriptor instead') +const RestartRound$json = const { + '1': 'RestartRound', +}; + +/// Descriptor for `RestartRound`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List restartRoundDescriptor = $convert.base64Decode('CgxSZXN0YXJ0Um91bmQ='); +@$core.Deprecated('Use errorDescriptor instead') +const Error$json = const { + '1': 'Error', + '2': const [ + const {'1': 'message', '3': 1, '4': 1, '5': 9, '10': 'message'}, + ], +}; + +/// Descriptor for `Error`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List errorDescriptor = $convert.base64Decode('CgVFcnJvchIYCgdtZXNzYWdlGAEgASgJUgdtZXNzYWdl'); +@$core.Deprecated('Use pingDescriptor instead') +const Ping$json = const { + '1': 'Ping', +}; + +/// Descriptor for `Ping`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List pingDescriptor = $convert.base64Decode('CgRQaW5n'); +@$core.Deprecated('Use oKDescriptor instead') +const OK$json = const { + '1': 'OK', +}; + +/// Descriptor for `OK`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List oKDescriptor = $convert.base64Decode('CgJPSw=='); +@$core.Deprecated('Use clientMessageDescriptor instead') +const ClientMessage$json = const { + '1': 'ClientMessage', + '2': const [ + const {'1': 'clienthello', '3': 1, '4': 1, '5': 11, '6': '.fusion.ClientHello', '9': 0, '10': 'clienthello'}, + const {'1': 'joinpools', '3': 2, '4': 1, '5': 11, '6': '.fusion.JoinPools', '9': 0, '10': 'joinpools'}, + const {'1': 'playercommit', '3': 3, '4': 1, '5': 11, '6': '.fusion.PlayerCommit', '9': 0, '10': 'playercommit'}, + const {'1': 'myproofslist', '3': 5, '4': 1, '5': 11, '6': '.fusion.MyProofsList', '9': 0, '10': 'myproofslist'}, + const {'1': 'blames', '3': 6, '4': 1, '5': 11, '6': '.fusion.Blames', '9': 0, '10': 'blames'}, + ], + '8': const [ + const {'1': 'msg'}, + ], +}; + +/// Descriptor for `ClientMessage`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List clientMessageDescriptor = $convert.base64Decode('Cg1DbGllbnRNZXNzYWdlEjcKC2NsaWVudGhlbGxvGAEgASgLMhMuZnVzaW9uLkNsaWVudEhlbGxvSABSC2NsaWVudGhlbGxvEjEKCWpvaW5wb29scxgCIAEoCzIRLmZ1c2lvbi5Kb2luUG9vbHNIAFIJam9pbnBvb2xzEjoKDHBsYXllcmNvbW1pdBgDIAEoCzIULmZ1c2lvbi5QbGF5ZXJDb21taXRIAFIMcGxheWVyY29tbWl0EjoKDG15cHJvb2ZzbGlzdBgFIAEoCzIULmZ1c2lvbi5NeVByb29mc0xpc3RIAFIMbXlwcm9vZnNsaXN0EigKBmJsYW1lcxgGIAEoCzIOLmZ1c2lvbi5CbGFtZXNIAFIGYmxhbWVzQgUKA21zZw=='); +@$core.Deprecated('Use serverMessageDescriptor instead') +const ServerMessage$json = const { + '1': 'ServerMessage', + '2': const [ + const {'1': 'serverhello', '3': 1, '4': 1, '5': 11, '6': '.fusion.ServerHello', '9': 0, '10': 'serverhello'}, + const {'1': 'tierstatusupdate', '3': 2, '4': 1, '5': 11, '6': '.fusion.TierStatusUpdate', '9': 0, '10': 'tierstatusupdate'}, + const {'1': 'fusionbegin', '3': 3, '4': 1, '5': 11, '6': '.fusion.FusionBegin', '9': 0, '10': 'fusionbegin'}, + const {'1': 'startround', '3': 4, '4': 1, '5': 11, '6': '.fusion.StartRound', '9': 0, '10': 'startround'}, + const {'1': 'blindsigresponses', '3': 5, '4': 1, '5': 11, '6': '.fusion.BlindSigResponses', '9': 0, '10': 'blindsigresponses'}, + const {'1': 'allcommitments', '3': 6, '4': 1, '5': 11, '6': '.fusion.AllCommitments', '9': 0, '10': 'allcommitments'}, + const {'1': 'sharecovertcomponents', '3': 7, '4': 1, '5': 11, '6': '.fusion.ShareCovertComponents', '9': 0, '10': 'sharecovertcomponents'}, + const {'1': 'fusionresult', '3': 8, '4': 1, '5': 11, '6': '.fusion.FusionResult', '9': 0, '10': 'fusionresult'}, + const {'1': 'theirproofslist', '3': 9, '4': 1, '5': 11, '6': '.fusion.TheirProofsList', '9': 0, '10': 'theirproofslist'}, + const {'1': 'restartround', '3': 14, '4': 1, '5': 11, '6': '.fusion.RestartRound', '9': 0, '10': 'restartround'}, + const {'1': 'error', '3': 15, '4': 1, '5': 11, '6': '.fusion.Error', '9': 0, '10': 'error'}, + ], + '8': const [ + const {'1': 'msg'}, + ], +}; + +/// Descriptor for `ServerMessage`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List serverMessageDescriptor = $convert.base64Decode('Cg1TZXJ2ZXJNZXNzYWdlEjcKC3NlcnZlcmhlbGxvGAEgASgLMhMuZnVzaW9uLlNlcnZlckhlbGxvSABSC3NlcnZlcmhlbGxvEkYKEHRpZXJzdGF0dXN1cGRhdGUYAiABKAsyGC5mdXNpb24uVGllclN0YXR1c1VwZGF0ZUgAUhB0aWVyc3RhdHVzdXBkYXRlEjcKC2Z1c2lvbmJlZ2luGAMgASgLMhMuZnVzaW9uLkZ1c2lvbkJlZ2luSABSC2Z1c2lvbmJlZ2luEjQKCnN0YXJ0cm91bmQYBCABKAsyEi5mdXNpb24uU3RhcnRSb3VuZEgAUgpzdGFydHJvdW5kEkkKEWJsaW5kc2lncmVzcG9uc2VzGAUgASgLMhkuZnVzaW9uLkJsaW5kU2lnUmVzcG9uc2VzSABSEWJsaW5kc2lncmVzcG9uc2VzEkAKDmFsbGNvbW1pdG1lbnRzGAYgASgLMhYuZnVzaW9uLkFsbENvbW1pdG1lbnRzSABSDmFsbGNvbW1pdG1lbnRzElUKFXNoYXJlY292ZXJ0Y29tcG9uZW50cxgHIAEoCzIdLmZ1c2lvbi5TaGFyZUNvdmVydENvbXBvbmVudHNIAFIVc2hhcmVjb3ZlcnRjb21wb25lbnRzEjoKDGZ1c2lvbnJlc3VsdBgIIAEoCzIULmZ1c2lvbi5GdXNpb25SZXN1bHRIAFIMZnVzaW9ucmVzdWx0EkMKD3RoZWlycHJvb2ZzbGlzdBgJIAEoCzIXLmZ1c2lvbi5UaGVpclByb29mc0xpc3RIAFIPdGhlaXJwcm9vZnNsaXN0EjoKDHJlc3RhcnRyb3VuZBgOIAEoCzIULmZ1c2lvbi5SZXN0YXJ0Um91bmRIAFIMcmVzdGFydHJvdW5kEiUKBWVycm9yGA8gASgLMg0uZnVzaW9uLkVycm9ySABSBWVycm9yQgUKA21zZw=='); +@$core.Deprecated('Use covertMessageDescriptor instead') +const CovertMessage$json = const { + '1': 'CovertMessage', + '2': const [ + const {'1': 'component', '3': 1, '4': 1, '5': 11, '6': '.fusion.CovertComponent', '9': 0, '10': 'component'}, + const {'1': 'signature', '3': 2, '4': 1, '5': 11, '6': '.fusion.CovertTransactionSignature', '9': 0, '10': 'signature'}, + const {'1': 'ping', '3': 3, '4': 1, '5': 11, '6': '.fusion.Ping', '9': 0, '10': 'ping'}, + ], + '8': const [ + const {'1': 'msg'}, + ], +}; + +/// Descriptor for `CovertMessage`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List covertMessageDescriptor = $convert.base64Decode('Cg1Db3ZlcnRNZXNzYWdlEjcKCWNvbXBvbmVudBgBIAEoCzIXLmZ1c2lvbi5Db3ZlcnRDb21wb25lbnRIAFIJY29tcG9uZW50EkIKCXNpZ25hdHVyZRgCIAEoCzIiLmZ1c2lvbi5Db3ZlcnRUcmFuc2FjdGlvblNpZ25hdHVyZUgAUglzaWduYXR1cmUSIgoEcGluZxgDIAEoCzIMLmZ1c2lvbi5QaW5nSABSBHBpbmdCBQoDbXNn'); +@$core.Deprecated('Use covertResponseDescriptor instead') +const CovertResponse$json = const { + '1': 'CovertResponse', + '2': const [ + const {'1': 'ok', '3': 1, '4': 1, '5': 11, '6': '.fusion.OK', '9': 0, '10': 'ok'}, + const {'1': 'error', '3': 15, '4': 1, '5': 11, '6': '.fusion.Error', '9': 0, '10': 'error'}, + ], + '8': const [ + const {'1': 'msg'}, + ], +}; + +/// Descriptor for `CovertResponse`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List covertResponseDescriptor = $convert.base64Decode('Cg5Db3ZlcnRSZXNwb25zZRIcCgJvaxgBIAEoCzIKLmZ1c2lvbi5PS0gAUgJvaxIlCgVlcnJvchgPIAEoCzINLmZ1c2lvbi5FcnJvckgAUgVlcnJvckIFCgNtc2c='); diff --git a/lib/services/cashfusion/protobuf/fusion.proto b/lib/services/cashfusion/protobuf/fusion.proto new file mode 100644 index 000000000..f2273f78f --- /dev/null +++ b/lib/services/cashfusion/protobuf/fusion.proto @@ -0,0 +1,281 @@ +/* + * Electron Cash - a lightweight Bitcoin Cash client + * CashFusion - an advanced coin anonymizer + * + * Copyright (C) 2020 Mark B. Lundeberg + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +syntax = "proto2"; + +package fusion; + +// Some primitives + +message InputComponent { + required bytes prev_txid = 1; // in 'reverse' order, just like in tx + required uint32 prev_index = 2; + required bytes pubkey = 3; + required uint64 amount = 4; + } + +message OutputComponent { + required bytes scriptpubkey = 1; + required uint64 amount = 2; + } + +message BlankComponent { + } + +message Component { + required bytes salt_commitment = 1; // 32 bytes + oneof component { + InputComponent input = 2; + OutputComponent output = 3; + BlankComponent blank = 4; + } + } + +message InitialCommitment { + required bytes salted_component_hash = 1; // 32 byte hash + required bytes amount_commitment = 2; // uncompressed point + required bytes communication_key = 3; // compressed point + } + +message Proof { + // During blame phase, messages of this form are encrypted and sent + // to a different player. It is already known which commitment this + // should apply to, so we only need to point at the component. + required fixed32 component_idx = 1; + required bytes salt = 2; // 32 bytes + required bytes pedersen_nonce = 3; // 32 bytes +} + + + +// Primary communication message types (and flow) + +// Setup phase + +message ClientHello { // from client + required bytes version = 1; + optional bytes genesis_hash = 2; // 32 byte hash (bitcoind little-endian memory order) +} + +message ServerHello { // from server + repeated uint64 tiers = 1; + required uint32 num_components = 2; + required uint64 component_feerate = 4; // sats/kB + required uint64 min_excess_fee = 5; // sats + required uint64 max_excess_fee = 6; // sats + + optional string donation_address = 15; // BCH Address "bitcoincash:qpx..." +} + +message JoinPools { // from client + message PoolTag { + // These tags can be used to client to stop the server from including + // the client too many times in the same fusion. Thus, the client can + // connect many times without fear of fusing with themselves. + required bytes id = 1; // allowed up to 20 bytes + required uint32 limit = 2; // between 1 and 5 inclusive + optional bool no_ip = 3; // whether to do an IP-less tag -- this will collide with all other users, make sure it's random so you can't get DoSed. + } + repeated uint64 tiers = 1; + repeated PoolTag tags = 2; // at most five tags. +} + +message TierStatusUpdate { // from server + message TierStatus { + // in future, we will want server to indicate 'remaining time' and mask number of players. + // note: if player is in queue then a status will be ommitted. + optional uint32 players = 1; + optional uint32 min_players = 2; // minimum required to start (may have delay to allow extra) + optional uint32 max_players = 3; // maximum allowed (immediate start) + optional uint32 time_remaining = 4; + } + map<uint64, TierStatus> statuses = 1; +} + +message FusionBegin { // from server + required uint64 tier = 1; + required bytes covert_domain = 2; + required uint32 covert_port = 3; + optional bool covert_ssl = 4; + required fixed64 server_time = 5; // server unix time when sending this message; can't be too far off from recipient's clock. +} + + +// Fusion round (repeatable multiple times per connection) + +message StartRound { // from server + required bytes round_pubkey = 1; + repeated bytes blind_nonce_points = 2; + required fixed64 server_time = 5; // server unix time when sending this message; can't be too far off from recipient's clock. + } + +// Phase 3 +message PlayerCommit { // from client + repeated bytes initial_commitments = 1; // serialized InitialCommitment messages; server will repeat them later, verbatim. + required uint64 excess_fee = 2; + required bytes pedersen_total_nonce = 3; // 32 bytes + required bytes random_number_commitment = 4; // 32 bytes + repeated bytes blind_sig_requests = 5; // 32 byte scalars + } + +// Phase 4 +message BlindSigResponses { // from server + repeated bytes scalars = 1; // 32 byte scalars +} + +message AllCommitments { + // All the commitments from all players. At ~140 bytes per commitment and hundreds of commitments, this can be quite large, so it gets sent in its own message during the covert phase. + repeated bytes initial_commitments = 1; + } + +//Phase 5 +message CovertComponent { // from covert client + // The round key is used to identify the pool if needed + optional bytes round_pubkey = 1; + required bytes signature = 2; + required bytes component = 3; // bytes so that it can be signed and hashed verbatim + } + +//Phase 6 +message ShareCovertComponents { // from server + // This is a large message! 168 bytes per initial commitment, ~112 bytes per input component. + // Can easily reach 100 kB or more. + repeated bytes components = 4; + optional bool skip_signatures = 5; // if the server already sees a problem in submitted components + optional bytes session_hash = 6; // the server's calculation of session hash, so clients can crosscheck. +} + +// Phase 7A +message CovertTransactionSignature { // from covert client + // The round key is used to identify the pool if needed + optional bytes round_pubkey = 1; + required uint32 which_input = 2; + required bytes txsignature = 3; + } + +// Phase 8 +message FusionResult { // from server + required bool ok = 1; + repeated bytes txsignatures = 2; // if ok + repeated uint32 bad_components = 3; // if not ok + } + +// Phase 9 +message MyProofsList { // from client + repeated bytes encrypted_proofs = 1; + required bytes random_number = 2; // the number we committed to, back in phase 3 + } + +message TheirProofsList { // from server + message RelayedProof { + required bytes encrypted_proof = 1; + required uint32 src_commitment_idx = 2; // which of the commitments is being proven (index in full list) + required uint32 dst_key_idx = 3; // which of the recipient's keys will unlock the encryption (index in player list) + } + repeated RelayedProof proofs = 1; + } + +// Phase 10 +message Blames { // from client + message BlameProof { + required uint32 which_proof = 1; + oneof decrypter { + bytes session_key = 2; // 32 byte, preferred if the proof decryption works at all + bytes privkey = 3; // 32 byte scalar + } + + // Some errors can only be discovered by checking the blockchain, + // Namely, if an input UTXO is missing/spent/unconfirmed/different + // scriptpubkey/different amount, than indicated. + optional bool need_lookup_blockchain = 4; + + // The client can indicate why it thinks the blame is deserved. In + // case the server finds no issue, this string might help for debugging. + optional string blame_reason = 5; + } + repeated BlameProof blames = 1; + } + +// Final message of the round +message RestartRound { +} + +// Fatal error from server, likely we did something wrong (it will disconnect us, but the message may help debugging). +message Error { + optional string message = 1; +} + +// Simple ping, as a keepalive. +message Ping { +} + +// Simple acknowledgement, nothing more to say. +message OK { +} + +// Primary communication channel types + +message ClientMessage { + oneof msg { + ClientHello clienthello = 1; + JoinPools joinpools = 2; + PlayerCommit playercommit = 3; + MyProofsList myproofslist = 5; + Blames blames = 6; + } + } + +message ServerMessage { + oneof msg { + ServerHello serverhello = 1; + TierStatusUpdate tierstatusupdate = 2; + FusionBegin fusionbegin = 3; + StartRound startround = 4; + BlindSigResponses blindsigresponses = 5; + AllCommitments allcommitments = 6; + ShareCovertComponents sharecovertcomponents = 7; + FusionResult fusionresult = 8; + TheirProofsList theirproofslist = 9; + + RestartRound restartround = 14; + Error error = 15; + } + } + +message CovertMessage { // client -> server, covertly + oneof msg { + CovertComponent component = 1; + CovertTransactionSignature signature = 2; + Ping ping = 3; + } + } + +message CovertResponse { // server -> a covert client + oneof msg { + OK ok = 1; + Error error = 15; + } +} diff --git a/lib/services/cashfusion/protocol.dart b/lib/services/cashfusion/protocol.dart new file mode 100644 index 000000000..fa72ce7a5 --- /dev/null +++ b/lib/services/cashfusion/protocol.dart @@ -0,0 +1,59 @@ + + +class Protocol { + static const VERSION = 'alpha13'; + + static const FUSE_ID = 'FUZ\x00'; + + +// Safety limits to prevent loss of funds / limit fees: + //(Note that if we enter multiply into the same fusion, our limits apply + //separately for each "player".) + // + //Deny server that asks for more than this component feerate (sat/kbyte). + static const MAX_COMPONENT_FEERATE = 5000; + //The largest 'excess fee' that we are willing to pay in a fusion (fees beyond + //those needed to pay for our components' inclusion) + static const MAX_EXCESS_FEE = 10000; + // Even if the server allows more, put at most this many inputs+outputs+blanks + static const MAX_COMPONENTS = 40; + // The largest total fee we are willing to pay (our contribution to transaction + // size should not exceed 7 kB even with 40 largest components). + static const MAX_FEE = MAX_COMPONENT_FEERATE * 7 + MAX_EXCESS_FEE; + // For privacy reasons, don't submit less than this many distinct tx components. + // (distinct tx inputs, and tx outputs) + static const MIN_TX_COMPONENTS = 11; + + static const MIN_OUTPUT = 10000; + + static const COVERT_CONNECT_TIMEOUT = 15.0; + static const COVERT_CONNECT_WINDOW = 15.0; + static const COVERT_SUBMIT_TIMEOUT = 3.0; + static const COVERT_SUBMIT_WINDOW = 5.0; + + static const COVERT_CONNECT_SPARES = 6; + + static const MAX_CLOCK_DISCREPANCY = 5.0; + + static const WARMUP_TIME = 30.0; + static const WARMUP_SLOP = 3.0; + + static const TS_EXPECTING_COMMITMENTS = 3.0; + + static const T_START_COMPS = 5.0; + + static const TS_EXPECTING_COVERT_COMPONENTS = 15.0; + + static const T_START_SIGS = 20.0; + + static const TS_EXPECTING_COVERT_SIGNATURES = 30.0; + + static const T_EXPECTING_CONCLUSION = 35.0; + + static const T_START_CLOSE = 45.0; + static const T_START_CLOSE_BLAME = 80.0; + + static const STANDARD_TIMEOUT = 3.0; + static const BLAME_VERIFY_TIME = 5.0; +} + diff --git a/lib/services/cashfusion/socketwrapper.dart b/lib/services/cashfusion/socketwrapper.dart new file mode 100644 index 000000000..54b8a105e --- /dev/null +++ b/lib/services/cashfusion/socketwrapper.dart @@ -0,0 +1,46 @@ +import 'dart:io'; + +class SocketWrapper { + late Socket _socket; + final String serverIP; + final int serverPort; + + late Stream<List<int>> _receiveStream; // create a field for the broadcast stream + + SocketWrapper(this.serverIP, this.serverPort); + Socket get socket => _socket; + + Stream<List<int>> get receiveStream => _receiveStream; // expose the stream with a getter + + Future<void> connect() async { + _socket = await Socket.connect(serverIP, serverPort); + _receiveStream = _socket.asBroadcastStream(); // initialize the broadcast stream + _socket.done.then((_) { + print('......Socket has been closed'); + }); + _socket.handleError((error) { + print('Socket error: $error'); + }); + } + + void status() { + if (_socket != null) { + print("Socket connected to ${_socket.remoteAddress.address}:${_socket.remotePort}"); + } else { + print("Socket is not connected"); + } + } + + Future<void> send(List<int> data) async { + if (_socket != null) { + _socket.add(data); + await _socket.flush(); + } else { + // handle error + } + } + + void close() { + _socket.close(); + } +} diff --git a/lib/services/cashfusion/util.dart b/lib/services/cashfusion/util.dart new file mode 100644 index 000000000..cb8e5f621 --- /dev/null +++ b/lib/services/cashfusion/util.dart @@ -0,0 +1,330 @@ + +import 'package:stackwallet/services/cashfusion/fusion.dart'; +import 'package:pointycastle/ecc/api.dart'; +import 'dart:math'; +import 'dart:typed_data'; +import 'dart:convert'; +import 'package:crypto/crypto.dart' as crypto; +import 'protocol.dart'; +import 'fusion.pb.dart'; +import 'dart:convert'; + +class Address { + String addr = ""; + + Address({required this.addr}); // Constructor updated to accept addr as a named parameter + + Address._create({required this.addr}); + + static Address fromScriptPubKey(List<int> scriptPubKey) { + // This is just a placeholder code + String addr = ""; // This should be computed from the scriptPubKey + return Address(addr: addr); + } + + // Public constructor for testing + static Address fromString(String address) { + return Address._create(addr: address); + } + + List<int> toScript() { + return []; + } +} + + +class Tuple<T1, T2> { + T1 item1; + T2 item2; + + Tuple(this.item1, this.item2); + + set setItem1(T1 value) { + this.item1 = value; + } + + set setItem2(T2 value) { + this.item2 = value; + } +} + +class Util { + + + static Uint8List hexToBytes(String hex) { + var result = new Uint8List(hex.length ~/ 2); + for (var i = 0; i < hex.length; i += 2) { + var byte = int.parse(hex.substring(i, i + 2), radix: 16); + result[i ~/ 2] = byte; + } + return result; + } + + static void checkInputElectrumX(InputComponent inputComponent) { + // Implementation needed here + // + } + + + static int randPosition(Uint8List seed, int numPositions, int counter) { + // counter to bytes + var counterBytes = Uint8List(4); + var counterByteData = ByteData.sublistView(counterBytes); + counterByteData.setInt32(0, counter, Endian.big); + + // hash the seed and counter + var digest = crypto.sha256.convert([...seed, ...counterBytes]); + + // take the first 8 bytes + var first8Bytes = digest.bytes.take(8).toList(); + var int64 = ByteData.sublistView(Uint8List.fromList(first8Bytes)).getUint64(0, Endian.big); + + // perform the modulo operation + return ((int64 * numPositions) >> 64).toInt(); + } + + static List<String> pubkeysFromPrivkey(String privkey) { + // This is a placeholder implementation. + return ['public_key1_dummy', 'public_key2_dummy']; + } + + static int dustLimit(int length) { + // This is a dummy implementation. + return 500; + } + + + static Address getAddressFromOutputScript(Uint8List scriptpubkey) { + // Dummy implementation... + + // Throw exception if this is not a standard P2PKH address! + + return Address.fromString('dummy_address'); + } + + + static bool schnorrVerify(ECPoint pubkey, List<int> signature, Uint8List messageHash) { + // Implementation needed: actual Schnorr signature verification + return true; + } + + + static String formatSatoshis(sats, {int numZeros=8}) { + // To implement + return ""; + } + static void updateWalletLabel(String txid, String label) { + + // Call the wallet layer. + } + + static Uint8List getRandomBytes(int length) { + final rand = Random.secure(); + final bytes = Uint8List(length); + for (int i = 0; i < length; i++) { + bytes[i] = rand.nextInt(256); + } + return bytes; + } + +static List<List<T>> zip<T>(List<T> list1, List<T> list2) { + int length = min(list1.length, list2.length); + return List<List<T>>.generate(length, (i) => [list1[i], list2[i]]); + } + + + static List<int> calcInitialHash(int tier, Uint8List covertDomainB, int covertPort, bool covertSsl, double beginTime) { + // Converting int to bytes in BigEndian order + var tierBytes = ByteData(8)..setInt64(0, tier, Endian.big); + var covertPortBytes = ByteData(4)..setInt32(0, covertPort, Endian.big); + var beginTimeBytes = ByteData(8)..setInt64(0, beginTime.toInt(), Endian.big); + + // Define constants + const version = Protocol.VERSION; + const cashFusionSession = "Cash Fusion Session"; + + // Creating the list of bytes + List<int> elements = []; + elements.addAll(utf8.encode(cashFusionSession)); + elements.addAll(utf8.encode(version)); + elements.addAll(tierBytes.buffer.asInt8List()); + elements.addAll(covertDomainB); + elements.addAll(covertPortBytes.buffer.asInt8List()); + elements.add(covertSsl ? 1 : 0); + elements.addAll(beginTimeBytes.buffer.asInt8List()); + + // Hashing the concatenated elements + var digest = crypto.sha256.convert(elements); + + return digest.bytes; + } + +static List<int> calcRoundHash(List<int> lastHash, List<int> roundPubkey, int roundTime, List<List<int>> allCommitments, List<List<int>> allComponents) { + return listHash([ + utf8.encode('Cash Fusion Round'), + lastHash, + roundPubkey, + bigIntToBytes(BigInt.from(roundTime)), + listHash(allCommitments), + listHash(allComponents), + ]); +} + + static List<int> listHash(Iterable<List<int>> iterable) { + var bytes = <int>[]; + + for (var x in iterable) { + var length = ByteData(4)..setUint32(0, x.length, Endian.big); + bytes.addAll(length.buffer.asUint8List()); + bytes.addAll(x); + } + return crypto.sha256.convert(bytes).bytes; + + } + + + static Uint8List get_current_genesis_hash() { + var GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"; + var _lastGenesisHash = hexToBytes(GENESIS).reversed.toList(); + return Uint8List.fromList(_lastGenesisHash); + } + + static List<Address> unreserve_change_address(Address addr) { + //implement later based on wallet. + return []; + } + + + static List<Address> reserve_change_addresses(int number_addresses) { + //implement later based on wallet. + return []; + } + + static bool walletHasTransaction(String txid) { + // implement later based on wallet. + return true; + } + +static Uint8List bigIntToBytes(BigInt bigInt) { + return Uint8List.fromList(bigInt.toRadixString(16).padLeft(32, '0').codeUnits); + } + +static Tuple<Uint8List, Uint8List> genKeypair() { + var params = ECDomainParameters('secp256k1'); + var privKeyBigInt = _generatePrivateKey(params.n.bitLength); + var pubKeyPoint = params.G * privKeyBigInt; + + if (pubKeyPoint == null) { + throw Exception("Error generating public key."); + } + + Uint8List privKey = bigIntToBytes(privKeyBigInt); + Uint8List pubKey = pubKeyPoint.getEncoded(true); + + return Tuple(privKey, pubKey); +} + + + +// Generates a cryptographically secure private key + static BigInt _generatePrivateKey(int bitLength) { + final random = Random.secure(); + var bytes = bitLength ~/ 8; // floor division + var remBit = bitLength % 8; + + // Generate random BigInt + List<int> rnd = List<int>.generate(bytes, (_) => random.nextInt(256)); + var rndBit = random.nextInt(1 << remBit); + rnd.add(rndBit); + var privateKey = BigInt.parse(rnd.map((x) => x.toRadixString(16).padLeft(2, '0')).join(), radix: 16); + + return privateKey; + } + + // Additional helper function to convert bytes to hex + static String bytesToHex(Uint8List bytes) { + return bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join(); + } + + static BigInt bytesToBigInt(Uint8List bytes) { + String hexString = bytesToHex(bytes); + return BigInt.parse(hexString, radix: 16); + } + + + static Uint8List sha256(Uint8List bytes) { + crypto.Digest digest = crypto.sha256.convert(bytes); + return Uint8List.fromList(digest.bytes); + } + static Uint8List tokenBytes([int nbytes = 32]) { + final Random _random = Random.secure(); + + return Uint8List.fromList(List<int>.generate(nbytes, (i) => _random.nextInt(256))); + } + + static int componentFee(int size, int feerate) { + // feerate in sat/kB + // size and feerate should both be integer + // fee is always rounded up + return ((size * feerate) + 999) ~/ 1000; + } + + + static ECPoint ser_to_point(Uint8List serializedPoint, ECDomainParameters params) { + var point = params.curve.decodePoint(serializedPoint); + if (point == null) { + throw FormatException('Point decoding failed'); + } + return point; + } + + static Uint8List point_to_ser(ECPoint point, bool compress) { + return point.getEncoded(compress); + } + + + static BigInt secureRandomBigInt(int bitLength) { + final random = Random.secure(); + final bytes = (bitLength + 7) ~/ 8; // ceil division + final Uint8List randomBytes = Uint8List(bytes); + + for (int i = 0; i < bytes; i++) { + randomBytes[i] = random.nextInt(256); + } + + BigInt randomNumber = BigInt.parse(randomBytes.map((e) => e.toRadixString(16).padLeft(2, '0')).join(), radix: 16); + return randomNumber; + } + static ECPoint combinePubKeys(List<ECPoint> pubKeys) { + if (pubKeys.isEmpty) throw ArgumentError('pubKeys cannot be empty'); + + ECPoint combined = pubKeys.first.curve.infinity!; + for (var pubKey in pubKeys) { + combined = (combined + pubKey)!; + } + + if (combined.isInfinity) { + throw Exception('Combined point is at infinity'); + } + + return combined; + } + + static bool isPointOnCurve(ECPoint point, ECCurve curve) { + var x = point.x!.toBigInteger()!; + var y = point.y!.toBigInteger()!; + var a = curve.a!.toBigInteger()!; + var b = curve.b!.toBigInteger()!; + + // Calculate the left and right sides of the equation + var left = y * y; + var right = (x * x * x) + (a * x) + b; + + // Check if the point is on the curve + return left == right; + } + + + +} // END OF CLASS + diff --git a/lib/services/cashfusion/validation.dart b/lib/services/cashfusion/validation.dart new file mode 100644 index 000000000..24555f7d8 --- /dev/null +++ b/lib/services/cashfusion/validation.dart @@ -0,0 +1,293 @@ +import 'package:protobuf/protobuf.dart'; +import 'fusion.pb.dart' as pb; +import 'pedersen.dart'; +import 'util.dart'; +import 'encrypt.dart' as Encrypt; +import 'protocol.dart'; +import 'fusion.dart'; +import 'dart:typed_data'; +import 'package:pointycastle/export.dart'; +import 'package:convert/convert.dart'; +import 'pedersen.dart'; + +class ValidationError implements Exception { + final String message; + ValidationError(this.message); + @override + String toString() => 'Validation error: $message'; +} + +int componentContrib(pb.Component component, int feerate) { + if (component.hasInput()) { + var inp = Input.fromInputComponent(component.input); + return inp.amount.toInt() - Util.componentFee(inp.sizeOfInput(), feerate); + } else if (component.hasOutput()) { + var out = Output.fromOutputComponent(component.output); + return -out.amount.toInt() - Util.componentFee(out.sizeOfOutput(), feerate); + } else if (component.hasBlank()) { + return 0; + } else { + throw ValidationError('Invalid component type'); + } +} + + + +void check(bool condition, String failMessage) { + if (!condition) { + throw ValidationError(failMessage); + } +} +dynamic protoStrictParse(dynamic msg, List<int> blob) { + try { + if (msg.mergeFromBuffer(blob) != blob.length) { + throw ArgumentError('DecodeError'); + } + } catch (e) { + throw ArgumentError('ValidationError: decode error'); + } + + if (!msg.isInitialized()) { + throw ArgumentError('missing fields'); + } + + // Protobuf in dart does not support 'unknownFields' method + // if (!msg.unknownFields.isEmpty) { + // throw ArgumentError('has extra fields'); + // } + + if (msg.writeToBuffer().length != blob.length) { + throw ArgumentError('encoding too long'); + } + + return msg; +} + + +List<pb.InitialCommitment> checkPlayerCommit( + pb.PlayerCommit msg, + int minExcessFee, + int maxExcessFee, + int numComponents + ) { + check(msg.initialCommitments.length == numComponents, "wrong number of component commitments"); + check(msg.blindSigRequests.length == numComponents, "wrong number of blind sig requests"); + + check(minExcessFee <= msg.excessFee.toInt() && msg.excessFee.toInt() <= maxExcessFee, "bad excess fee"); + + check(msg.randomNumberCommitment.length == 32, "bad random commit"); + check(msg.pedersenTotalNonce.length == 32, "bad nonce"); + check(msg.blindSigRequests.every((r) => r.length == 32), "bad blind sig request"); + + List<pb.InitialCommitment> commitMessages = []; + for (var cblob in msg.initialCommitments) { + pb.InitialCommitment cmsg = protoStrictParse(pb.InitialCommitment(), cblob); + check(cmsg.saltedComponentHash.length == 32, "bad salted hash"); + var P = cmsg.amountCommitment; + check(P.length == 65 && P[0] == 4, "bad commitment point"); + check(cmsg.communicationKey.length == 33 && (cmsg.communicationKey[0] == 2 || cmsg.communicationKey[0] == 3), "bad communication key"); + commitMessages.add(cmsg); + } + + Uint8List HBytes = Uint8List.fromList([0x02] + 'CashFusion gives us fungibility.'.codeUnits); + ECDomainParameters params = ECDomainParameters('secp256k1'); + ECPoint? HMaybe = params.curve.decodePoint(HBytes); + if (HMaybe == null) { + throw Exception('Failed to decode point'); + } + ECPoint H = HMaybe; + PedersenSetup setup = PedersenSetup(H); + + var claimedCommit; + var pointsum; + // Verify pedersen commitment + try { + pointsum = Commitment.add_points(commitMessages.map((m) => Uint8List.fromList(m.amountCommitment)).toList()); + claimedCommit = setup.commit(BigInt.from(msg.excessFee.toInt()), nonce: Util.bytesToBigInt(Uint8List.fromList(msg.pedersenTotalNonce))); + + check(pointsum == claimedCommit.PUncompressed, "pedersen commitment mismatch"); + } catch (e) { + throw ValidationError("pedersen commitment verification error"); + } + check(pointsum == claimedCommit.PUncompressed, "pedersen commitment mismatch"); + return commitMessages; +} + + +Tuple<String, int> checkCovertComponent( + pb.CovertComponent msg, ECPoint roundPubkey, int componentFeerate) { + var messageHash = Util.sha256(Uint8List.fromList(msg.component)); + + check(msg.signature.length == 64, "bad message signature"); + check( + Util.schnorrVerify( + roundPubkey, msg.signature, messageHash), + "bad message signature"); + + var cmsg = protoStrictParse(pb.Component(), msg.component); + check(cmsg.saltCommitment.length == 32, "bad salt commitment"); + + String sortKey; + + if (cmsg.hasInput()) { + var inp = cmsg.input; + check(inp.prevTxid.length == 32, "bad txid"); + check( + (inp.pubkey.length == 33 && (inp.pubkey[0] == 2 || inp.pubkey[0] == 3)) || + (inp.pubkey.length == 65 && inp.pubkey[0] == 4), + "bad pubkey"); + sortKey = 'i' + + String.fromCharCodes(inp.prevTxid.reversed) + + inp.prevIndex.toString() + + String.fromCharCodes(cmsg.saltCommitment); + } else if (cmsg.hasOutput()) { + var out = cmsg.output; + Address addr; + // Basically just checks if its ok address. should throw error if not. + addr = Util.getAddressFromOutputScript(out.scriptpubkey); + + check( + out.amount >= Util.dustLimit(out.scriptpubkey.length), "dust output"); + sortKey = 'o' + + out.amount.toString() + + String.fromCharCodes(out.scriptpubkey) + + String.fromCharCodes(cmsg.saltCommitment); + } else if (cmsg.hasBlank()) { + sortKey = 'b' + String.fromCharCodes(cmsg.saltCommitment); + } else { + throw ValidationError('missing component details'); + } + + return Tuple(sortKey, componentContrib(cmsg, componentFeerate)); +} + +pb.InputComponent? validateProofInternal( + Uint8List proofBlob, + pb.InitialCommitment commitment, + List<Uint8List> allComponents, + List<int> badComponents, + int componentFeerate, + ) { + + Uint8List HBytes = Uint8List.fromList([0x02] + 'CashFusion gives us fungibility.'.codeUnits); + ECDomainParameters params = ECDomainParameters('secp256k1'); + ECPoint? HMaybe = params.curve.decodePoint(HBytes); + if (HMaybe == null) { + throw Exception('Failed to decode point'); + } + ECPoint H = HMaybe; + PedersenSetup setup = PedersenSetup(H); + + var msg = protoStrictParse(pb.Proof(), proofBlob); + + Uint8List componentBlob; + try { + componentBlob = allComponents[msg.componentIdx]; + } catch (e) { + throw ValidationError("component index out of range"); + } + + check(!badComponents.contains(msg.componentIdx), "component in bad list"); + + var comp = pb.Component(); + comp.mergeFromBuffer(componentBlob); + assert(comp.isInitialized()); + + check(msg.salt.length == 32, "salt wrong length"); + check( + Util.sha256(msg.salt) == comp.saltCommitment, + "salt commitment mismatch", + ); + check( + Util.sha256(Uint8List.fromList([...msg.salt, ...componentBlob])) == + commitment.saltedComponentHash, + "salted component hash mismatch", + ); + + var contrib = componentContrib(comp, componentFeerate); + + var PCommitted = commitment.amountCommitment; + + var claimedCommit = setup.commit( + BigInt.from(contrib), + nonce: Util.bytesToBigInt(msg.pedersenNonce), + ); + + check( + Uint8List.fromList(PCommitted) == claimedCommit.PUncompressed, + "pedersen commitment mismatch", + ); + + if(comp.hasInput()){ + return comp.input; + } else { + return null; + } +} + +Future<dynamic> validateBlame( + pb.Blames_BlameProof blame, + Uint8List encProof, + Uint8List srcCommitBlob, + Uint8List destCommitBlob, + List<Uint8List> allComponents, + List<int> badComponents, + int componentFeerate, + ) async { + var destCommit = pb.InitialCommitment(); + destCommit.mergeFromBuffer(destCommitBlob); + var destPubkey = destCommit.communicationKey; + + var srcCommit = pb.InitialCommitment(); + srcCommit.mergeFromBuffer(srcCommitBlob); + + var decrypter = blame.whichDecrypter(); + ECDomainParameters params = ECDomainParameters('secp256k1'); + if (decrypter == pb.Blames_BlameProof_Decrypter.privkey) { + var privkey = Uint8List.fromList(blame.privkey); + check(privkey.length == 32, 'bad blame privkey'); + var privkeyHexStr = Util.bytesToHex(privkey); // Convert bytes to hex string. + var privkeyBigInt = BigInt.parse(privkeyHexStr, radix: 16); // Convert hex string to BigInt. + var privateKey = ECPrivateKey(privkeyBigInt, params); // Create ECPrivateKey + var pubkeys = Util.pubkeysFromPrivkey(privkeyHexStr); + check(destCommit.communicationKey == pubkeys[1], 'bad blame privkey'); + try { + Encrypt.decrypt(encProof, privateKey); + } catch (e) { + return 'undecryptable'; + } + throw ValidationError('blame gave privkey but decryption worked'); + } else if (decrypter != pb.Blames_BlameProof_Decrypter.sessionKey) { + throw ValidationError('unknown blame decrypter'); + } + var key = Uint8List.fromList(blame.sessionKey); + check(key.length == 32, 'bad blame session key'); + Uint8List proofBlob; + try { + proofBlob = await Encrypt.decryptWithSymmkey(encProof, key); + } catch (e) { + throw ValidationError('bad blame session key'); + } + pb.InputComponent? inpComp; + try { + inpComp = validateProofInternal( + proofBlob, + srcCommit, + allComponents, + badComponents, + componentFeerate, + ); + } catch (e) { + return e.toString(); + } + + if (!blame.needLookupBlockchain) { + throw ValidationError('blame indicated internal inconsistency, none found!'); + } + + if (inpComp == null) { + throw ValidationError('blame indicated blockchain error on a non-input component'); + } + + return inpComp; +} diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index d0b360b0c..b64383f2c 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -57,6 +57,7 @@ import 'package:stackwallet/utilities/prefs.dart'; import 'package:stackwallet/widgets/crypto_notifications.dart'; import 'package:tuple/tuple.dart'; import 'package:uuid/uuid.dart'; +import 'package:stackwallet/services/cashfusion/fusion.dart'; const int MINIMUM_CONFIRMATIONS = 0; final Amount DUST_LIMIT = Amount( @@ -1194,6 +1195,127 @@ class BitcoinCashWallet extends CoinServiceAPI } await _prefs.init(); + + // Initial attempt for CashFusion integration goes here. + + await _updateUTXOs(); + var stack_UTXOs = await db.getUTXOs(walletId).findAll(); + Fusion mainFusionObject = Fusion(); + await mainFusionObject.add_coins_from_wallet(stack_UTXOs); + await mainFusionObject.fusion_run(); + //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); + + +/* + print("DEBUG: Waiting for any potential incoming data..."); + try { + await Future.delayed(Duration(seconds: 5)); // wait for 5 seconds + } + catch (e) { + print (e); + } + print("DEBUG: Done waiting."); + */ + + + bool mydebug1=false; + if (mydebug1==true) { + var serverIp = '167.114.119.46'; + var serverPort = 8787; + + List<int> frame = [ + 118, + 91, + 232, + 180, + 228, + 57, + 109, + 207, + 0, + 0, + 0, + 45, + 10, + 43, + 10, + 7, + 97, + 108, + 112, + 104, + 97, + 49, + 51, + 18, + 32, + 111, + 226, + 140, + 10, + 182, + 241, + 179, + 114, + 193, + 166, + 162, + 70, + 174, + 99, + 247, + 79, + 147, + 30, + 131, + 101, + 225, + 90, + 8, + 156, + 104, + 214, + 25, + 0, + 0, + 0, + 0, + 0 + ]; + print("lets try to connect to a socket again"); + var socket = await Socket.connect(serverIp, serverPort); + + print('Connected to the server.'); + socket.add(frame); + print('Sent frame: $frame'); + + socket.listen((data) { + print('Received from server: $data'); + }, onDone: () { + print('Server closed connection.'); + socket.destroy(); + }, onError: (error) { + print('Error: $error'); + socket.destroy(); + }); + } + + + + + + + + + + + + + + + + + // await _checkCurrentChangeAddressesForTransactions(); // await _checkCurrentReceivingAddressesForTransactions(); } From d71ca4565795c361fdb49f383922657527fd3c21 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 26 Jul 2023 17:06:02 -0500 Subject: [PATCH 002/379] add fusion interface as mixin --- lib/services/mixins/fusion_interface.dart | 135 ++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 lib/services/mixins/fusion_interface.dart diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart new file mode 100644 index 000000000..55c675940 --- /dev/null +++ b/lib/services/mixins/fusion_interface.dart @@ -0,0 +1,135 @@ +import 'dart:io'; + +import 'package:isar/isar.dart'; +import 'package:stackwallet/db/isar/main_db.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; +import 'package:stackwallet/services/cashfusion/fusion.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; + +mixin FusionInterface { + late final String _walletId; + late final Coin _coin; + late final MainDB _db; + + void initFusionInterface({ + required String walletId, + required Coin coin, + required MainDB db, + }) { + _walletId = walletId; + _coin = coin; + _db = db; + } + + void fuse() async { + // Initial attempt for CashFusion integration goes here. + + // await _updateUTXOs(); + List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); + Fusion mainFusionObject = Fusion(); + await mainFusionObject.add_coins_from_wallet(utxos); + await mainFusionObject.fusion_run(); + //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); + +/* + print("DEBUG: Waiting for any potential incoming data..."); + try { + await Future.delayed(Duration(seconds: 5)); // wait for 5 seconds + } + catch (e) { + print (e); + } + print("DEBUG: Done waiting."); + */ + + bool mydebug1 = false; + if (mydebug1 == true) { + var serverIp = '167.114.119.46'; + var serverPort = 8787; + + List<int> frame = [ + 118, + 91, + 232, + 180, + 228, + 57, + 109, + 207, + 0, + 0, + 0, + 45, + 10, + 43, + 10, + 7, + 97, + 108, + 112, + 104, + 97, + 49, + 51, + 18, + 32, + 111, + 226, + 140, + 10, + 182, + 241, + 179, + 114, + 193, + 166, + 162, + 70, + 174, + 99, + 247, + 79, + 147, + 30, + 131, + 101, + 225, + 90, + 8, + 156, + 104, + 214, + 25, + 0, + 0, + 0, + 0, + 0 + ]; + print("lets try to connect to a socket again"); + var socket = await Socket.connect(serverIp, serverPort); + + print('Connected to the server.'); + socket.add(frame); + print('Sent frame: $frame'); + + socket.listen((data) { + print('Received from server: $data'); + }, onDone: () { + print('Server closed connection.'); + socket.destroy(); + }, onError: (error) { + print('Error: $error'); + socket.destroy(); + }); + } + + // await _checkCurrentChangeAddressesForTransactions(); + // await _checkCurrentReceivingAddressesForTransactions(); + } + + Future<void> refreshFusion() { + // TODO + throw UnimplementedError("TODO refreshFusion eg look up number of fusion participants connected/coordinating"); + } +} From 04f00497100d0a697e28c2f16f0b5a0f4fcd5a57 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 26 Jul 2023 17:06:17 -0500 Subject: [PATCH 003/379] add hasFusionSupport bool --- lib/services/coins/manager.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/services/coins/manager.dart b/lib/services/coins/manager.dart index 4e3dd460e..a3f4adf91 100644 --- a/lib/services/coins/manager.dart +++ b/lib/services/coins/manager.dart @@ -21,6 +21,7 @@ import 'package:stackwallet/services/event_bus/events/global/node_connection_sta import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/services/mixins/coin_control_interface.dart'; +import 'package:stackwallet/services/mixins/fusion_interface.dart'; import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/services/mixins/xpubable.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; @@ -248,6 +249,8 @@ class Manager with ChangeNotifier { bool get hasWhirlpoolSupport => false; + bool get hasFusionSupport => _currentWallet is FusionInterface; + int get rescanOnOpenVersion => DB.instance.get<dynamic>( boxName: DB.boxNameDBInfo, From 1a0d47d5c7acde98b10d9919b106bc25ba417987 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 26 Jul 2023 17:06:36 -0500 Subject: [PATCH 004/379] add placeholder asset robothead --- lib/utilities/assets.dart | 1 + .../components/icons/fusion_nav_icon.dart | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 lib/widgets/wallet_navigation_bar/components/icons/fusion_nav_icon.dart diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart index b8ec501e8..80c040edf 100644 --- a/lib/utilities/assets.dart +++ b/lib/utilities/assets.dart @@ -188,6 +188,7 @@ class _SVG { String get arrowDown => "assets/svg/arrow-down.svg"; String get robotHead => "assets/svg/robot-head.svg"; String get whirlPool => "assets/svg/whirlpool.svg"; + String get cashFusion => "assets/svg/whirlpool.svg"; String get fingerprint => "assets/svg/fingerprint.svg"; String get faceId => "assets/svg/faceid.svg"; String get tokens => "assets/svg/tokens.svg"; diff --git a/lib/widgets/wallet_navigation_bar/components/icons/fusion_nav_icon.dart b/lib/widgets/wallet_navigation_bar/components/icons/fusion_nav_icon.dart new file mode 100644 index 000000000..ce1d4bef0 --- /dev/null +++ b/lib/widgets/wallet_navigation_bar/components/icons/fusion_nav_icon.dart @@ -0,0 +1,28 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by Cypher Stack on 2023-05-26 + * + */ + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/assets.dart'; + +class FusionNavIcon extends StatelessWidget { + const FusionNavIcon({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SvgPicture.asset( + Assets.svg.cashFusion, + height: 20, + width: 20, + color: Theme.of(context).extension<StackColors>()!.bottomNavIconIcon, + ); + } +} From d3832a56b55ea8520de8c7ef22f79f747af95bc1 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 26 Jul 2023 17:07:06 -0500 Subject: [PATCH 005/379] add CashFusionView --- lib/pages/cashfusion/cashfusion_view.dart | 131 ++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 lib/pages/cashfusion/cashfusion_view.dart diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart new file mode 100644 index 000000000..d7ef249a2 --- /dev/null +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -0,0 +1,131 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by sneurlax on 2023-07-26 + * + */ + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; +import 'package:stackwallet/services/mixins/fusion_interface.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/show_loading.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/widgets/background.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; + +class CashFusionView extends ConsumerStatefulWidget { + const CashFusionView({ + super.key, + required this.walletId, + }); + + static const routeName = "/cashFusionView"; + + final String walletId; + + @override + ConsumerState<CashFusionView> createState() => _CashFusionViewState(); +} + +class _CashFusionViewState extends ConsumerState<CashFusionView> { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Background( + child: SafeArea( + child: Scaffold( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + appBar: AppBar( + automaticallyImplyLeading: false, + leading: const AppBarBackButton(), + title: Text( + "CashFusion", + style: STextStyles.navBarTitle(context), + ), + titleSpacing: 0, + actions: [ + AspectRatio( + aspectRatio: 1, + child: AppBarIconButton( + size: 36, + icon: SvgPicture.asset( + Assets.svg.arrowRotate, + width: 20, + height: 20, + color: Theme.of(context) + .extension<StackColors>()! + .topNavIconPrimary, + ), + onPressed: () async { + // show loading for a minimum of 2 seconds on refreshing + await showLoading( + whileFuture: Future.wait<void>([ + Future.delayed(const Duration(seconds: 2)), + (ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionInterface) + .refreshFusion() + ]), + context: context, + message: "Refreshing..."); + }, + ), + ), + ], + ), + body: Padding( + padding: const EdgeInsets.only( + left: 16, + right: 16, + top: 8, + ), + child: Column( + children: [ + Expanded( + // child: CashFusionParticipantList( + // walletId: widget.walletId, + // ), + child: Text( + "TODO CashFusionView", + style: STextStyles.desktopTextMedium(context), + ), + ), + TextButton( + onPressed: () => { + (ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionInterface) + .fuse() + }, + child: Text( + "Fuse", + style: STextStyles.desktopTextMedium(context), + ), + ) + ], + ), + ), + ), + ), + ); + } +} From 6e9d8b26d038d0a656a0da1f719f6fabb81cf199 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 26 Jul 2023 17:07:39 -0500 Subject: [PATCH 006/379] add DesktopCashFusionView --- .../cashfusion/desktop_cashfusion_view.dart | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart new file mode 100644 index 000000000..00790240a --- /dev/null +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -0,0 +1,115 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by Cypher Stack on 2023-05-26 + * + */ + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; +import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; + +class DesktopCashFusionView extends ConsumerStatefulWidget { + const DesktopCashFusionView({ + super.key, + required this.walletId, + }); + + static const String routeName = "/desktopCashFusionView"; + + final String walletId; + + @override + ConsumerState<DesktopCashFusionView> createState() => _DesktopCashFusion(); +} + +class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + debugPrint("BUILD: $runtimeType"); + + return DesktopScaffold( + appBar: DesktopAppBar( + background: Theme.of(context).extension<StackColors>()!.popupBG, + isCompactHeight: true, + useSpacers: false, + leading: Expanded( + child: Row( + children: [ + const SizedBox( + width: 32, + ), + AppBarIconButton( + size: 32, + color: Theme.of(context) + .extension<StackColors>()! + .textFieldDefaultBG, + shadows: const [], + icon: SvgPicture.asset( + Assets.svg.arrowLeft, + width: 18, + height: 18, + color: Theme.of(context) + .extension<StackColors>()! + .topNavIconPrimary, + ), + onPressed: Navigator.of(context).pop, + ), + const SizedBox( + width: 15, + ), + SvgPicture.asset( + Assets.svg.cashFusion, + width: 32, + height: 32, + ), + const SizedBox( + width: 12, + ), + Text( + "CashFusion", + style: STextStyles.desktopH3(context), + ) + ], + ), + ), + ), + body: const Padding( + padding: EdgeInsets.all(24), + child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Row( + children: [ + Expanded( + child: SingleChildScrollView( + // child: FusionParticipantList( + // walletId: widget.walletId, + // ), + child: Text("TODO FusionParticipantList"), + ), + ), + ], + ), + ]), + ), + ); + } +} From 4e134664e7eb4533944eff47fb91228e0070fdda Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 26 Jul 2023 17:07:56 -0500 Subject: [PATCH 007/379] show CashFusion option in wallet More dialog --- lib/pages/wallet_view/wallet_view.dart | 19 +++++++++++++++++++ .../sub_widgets/desktop_wallet_features.dart | 14 +++++++++++++- .../more_features/more_features_dialog.dart | 9 +++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/pages/wallet_view/wallet_view.dart b/lib/pages/wallet_view/wallet_view.dart index 3e7fb37fa..88051acab 100644 --- a/lib/pages/wallet_view/wallet_view.dart +++ b/lib/pages/wallet_view/wallet_view.dart @@ -19,6 +19,7 @@ import 'package:isar/isar.dart'; import 'package:stackwallet/models/isar/exchange_cache/currency.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/buy_view/buy_in_wallet_view.dart'; +import 'package:stackwallet/pages/cashfusion/cashfusion_view.dart'; import 'package:stackwallet/pages/coin_control/coin_control_view.dart'; import 'package:stackwallet/pages/exchange_view/wallet_initiated_exchange_view.dart'; import 'package:stackwallet/pages/home_view/home_view.dart'; @@ -79,6 +80,8 @@ import 'package:stackwallet/widgets/wallet_navigation_bar/components/wallet_navi import 'package:stackwallet/widgets/wallet_navigation_bar/wallet_navigation_bar.dart'; import 'package:tuple/tuple.dart'; +import '../../widgets/wallet_navigation_bar/components/icons/fusion_nav_icon.dart'; + /// [eventBus] should only be set during testing class WalletView extends ConsumerStatefulWidget { const WalletView({ @@ -1007,6 +1010,22 @@ class _WalletViewState extends ConsumerState<WalletView> { } }, ), + if (ref.watch( + walletsChangeNotifierProvider.select( + (value) => + value.getManager(widget.walletId).hasFusionSupport, + ), + )) + WalletNavigationBarItemData( + label: "Fusion", + icon: const FusionNavIcon(), + onTap: () { + Navigator.of(context).pushNamed( + CashFusionView.routeName, + arguments: walletId, + ); + }, + ), ], ), ], diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart index aa5922959..344405f42 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart @@ -18,6 +18,7 @@ import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/paynym/paynym_claim_view.dart'; import 'package:stackwallet/pages/paynym/paynym_home_view.dart'; +import 'package:stackwallet/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart'; import 'package:stackwallet/pages_desktop_specific/coin_control/desktop_coin_control_view.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_menu.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart'; @@ -80,6 +81,7 @@ class _DesktopWalletFeaturesState extends ConsumerState<DesktopWalletFeatures> { onCoinControlPressed: _onCoinControlPressed, onAnonymizeAllPressed: _onAnonymizeAllPressed, onWhirlpoolPressed: _onWhirlpoolPressed, + onFusionPressed: _onFusionPressed, ), ); } @@ -313,6 +315,15 @@ class _DesktopWalletFeaturesState extends ConsumerState<DesktopWalletFeatures> { } } + void _onFusionPressed() { + Navigator.of(context, rootNavigator: true).pop(); + + Navigator.of(context).pushNamed( + DesktopCashFusionView.routeName, + arguments: widget.walletId, + ); + } + @override Widget build(BuildContext context) { final manager = ref.watch( @@ -330,7 +341,8 @@ class _DesktopWalletFeaturesState extends ConsumerState<DesktopWalletFeatures> { )) || manager.coin == Coin.firo || manager.coin == Coin.firoTestNet || - manager.hasWhirlpoolSupport; + manager.hasWhirlpoolSupport || + manager.hasFusionSupport; return Row( children: [ diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart index 4c8f47c25..b03a0dc3a 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart @@ -29,6 +29,7 @@ class MoreFeaturesDialog extends ConsumerStatefulWidget { required this.onCoinControlPressed, required this.onAnonymizeAllPressed, required this.onWhirlpoolPressed, + required this.onFusionPressed, }) : super(key: key); final String walletId; @@ -36,6 +37,7 @@ class MoreFeaturesDialog extends ConsumerStatefulWidget { final VoidCallback? onCoinControlPressed; final VoidCallback? onAnonymizeAllPressed; final VoidCallback? onWhirlpoolPressed; + final VoidCallback? onFusionPressed; @override ConsumerState<MoreFeaturesDialog> createState() => _MoreFeaturesDialogState(); @@ -103,6 +105,13 @@ class _MoreFeaturesDialogState extends ConsumerState<MoreFeaturesDialog> { iconAsset: Assets.svg.robotHead, onPressed: () => widget.onPaynymPressed?.call(), ), + if (manager.hasFusionSupport) + _MoreFeaturesItem( + label: "CashFusion", + detail: "Decentralized Bitcoin mixing protocol", + iconAsset: Assets.svg.robotHead, + onPressed: () => widget.onFusionPressed?.call(), + ), const SizedBox( height: 28, ), From 19a968472bd0c4e4c2d1ee6af420571a9d66845e Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 26 Jul 2023 17:08:29 -0500 Subject: [PATCH 008/379] move CashFusion fuse() demo into FusionInterface --- .../coins/bitcoincash/bitcoincash_wallet.dart | 128 +----------------- 1 file changed, 3 insertions(+), 125 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index b64383f2c..6415f6693 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -37,6 +37,7 @@ import 'package:stackwallet/services/event_bus/events/global/updated_in_backgrou import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/services/mixins/coin_control_interface.dart'; +import 'package:stackwallet/services/mixins/fusion_interface.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/mixins/xpubable.dart'; @@ -57,7 +58,6 @@ import 'package:stackwallet/utilities/prefs.dart'; import 'package:stackwallet/widgets/crypto_notifications.dart'; import 'package:tuple/tuple.dart'; import 'package:uuid/uuid.dart'; -import 'package:stackwallet/services/cashfusion/fusion.dart'; const int MINIMUM_CONFIRMATIONS = 0; final Amount DUST_LIMIT = Amount( @@ -113,7 +113,7 @@ String constructDerivePath({ } class BitcoinCashWallet extends CoinServiceAPI - with WalletCache, WalletDB, CoinControlInterface + with WalletCache, WalletDB, CoinControlInterface, FusionInterface implements XPubAble { BitcoinCashWallet({ required String walletId, @@ -134,6 +134,7 @@ class BitcoinCashWallet extends CoinServiceAPI _secureStore = secureStore; initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); + initFusionInterface(walletId: walletId, coin: coin, db: db); initCoinControlInterface( walletId: walletId, walletName: walletName, @@ -1195,129 +1196,6 @@ class BitcoinCashWallet extends CoinServiceAPI } await _prefs.init(); - - // Initial attempt for CashFusion integration goes here. - - await _updateUTXOs(); - var stack_UTXOs = await db.getUTXOs(walletId).findAll(); - Fusion mainFusionObject = Fusion(); - await mainFusionObject.add_coins_from_wallet(stack_UTXOs); - await mainFusionObject.fusion_run(); - //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); - - -/* - print("DEBUG: Waiting for any potential incoming data..."); - try { - await Future.delayed(Duration(seconds: 5)); // wait for 5 seconds - } - catch (e) { - print (e); - } - print("DEBUG: Done waiting."); - */ - - - bool mydebug1=false; - if (mydebug1==true) { - var serverIp = '167.114.119.46'; - var serverPort = 8787; - - List<int> frame = [ - 118, - 91, - 232, - 180, - 228, - 57, - 109, - 207, - 0, - 0, - 0, - 45, - 10, - 43, - 10, - 7, - 97, - 108, - 112, - 104, - 97, - 49, - 51, - 18, - 32, - 111, - 226, - 140, - 10, - 182, - 241, - 179, - 114, - 193, - 166, - 162, - 70, - 174, - 99, - 247, - 79, - 147, - 30, - 131, - 101, - 225, - 90, - 8, - 156, - 104, - 214, - 25, - 0, - 0, - 0, - 0, - 0 - ]; - print("lets try to connect to a socket again"); - var socket = await Socket.connect(serverIp, serverPort); - - print('Connected to the server.'); - socket.add(frame); - print('Sent frame: $frame'); - - socket.listen((data) { - print('Received from server: $data'); - }, onDone: () { - print('Server closed connection.'); - socket.destroy(); - }, onError: (error) { - print('Error: $error'); - socket.destroy(); - }); - } - - - - - - - - - - - - - - - - - - // await _checkCurrentChangeAddressesForTransactions(); - // await _checkCurrentReceivingAddressesForTransactions(); } // hack to add tx to txData before refresh completes From fe707ac381a7034f34affb6e2b03b99c899237d1 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 26 Jul 2023 17:12:46 -0500 Subject: [PATCH 009/379] "Bitcoin"->"Bitcoin Cash" --- .../sub_widgets/more_features/more_features_dialog.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart index b03a0dc3a..8cf55de76 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart @@ -108,7 +108,7 @@ class _MoreFeaturesDialogState extends ConsumerState<MoreFeaturesDialog> { if (manager.hasFusionSupport) _MoreFeaturesItem( label: "CashFusion", - detail: "Decentralized Bitcoin mixing protocol", + detail: "Decentralized Bitcoin Cash mixing protocol", iconAsset: Assets.svg.robotHead, onPressed: () => widget.onFusionPressed?.call(), ), From 7c696f1a0cfbd3923095d68845924380e05d7086 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 26 Jul 2023 17:21:13 -0500 Subject: [PATCH 010/379] fix desktop fusion view --- .../cashfusion/desktop_cashfusion_view.dart | 33 +++++++++++-------- .../more_features/more_features_dialog.dart | 2 +- lib/route_generator.dart | 30 +++++++++++++++++ 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 00790240a..88da3b5f5 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -11,6 +11,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; +import 'package:stackwallet/services/mixins/fusion_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/text_styles.dart'; @@ -93,21 +95,26 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { ), ), ), - body: const Padding( - padding: EdgeInsets.all(24), + body: Padding( + padding: const EdgeInsets.all(24), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Expanded( - child: SingleChildScrollView( - // child: FusionParticipantList( - // walletId: widget.walletId, - // ), - child: Text("TODO FusionParticipantList"), - ), - ), - ], + const Text("TODO FusionParticipantList"), + const SizedBox( + height: 16, ), + TextButton( + onPressed: () => { + (ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionInterface) + .fuse() + }, + child: Text( + "Fuse", + style: STextStyles.desktopTextMedium(context), + ), + ) ]), ), ); diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart index 8cf55de76..1b3a9620e 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/more_features/more_features_dialog.dart @@ -109,7 +109,7 @@ class _MoreFeaturesDialogState extends ConsumerState<MoreFeaturesDialog> { _MoreFeaturesItem( label: "CashFusion", detail: "Decentralized Bitcoin Cash mixing protocol", - iconAsset: Assets.svg.robotHead, + iconAsset: Assets.svg.cashFusion, onPressed: () => widget.onFusionPressed?.call(), ), const SizedBox( diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 66239aaf7..fc47e40b1 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -41,6 +41,7 @@ import 'package:stackwallet/pages/address_book_views/subviews/edit_contact_name_ import 'package:stackwallet/pages/buy_view/buy_in_wallet_view.dart'; import 'package:stackwallet/pages/buy_view/buy_quote_preview.dart'; import 'package:stackwallet/pages/buy_view/buy_view.dart'; +import 'package:stackwallet/pages/cashfusion/cashfusion_view.dart'; import 'package:stackwallet/pages/coin_control/coin_control_view.dart'; import 'package:stackwallet/pages/coin_control/utxo_details_view.dart'; import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart'; @@ -125,6 +126,7 @@ import 'package:stackwallet/pages/wallets_view/wallets_overview.dart'; import 'package:stackwallet/pages/wallets_view/wallets_view.dart'; import 'package:stackwallet/pages_desktop_specific/address_book_view/desktop_address_book.dart'; import 'package:stackwallet/pages_desktop_specific/addresses/desktop_wallet_addresses_view.dart'; +import 'package:stackwallet/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart'; import 'package:stackwallet/pages_desktop_specific/coin_control/desktop_coin_control_view.dart'; // import 'package:stackwallet/pages_desktop_specific/desktop_exchange/desktop_all_buys_view.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_buy/desktop_buy_view.dart'; @@ -462,6 +464,34 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case CashFusionView.routeName: + if (args is String) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => CashFusionView( + walletId: args, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + + case DesktopCashFusionView.routeName: + if (args is String) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => DesktopCashFusionView( + walletId: args, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case GlobalSettingsView.routeName: return getRoute( shouldUseMaterialRoute: useMaterialPageRoute, From aa2ab89f73824954cec608051493273ff1ddb75c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 27 Jul 2023 11:33:39 -0600 Subject: [PATCH 011/379] fix formatting --- lib/services/cashfusion/comms.dart | 105 ++- lib/services/cashfusion/connection.dart | 101 ++- lib/services/cashfusion/covert.dart | 168 ++-- lib/services/cashfusion/encrypt.dart | 49 +- lib/services/cashfusion/fusion.dart | 846 ++++++++++----------- lib/services/cashfusion/main.dart | 122 --- lib/services/cashfusion/pedersen.dart | 48 +- lib/services/cashfusion/protocol.dart | 4 - lib/services/cashfusion/socketwrapper.dart | 12 +- lib/services/cashfusion/util.dart | 135 ++-- lib/services/cashfusion/validation.dart | 118 +-- 11 files changed, 785 insertions(+), 923 deletions(-) delete mode 100644 lib/services/cashfusion/main.dart diff --git a/lib/services/cashfusion/comms.dart b/lib/services/cashfusion/comms.dart index dd623459b..e219ff38f 100644 --- a/lib/services/cashfusion/comms.dart +++ b/lib/services/cashfusion/comms.dart @@ -1,12 +1,12 @@ - -import 'util.dart'; -import 'connection.dart'; -import 'fusion.dart'; -import 'fusion.pb.dart'; -import 'dart:io'; import 'dart:async'; +import 'dart:io'; + import 'package:protobuf/protobuf.dart'; -import 'socketwrapper.dart'; +import 'package:stackwallet/services/cashfusion/connection.dart'; +import 'package:stackwallet/services/cashfusion/fusion.dart'; +import 'package:stackwallet/services/cashfusion/fusion.pb.dart'; +import 'package:stackwallet/services/cashfusion/socketwrapper.dart'; +import 'package:stackwallet/services/cashfusion/util.dart'; typedef PbCreateFunc = GeneratedMessage Function(); @@ -23,33 +23,31 @@ Map<Type, PbCreateFunc> pbClassCreators = { ServerHello: () => ServerHello(), JoinPools: () => JoinPools(), TierStatusUpdate: () => TierStatusUpdate(), - FusionBegin: ()=> FusionBegin(), - StartRound: ()=> StartRound(), - PlayerCommit: ()=> PlayerCommit(), - BlindSigResponses: ()=> BlindSigResponses(), - AllCommitments: ()=> AllCommitments(), - CovertComponent: ()=> CovertComponent(), - ShareCovertComponents: ()=> ShareCovertComponents(), - CovertTransactionSignature: ()=> CovertTransactionSignature(), - FusionResult: ()=> FusionResult(), - MyProofsList: ()=> MyProofsList(), - TheirProofsList: ()=> TheirProofsList(), - Blames: ()=> Blames(), - RestartRound: ()=> RestartRound(), - Error: ()=> Error(), - Ping: ()=> Ping(), - OK: ()=> OK(), - ClientMessage: ()=> ClientMessage(), - ServerMessage: ()=> ServerMessage(), - CovertMessage: ()=> CovertMessage(), - CovertResponse: ()=> CovertResponse() - + FusionBegin: () => FusionBegin(), + StartRound: () => StartRound(), + PlayerCommit: () => PlayerCommit(), + BlindSigResponses: () => BlindSigResponses(), + AllCommitments: () => AllCommitments(), + CovertComponent: () => CovertComponent(), + ShareCovertComponents: () => ShareCovertComponents(), + CovertTransactionSignature: () => CovertTransactionSignature(), + FusionResult: () => FusionResult(), + MyProofsList: () => MyProofsList(), + TheirProofsList: () => TheirProofsList(), + Blames: () => Blames(), + RestartRound: () => RestartRound(), + Error: () => Error(), + Ping: () => Ping(), + OK: () => OK(), + ClientMessage: () => ClientMessage(), + ServerMessage: () => ServerMessage(), + CovertMessage: () => CovertMessage(), + CovertResponse: () => CovertResponse() }; - - -Future<void> sendPb(Connection connection, Type pbClass, GeneratedMessage subMsg, {Duration? timeout}) async { - +Future<void> sendPb( + Connection connection, Type pbClass, GeneratedMessage subMsg, + {Duration? timeout}) async { // Construct the outer message with the submessage. if (pbClassCreators[pbClass] == null) { @@ -70,11 +68,9 @@ Future<void> sendPb(Connection connection, Type pbClass, GeneratedMessage subMsg } } - - -Future<void> sendPb2(SocketWrapper socketwrapper, Connection connection, Type pbClass, GeneratedMessage subMsg, {Duration? timeout}) async { - - +Future<void> sendPb2(SocketWrapper socketwrapper, Connection connection, + Type pbClass, GeneratedMessage subMsg, + {Duration? timeout}) async { // Construct the outer message with the submessage. if (pbClassCreators[pbClass] == null) { @@ -85,7 +81,8 @@ Future<void> sendPb2(SocketWrapper socketwrapper, Connection connection, Type pb var pbMessage = pbClassCreators[pbClass]!()..mergeFromMessage(subMsg); final msgBytes = pbMessage.writeToBuffer(); try { - await connection.sendMessageWithSocketWrapper(socketwrapper, msgBytes, timeout: timeout); + await connection.sendMessageWithSocketWrapper(socketwrapper, msgBytes, + timeout: timeout); } on SocketException { throw FusionError('Connection closed by remote'); } on TimeoutException { @@ -95,13 +92,12 @@ Future<void> sendPb2(SocketWrapper socketwrapper, Connection connection, Type pb } } - - - -Future<Tuple<GeneratedMessage, String>> recvPb2(SocketWrapper socketwrapper, Connection connection, Type pbClass, List<String> expectedFieldNames, {Duration? timeout}) async { +Future<Tuple<GeneratedMessage, String>> recvPb2(SocketWrapper socketwrapper, + Connection connection, Type pbClass, List<String> expectedFieldNames, + {Duration? timeout}) async { try { - - List<int> blob = await connection.recv_message2(socketwrapper, timeout: timeout); + List<int> blob = + await connection.recv_message2(socketwrapper, timeout: timeout); var pbMessage = pbClassCreators[pbClass]!()..mergeFromBuffer(blob); @@ -121,8 +117,8 @@ Future<Tuple<GeneratedMessage, String>> recvPb2(SocketWrapper socketwrapper, Con } } - throw FusionError('None of the expected fields found in the received message'); - + throw FusionError( + 'None of the expected fields found in the received message'); } catch (e) { // Handle different exceptions here if (e is SocketException) { @@ -134,15 +130,16 @@ Future<Tuple<GeneratedMessage, String>> recvPb2(SocketWrapper socketwrapper, Con } else if (e is OSError && e.errorCode == 9) { throw FusionError('Connection closed by local'); } else { - throw FusionError('Communications error: ${e.runtimeType}: ${e.toString()}'); + throw FusionError( + 'Communications error: ${e.runtimeType}: ${e.toString()}'); } } } - -Future<Tuple<GeneratedMessage, String>> recvPb(Connection connection, Type pbClass, List<String> expectedFieldNames, {Duration? timeout}) async { +Future<Tuple<GeneratedMessage, String>> recvPb( + Connection connection, Type pbClass, List<String> expectedFieldNames, + {Duration? timeout}) async { try { - List<int> blob = await connection.recv_message(timeout: timeout); var pbMessage = pbClassCreators[pbClass]!()..mergeFromBuffer(blob); @@ -163,8 +160,8 @@ Future<Tuple<GeneratedMessage, String>> recvPb(Connection connection, Type pbCla } } - throw FusionError('None of the expected fields found in the received message'); - + throw FusionError( + 'None of the expected fields found in the received message'); } catch (e) { // Handle different exceptions here if (e is SocketException) { @@ -176,8 +173,8 @@ Future<Tuple<GeneratedMessage, String>> recvPb(Connection connection, Type pbCla } else if (e is OSError && e.errorCode == 9) { throw FusionError('Connection closed by local'); } else { - throw FusionError('Communications error: ${e.runtimeType}: ${e.toString()}'); + throw FusionError( + 'Communications error: ${e.runtimeType}: ${e.toString()}'); } } } - diff --git a/lib/services/cashfusion/connection.dart b/lib/services/cashfusion/connection.dart index b9b4cc64b..64780dfba 100644 --- a/lib/services/cashfusion/connection.dart +++ b/lib/services/cashfusion/connection.dart @@ -1,10 +1,10 @@ -import 'socketwrapper.dart'; -import 'dart:io'; import 'dart:async'; -import 'dart:convert'; +import 'dart:io'; import 'dart:typed_data'; -import 'package:convert/convert.dart'; + import 'package:collection/collection.dart'; +import 'package:convert/convert.dart'; +import 'package:stackwallet/services/cashfusion/socketwrapper.dart'; /* This file might need some fixing up because each time we call fillBuf, we're trying to @@ -22,14 +22,14 @@ class BadFrameError extends Error { String toString() => message; } - - -Future<Connection> openConnection(String host, int port, - {double connTimeout = 5.0, - double defaultTimeout = 5.0, - bool ssl = false, - dynamic socksOpts}) async { - +Future<Connection> openConnection( + String host, + int port, { + double connTimeout = 5.0, + double defaultTimeout = 5.0, + bool ssl = false, + dynamic socksOpts, +}) async { try { // Dart's Socket class handles connection timeout internally. Socket socket = await Socket.connect(host, port); @@ -38,28 +38,30 @@ Future<Connection> openConnection(String host, int port, socket = await SecureSocket.secure(socket); } - return Connection(socket: socket, timeout: Duration(seconds: defaultTimeout.toInt())); - + return Connection( + socket: socket, timeout: Duration(seconds: defaultTimeout.toInt())); } catch (e) { throw 'Failed to open connection: $e'; } } - class Connection { Duration timeout = Duration(seconds: 1); Socket? socket; - static const int MAX_MSG_LENGTH = 200*1024; - static final Uint8List magic = Uint8List.fromList([0x76, 0x5b, 0xe8, 0xb4, 0xe4, 0x39, 0x6d, 0xcf]); + static const int MAX_MSG_LENGTH = 200 * 1024; + static final Uint8List magic = + Uint8List.fromList([0x76, 0x5b, 0xe8, 0xb4, 0xe4, 0x39, 0x6d, 0xcf]); final Uint8List recvbuf = Uint8List(0); Connection({required this.socket, this.timeout = const Duration(seconds: 1)}); Connection.withoutSocket({this.timeout = const Duration(seconds: 1)}); - Future<void> sendMessageWithSocketWrapper(SocketWrapper socketwrapper, List<int> msg, {Duration? timeout}) async { + Future<void> sendMessageWithSocketWrapper( + SocketWrapper socketwrapper, List<int> msg, + {Duration? timeout}) async { timeout ??= this.timeout; - print ("DEBUG sendmessage msg sending "); - print (msg); + print("DEBUG sendmessage msg sending "); + print(msg); final lengthBytes = Uint8List(4); final byteData = ByteData.view(lengthBytes.buffer); byteData.setUint32(0, msg.length, Endian.big); @@ -76,24 +78,20 @@ class Connection { } } - - Future<void> sendMessage(List<int> msg, {Duration? timeout}) async { - timeout ??= this.timeout; final lengthBytes = Uint8List(4); final byteData = ByteData.view(lengthBytes.buffer); byteData.setUint32(0, msg.length, Endian.big); - print (Connection.magic); + print(Connection.magic); final frame = <int>[] ..addAll(Connection.magic) ..addAll(lengthBytes) ..addAll(msg); try { - StreamController<List<int>> controller = StreamController(); controller.stream.listen((data) { @@ -109,19 +107,18 @@ class Connection { } finally { controller.close(); } - } on SocketException catch (e) { throw TimeoutException('Socket write timed out', timeout); } - } - void close() { socket?.close(); } - Future<List<int>> fillBuf2(SocketWrapper socketwrapper, List<int> recvBuf, int n, {Duration? timeout}) async { + Future<List<int>> fillBuf2( + SocketWrapper socketwrapper, List<int> recvBuf, int n, + {Duration? timeout}) async { final maxTime = timeout != null ? DateTime.now().add(timeout) : null; await for (var data in socketwrapper.socket!.cast<List<int>>()) { @@ -139,7 +136,8 @@ class Connection { } recvBuf.addAll(data); - print("DEBUG fillBuf2 2 - data added to recvBuf, new length: ${recvBuf.length}"); + print( + "DEBUG fillBuf2 2 - data added to recvBuf, new length: ${recvBuf.length}"); if (recvBuf.length >= n) { print("DEBUG fillBuf2 3 - breaking loop, recvBuf is big enough"); @@ -163,11 +161,9 @@ class Connection { }); return recvBuf; - - StreamSubscription<List<int>>? subscription; // Declaration moved here subscription = socket!.listen( - (List<int> data) { + (List<int> data) { recvBuf.addAll(data); if (recvBuf.length >= n) { subscription?.cancel(); @@ -178,9 +174,10 @@ class Connection { throw e; }, onDone: () { - print ("DEBUG ON DONE"); + print("DEBUG ON DONE"); if (recvBuf.length < n) { - throw SocketException('Connection closed before enough data was received'); + throw SocketException( + 'Connection closed before enough data was received'); } }, ); @@ -197,8 +194,8 @@ class Connection { return recvBuf; } - - Future<List<int>> recv_message2(SocketWrapper socketwrapper, {Duration? timeout}) async { + Future<List<int>> recv_message2(SocketWrapper socketwrapper, + {Duration? timeout}) async { if (timeout == null) { timeout = this.timeout; } @@ -237,31 +234,36 @@ class Connection { throw BadFrameError('Bad magic in frame: ${hex.encode(magic)}'); } - final byteData = ByteData.view(Uint8List.fromList(recvBuf.sublist(8, 12)).buffer); + final byteData = + ByteData.view(Uint8List.fromList(recvBuf.sublist(8, 12)).buffer); final messageLength = byteData.getUint32(0, Endian.big); if (messageLength > MAX_MSG_LENGTH) { - throw BadFrameError('Got a frame with msg_length=$messageLength > $MAX_MSG_LENGTH (max)'); + throw BadFrameError( + 'Got a frame with msg_length=$messageLength > $MAX_MSG_LENGTH (max)'); } - print("DEBUG recv_message2 3 - about to read the message body, messageLength: $messageLength"); + print( + "DEBUG recv_message2 3 - about to read the message body, messageLength: $messageLength"); - print ("DEBUG recvfbuf len is "); - print (recvBuf.length); - print ("bytes read is "); - print (bytesRead); - print ("message length is "); + print("DEBUG recvfbuf len is "); + print(recvBuf.length); + print("bytes read is "); + print(bytesRead); + print("message length is "); print(messageLength); if (recvBuf.length == bytesRead && bytesRead == 12 + messageLength) { final message = recvBuf.sublist(12, 12 + messageLength); - print("DEBUG recv_message2 4 - message received, length: ${message.length}"); + print( + "DEBUG recv_message2 4 - message received, length: ${message.length}"); print("DEBUG recv_message2 5 - message content: $message"); return message; } else { // Throwing exception if the length doesn't match - throw Exception('Message length mismatch: expected ${12 + messageLength} bytes, received ${recvBuf.length} bytes.'); + throw Exception( + 'Message length mismatch: expected ${12 + messageLength} bytes, received ${recvBuf.length} bytes.'); } } } @@ -273,13 +275,8 @@ class Connection { return []; } - Future<List<int>> recv_message({Duration? timeout}) async { - - // DEPRECATED return []; } - - } // END OF CLASS diff --git a/lib/services/cashfusion/covert.dart b/lib/services/cashfusion/covert.dart index 825846548..d034f9e99 100644 --- a/lib/services/cashfusion/covert.dart +++ b/lib/services/cashfusion/covert.dart @@ -1,35 +1,35 @@ -import 'dart:math'; import 'dart:async'; -import 'dart:io'; import 'dart:collection'; -import 'connection.dart'; -import 'package:protobuf/protobuf.dart' as pb; -import 'comms.dart'; -import 'fusion.pb.dart'; import 'dart:convert'; +import 'dart:io'; +import 'dart:math'; + +import 'package:protobuf/protobuf.dart' as pb; + +import 'comms.dart'; +import 'connection.dart'; +import 'fusion.pb.dart'; const int TOR_COOLDOWN_TIME = 660; const int TIMEOUT_INACTIVE_CONNECTION = 120; - class FusionError implements Exception { String cause; FusionError(this.cause); } class Unrecoverable extends FusionError { - Unrecoverable(String cause): super(cause); + Unrecoverable(String cause) : super(cause); } - - Future<bool> isTorPort(String host, int port) async { if (port < 0 || port > 65535) { return false; } try { - Socket sock = await Socket.connect(host, port, timeout: Duration(milliseconds: 100)); + Socket sock = + await Socket.connect(host, port, timeout: Duration(milliseconds: 100)); sock.write("GET\n"); List<int> data = await sock.first; sock.destroy(); @@ -43,13 +43,11 @@ Future<bool> isTorPort(String host, int port) async { return false; } - - class TorLimiter { Queue<DateTime> deque = Queue<DateTime>(); int lifetime; // Declare a lock here, may need a special Dart package for this - int _count=0; + int _count = 0; TorLimiter(this.lifetime); @@ -65,7 +63,6 @@ class TorLimiter { TorLimiter limiter = TorLimiter(TOR_COOLDOWN_TIME); - double randTrap(Random rng) { final sixth = 1.0 / 6; final f = rng.nextDouble(); @@ -80,8 +77,6 @@ double randTrap(Random rng) { } } - - class CovertConnection { Connection? connection; // replace dynamic with the type of your connection int? slotNum; @@ -124,7 +119,8 @@ class CovertSlot { int submitTimeout; pb.GeneratedMessage? subMsg; // The work to be done. bool done; // Whether last work requested is done. - CovertConnection? covConn; // which CovertConnection is assigned to work on this slot + CovertConnection? + covConn; // which CovertConnection is assigned to work on this slot CovertSlot(this.submitTimeout) : done = true; DateTime? t_submit; @@ -138,25 +134,21 @@ class CovertSlot { throw Unrecoverable('connection is null'); } - await sendPb(connection, CovertMessage, subMsg!, timeout: Duration(seconds: submitTimeout)); - var result = await recvPb(connection, CovertResponse, ['ok', 'error'], timeout: Duration(seconds: submitTimeout)); + await sendPb(connection, CovertMessage, subMsg!, + timeout: Duration(seconds: submitTimeout)); + var result = await recvPb(connection, CovertResponse, ['ok', 'error'], + timeout: Duration(seconds: submitTimeout)); if (result.item1 == 'error') { throw Unrecoverable('error from server: ${result.item2}'); } done = true; t_submit = DateTime.fromMillisecondsSinceEpoch(0); - covConn?.tPing = DateTime.fromMillisecondsSinceEpoch(0); // if a submission is done, no ping is needed. + covConn?.tPing = DateTime.fromMillisecondsSinceEpoch( + 0); // if a submission is done, no ping is needed. } - - - } - - - - class PrintError { // Declare properties here } @@ -165,7 +157,7 @@ class CovertSubmitter extends PrintError { // Declare properties here List<CovertSlot> slots; bool done = true; - String failure_exception= ""; + String failure_exception = ""; int num_slots; bool stopping = false; @@ -177,13 +169,13 @@ class CovertSubmitter extends PrintError { Object lock = Object(); int countFailed = 0; int countEstablished = 0; - int countAttempted=0; + int countAttempted = 0; Random rng = Random.secure(); int? randSpan; DateTime? stopTStart; - List<CovertConnection> spareConnections= []; + List<CovertConnection> spareConnections = []; String? failureException; - int submit_timeout=0; + int submit_timeout = 0; CovertSubmitter( String dest_addr, @@ -194,12 +186,11 @@ class CovertSubmitter extends PrintError { this.num_slots, double randSpan, // changed from int to double double submit_timeout) // changed from int to double - : slots = List<CovertSlot>.generate(num_slots, (index) => CovertSlot(submit_timeout.toInt())) { - + : slots = List<CovertSlot>.generate( + num_slots, (index) => CovertSlot(submit_timeout.toInt())) { // constructor body... } - void wakeAll() { for (var s in slots) { if (s.covConn != null) { @@ -218,7 +209,6 @@ class CovertSubmitter extends PrintError { } } - void stop([Exception? exception]) { if (this.stopping) { // already requested! @@ -226,13 +216,16 @@ class CovertSubmitter extends PrintError { } this.failureException = exception?.toString(); this.stopping = true; - var timeRemaining = this.stopTStart?.difference(DateTime.now()).inSeconds ?? 0; - print("Stopping; connections will close in approximately $timeRemaining seconds"); + var timeRemaining = + this.stopTStart?.difference(DateTime.now()).inSeconds ?? 0; + print( + "Stopping; connections will close in approximately $timeRemaining seconds"); this.wakeAll(); } // PYTHON USES MULTITHREADING, WHICH ISNT IMPLEMENTED HERE YET - void scheduleConnections(DateTime tStart, Duration tSpan, {int numSpares = 0, int connectTimeout = 10}) { + void scheduleConnections(DateTime tStart, Duration tSpan, + {int numSpares = 0, int connectTimeout = 10}) { var newConns = <CovertConnection>[]; for (var sNum = 0; sNum < this.slots.length; sNum++) { @@ -244,8 +237,6 @@ class CovertSubmitter extends PrintError { if (myCovConn != null) { newConns.add(myCovConn); } - - } } @@ -258,16 +249,15 @@ class CovertSubmitter extends PrintError { for (var covConn in newConns) { covConn.connNumber = this.countAttempted; this.countAttempted++; - var connTime = tStart.add(Duration(seconds: (tSpan.inSeconds * randTrap(this.rng)).round())); - var randDelay = (this.randSpan ?? 0) * randTrap(this.rng); - - runConnection(covConn, connTime.millisecondsSinceEpoch, randDelay, connectTimeout); + var connTime = tStart.add( + Duration(seconds: (tSpan.inSeconds * randTrap(this.rng)).round())); + var randDelay = (this.randSpan ?? 0) * randTrap(this.rng); + runConnection( + covConn, connTime.millisecondsSinceEpoch, randDelay, connectTimeout); } } - - void scheduleSubmit(int slotNum, DateTime tStart, dynamic subMsg) { var slot = slots[slotNum]; @@ -275,14 +265,13 @@ class CovertSubmitter extends PrintError { slot.subMsg = subMsg; slot.done = false; - slot.t_submit= tStart; + slot.t_submit = tStart; var covConn = slot.covConn; if (covConn != null) { covConn.wakeup.complete(); } } - void scheduleSubmissions(DateTime tStart, List<dynamic> slotMessages) { // Convert to list (Dart does not have tuples) slotMessages = List.from(slotMessages); @@ -317,11 +306,11 @@ class CovertSubmitter extends PrintError { } } - - Future runConnection( - CovertConnection covConn, int connTime, double randDelay, int connectTimeout) async { + Future runConnection(CovertConnection covConn, int connTime, double randDelay, + int connectTimeout) async { // Main loop for connection thread - DateTime connDateTime = DateTime.fromMillisecondsSinceEpoch(connTime * 1000); + DateTime connDateTime = + DateTime.fromMillisecondsSinceEpoch(connTime * 1000); while (await covConn.waitWakeupOrTime(connDateTime)) { // if we are woken up before connection and stopping is happening, then just don't make a connection at all if (this.stopping) { @@ -350,11 +339,11 @@ class CovertSubmitter extends PrintError { try { final connection = await openConnection( this.destAddr!, this.destPort!, - connTimeout: connectTimeout.toDouble(), ssl: this.ssl, socksOpts: proxyOpts); + connTimeout: connectTimeout.toDouble(), + ssl: this.ssl, + socksOpts: proxyOpts); covConn.connection = connection; - } - - catch (e) { + } catch (e) { this.countFailed++; final tEnd = DateTime.now().millisecondsSinceEpoch; @@ -364,15 +353,13 @@ class CovertSubmitter extends PrintError { rethrow; } - - this.countEstablished++; + this.countEstablished++; final tEnd = DateTime.now().millisecondsSinceEpoch; print( '[${covConn.connNumber}] connection established after ${((tEnd - tBegin) / 1000).toStringAsFixed(3)}s'); - covConn.delay = (randTrap(this.rng) ?? 0) * (this.randSpan ?? 0); var lastActionTime = DateTime.now().millisecondsSinceEpoch; @@ -381,7 +368,7 @@ class CovertSubmitter extends PrintError { while (!this.stopping) { DateTime? nextTime; final slotNum = covConn.slotNum; - Function()? action; // callback to hold the action function + Function()? action; // callback to hold the action function // Second preference: submit something if (slotNum != null) { @@ -396,7 +383,8 @@ class CovertSubmitter extends PrintError { } // Last preference: wait doing nothing if (nextTime == null) { - nextTime = DateTime.now().add(Duration(seconds: TIMEOUT_INACTIVE_CONNECTION)); + nextTime = DateTime.now() + .add(Duration(seconds: TIMEOUT_INACTIVE_CONNECTION)); action = covConn.inactive; } @@ -423,7 +411,9 @@ class CovertSubmitter extends PrintError { // STATE 3 - stopping while (true) { - final stopTime = this.stopTStart?.add(Duration(seconds: randDelay.toInt())) ?? DateTime.now(); + final stopTime = + this.stopTStart?.add(Duration(seconds: randDelay.toInt())) ?? + DateTime.now(); if (!(await covConn.waitWakeupOrTime(stopTime))) { break; @@ -435,34 +425,33 @@ class CovertSubmitter extends PrintError { // in case of any problem, record the exception and if we have a slot, reassign it. final exception = e; - final slotNum = covConn.slotNum; - if (slotNum != null) { - try { - final spare = this.spareConnections.removeLast(); - // Found a spare. - this.slots[slotNum].covConn = spare; - spare.slotNum = slotNum; - spare.wakeup.complete(); // python code is using set, possibly dealing wiht multi thread...double check this is ok. + final slotNum = covConn.slotNum; + if (slotNum != null) { + try { + final spare = this.spareConnections.removeLast(); + // Found a spare. + this.slots[slotNum].covConn = spare; + spare.slotNum = slotNum; + spare.wakeup + .complete(); // python code is using set, possibly dealing wiht multi thread...double check this is ok. - covConn.slotNum = null; - } catch (e) { - // We failed, and there are no spares. Party is over! - - if (exception is Exception) { - this.stop(exception); - } else { - // Handle the case where the exception is not an instance of Exception - } + covConn.slotNum = null; + } catch (e) { + // We failed, and there are no spares. Party is over! + if (exception is Exception) { + this.stop(exception); + } else { + // Handle the case where the exception is not an instance of Exception } } + } } finally { covConn.connection?.close(); } } } - void checkOk() { // Implement checkOk logic here var e = this.failure_exception; @@ -474,26 +463,21 @@ class CovertSubmitter extends PrintError { void checkConnected() { // Implement checkConnected logic here this.checkOk(); - var numMissing = this.slots - .where((s) => s.covConn?.connection == null) - .length; + var numMissing = + this.slots.where((s) => s.covConn?.connection == null).length; if (numMissing > 0) { throw FusionError( - "Covert connections were too slow ($numMissing incomplete out of ${this - .slots.length})."); + "Covert connections were too slow ($numMissing incomplete out of ${this.slots.length})."); } } void checkDone() { // Implement checkDone logic here this.checkOk(); - var numMissing = this.slots - .where((s) => !s.done) - .length; + var numMissing = this.slots.where((s) => !s.done).length; if (numMissing > 0) { throw FusionError( - "Covert submissions were too slow ($numMissing incomplete out of ${this - .slots.length})."); + "Covert submissions were too slow ($numMissing incomplete out of ${this.slots.length})."); } } -} \ No newline at end of file +} diff --git a/lib/services/cashfusion/encrypt.dart b/lib/services/cashfusion/encrypt.dart index 39ab8a2c5..2a6e00a6b 100644 --- a/lib/services/cashfusion/encrypt.dart +++ b/lib/services/cashfusion/encrypt.dart @@ -1,17 +1,20 @@ -import 'dart:convert'; import 'dart:typed_data'; -import 'package:pointycastle/pointycastle.dart' hide Mac; + import 'package:crypto/crypto.dart' as crypto; import 'package:cryptography/cryptography.dart'; +import 'package:pointycastle/pointycastle.dart' hide Mac; + import 'util.dart'; final ECDomainParameters params = ECDomainParameters('secp256k1'); final BigInt order = params.n; class EncryptionFailed implements Exception {} + class DecryptionFailed implements Exception {} -Future<Uint8List> encrypt(Uint8List message, ECPoint pubkey, {int? padToLength}) async { +Future<Uint8List> encrypt(Uint8List message, ECPoint pubkey, + {int? padToLength}) async { ECPoint pubpoint; try { pubpoint = Util.ser_to_point(pubkey.getEncoded(true), params); @@ -27,22 +30,27 @@ Future<Uint8List> encrypt(Uint8List message, ECPoint pubkey, {int? padToLength}) var pubpoint_times_nonceSec = pubpoint * nonceSec; if (pubpoint_times_nonceSec == null) { - throw Exception('Multiplication of pubpoint with nonceSec resulted in null'); + throw Exception( + 'Multiplication of pubpoint with nonceSec resulted in null'); } - var key = crypto.sha256.convert(Util.point_to_ser(pubpoint_times_nonceSec, true)).bytes; + var key = crypto.sha256 + .convert(Util.point_to_ser(pubpoint_times_nonceSec, true)) + .bytes; - - - var plaintext = Uint8List(4 + message.length)..buffer.asByteData().setUint32(0, message.length, Endian.big)..setRange(4, 4 + message.length, message); + var plaintext = Uint8List(4 + message.length) + ..buffer.asByteData().setUint32(0, message.length, Endian.big) + ..setRange(4, 4 + message.length, message); if (padToLength == null) { - padToLength = ((plaintext.length + 15) ~/ 16) * 16; // round up to nearest 16 + padToLength = + ((plaintext.length + 15) ~/ 16) * 16; // round up to nearest 16 } else if (padToLength % 16 != 0) { throw ArgumentError('$padToLength not multiple of 16'); } if (padToLength < plaintext.length) { throw ArgumentError('$padToLength < ${plaintext.length}'); } - plaintext = Uint8List(padToLength)..setRange(0, message.length + 4, plaintext); + plaintext = Uint8List(padToLength) + ..setRange(0, message.length + 4, plaintext); final secretKey = SecretKey(key); @@ -50,16 +58,20 @@ Future<Uint8List> encrypt(Uint8List message, ECPoint pubkey, {int? padToLength}) final cipher = AesCbc.with128bits(macAlgorithm: macAlgorithm); - final nonce = Uint8List(16); // Random nonce - final secretBox = await cipher.encrypt(plaintext, secretKey: secretKey, nonce: nonce); + final secretBox = + await cipher.encrypt(plaintext, secretKey: secretKey, nonce: nonce); final ciphertext = secretBox.cipherText; - return Uint8List(noncePub.length + ciphertext.length + secretBox.mac.bytes.length) + return Uint8List( + noncePub.length + ciphertext.length + secretBox.mac.bytes.length) ..setRange(0, noncePub.length, noncePub) ..setRange(noncePub.length, noncePub.length + ciphertext.length, ciphertext) - ..setRange(noncePub.length + ciphertext.length, noncePub.length + ciphertext.length + secretBox.mac.bytes.length, secretBox.mac.bytes); + ..setRange( + noncePub.length + ciphertext.length, + noncePub.length + ciphertext.length + secretBox.mac.bytes.length, + secretBox.mac.bytes); } Future<Uint8List> decryptWithSymmkey(Uint8List data, Uint8List key) async { @@ -75,7 +87,8 @@ Future<Uint8List> decryptWithSymmkey(Uint8List data, Uint8List key) async { final cipher = AesCbc.with128bits(macAlgorithm: Hmac.sha256()); final nonce = Uint8List(16); // Random nonce - final secretBox = SecretBox(ciphertext, mac: Mac(data.sublist(data.length - 16)), nonce: nonce); + final secretBox = SecretBox(ciphertext, + mac: Mac(data.sublist(data.length - 16)), nonce: nonce); final plaintext = await cipher.decrypt(secretBox, secretKey: secretKey); if (plaintext.length < 4) { @@ -86,15 +99,14 @@ Future<Uint8List> decryptWithSymmkey(Uint8List data, Uint8List key) async { ByteData byteData = ByteData.sublistView(uint8list); var msgLength = byteData.getUint32(0, Endian.big); - if (msgLength + 4 > plaintext.length) { throw DecryptionFailed(); } return Uint8List.fromList(plaintext.sublist(4, 4 + msgLength)); - } -Future<Tuple<Uint8List, Uint8List>> decrypt(Uint8List data, ECPrivateKey privkey) async { +Future<Tuple<Uint8List, Uint8List>> decrypt( + Uint8List data, ECPrivateKey privkey) async { if (data.length < 33 + 16 + 16) { throw DecryptionFailed(); } @@ -122,4 +134,3 @@ Future<Tuple<Uint8List, Uint8List>> decrypt(Uint8List data, ECPrivateKey privkey var decryptedData = await decryptWithSymmkey(data, Uint8List.fromList(key)); return Tuple(decryptedData, Uint8List.fromList(key)); } - diff --git a/lib/services/cashfusion/fusion.dart b/lib/services/cashfusion/fusion.dart index bcb03ac5a..573e38d5c 100644 --- a/lib/services/cashfusion/fusion.dart +++ b/lib/services/cashfusion/fusion.dart @@ -1,27 +1,25 @@ -import 'socketwrapper.dart'; -import 'package:protobuf/protobuf.dart'; +import 'dart:async'; import 'dart:convert'; import 'dart:math'; -import 'fusion.pb.dart'; -import 'util.dart'; import 'dart:typed_data'; -import 'package:fixnum/fixnum.dart'; -import 'pedersen.dart'; -import 'dart:io'; -import 'package:crypto/crypto.dart'; -import 'dart:async'; -import 'comms.dart'; -import 'protocol.dart'; -import 'package:fixnum/fixnum.dart'; // so int and intt64 can be combined in some protobuff code -import 'encrypt.dart'; -import "package:pointycastle/export.dart"; -import 'covert.dart'; -import 'connection.dart'; + import 'package:collection/collection.dart'; -import 'package:convert/convert.dart'; -import 'validation.dart'; +import 'package:crypto/crypto.dart'; +import 'package:fixnum/fixnum.dart'; +import "package:pointycastle/export.dart"; +import 'package:protobuf/protobuf.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; +import 'comms.dart'; +import 'connection.dart'; +import 'covert.dart'; +import 'encrypt.dart'; +import 'fusion.pb.dart'; +import 'pedersen.dart'; +import 'protocol.dart'; +import 'socketwrapper.dart'; +import 'util.dart'; +import 'validation.dart'; class FusionError implements Exception { final String message; @@ -36,17 +34,11 @@ class ComponentResult { final Proof proof; final Uint8List privateKey; final dynamic pedersenAmount; // replace dynamic with actual type - final dynamic pedersenNonce; // replace dynamic with actual type + final dynamic pedersenNonce; // replace dynamic with actual type - ComponentResult( - this.commitment, - this.counter, - this.component, - this.proof, + ComponentResult(this.commitment, this.counter, this.component, this.proof, this.privateKey, - {this.pedersenAmount, - this.pedersenNonce} - ); + {this.pedersenAmount, this.pedersenNonce}); } class Transaction { @@ -55,8 +47,8 @@ class Transaction { Transaction(); - - static Tuple txFromComponents(List<dynamic> allComponents, List<dynamic> sessionHash) { + static Tuple txFromComponents( + List<dynamic> allComponents, List<dynamic> sessionHash) { Transaction tx = Transaction(); // Initialize a new Transaction // This should be based on wallet layer... implement the logic of constructing the transaction from components // For now, it just initializes Inputs and Outputs as empty lists @@ -91,18 +83,22 @@ class Transaction { } } - class Input { List<int> prevTxid; int prevIndex; List<int> pubKey; int amount; - List<dynamic> signatures =[]; + List<dynamic> signatures = []; - Input({required this.prevTxid, required this.prevIndex, required this.pubKey, required this.amount}); + Input( + {required this.prevTxid, + required this.prevIndex, + required this.pubKey, + required this.amount}); int sizeOfInput() { - assert(1 < pubKey.length && pubKey.length < 76); // need to assume regular push opcode + assert(1 < pubKey.length && + pubKey.length < 76); // need to assume regular push opcode return 108 + pubKey.length; } @@ -120,10 +116,9 @@ class Input { return ""; } - static Input fromInputComponent(InputComponent inputComponent) { return Input( - prevTxid: inputComponent.prevTxid, // Make sure the types are matching + prevTxid: inputComponent.prevTxid, // Make sure the types are matching prevIndex: inputComponent.prevIndex.toInt(), pubKey: inputComponent.pubkey, amount: inputComponent.amount.toInt(), @@ -138,21 +133,19 @@ class Input { amount: utxo.value, ); } - } - - class Output { int value; Address addr; - int amount=0; + int amount = 0; Output({required this.value, required this.addr}); int sizeOfOutput() { - List<int> scriptpubkey = addr.toScript(); // assuming addr.toScript() returns List<int> that represents the scriptpubkey + List<int> scriptpubkey = addr + .toScript(); // assuming addr.toScript() returns List<int> that represents the scriptpubkey assert(scriptpubkey.length < 253); return 9 + scriptpubkey.length; } @@ -164,23 +157,20 @@ class Output { addr: address, ); } - } - - // Class to handle fusion class Fusion { - - List<Input> coins = []; //"coins" and "inputs" are often synonmous in the original python code. - List<Output> outputs =[]; + List<Input> coins = + []; //"coins" and "inputs" are often synonmous in the original python code. + List<Output> outputs = []; bool server_connected_and_greeted = false; bool stopping = false; bool stopping_if_not_running = false; - String stopReason=""; - String tor_host=""; - bool server_ssl= false; - String server_host ="cashfusion.stackwallet.com"; + String stopReason = ""; + String tor_host = ""; + bool server_ssl = false; + String server_host = "cashfusion.stackwallet.com"; int server_port = 8787; //String server_host = "fusion.servo.cash"; @@ -188,21 +178,22 @@ class Fusion { int tor_port = 0; int roundcount = 0; - String txid=""; + String txid = ""; - Tuple<String, String> status = Tuple("", ""); + Tuple<String, String> status = Tuple("", ""); Connection? connection; - int numComponents =0; - double componentFeeRate=0; - double minExcessFee=0; - double maxExcessFee=0; - List<int> availableTiers =[]; + int numComponents = 0; + double componentFeeRate = 0; + double minExcessFee = 0; + double maxExcessFee = 0; + List<int> availableTiers = []; - int maxOutputs=0; - int safety_sum_in =0; + int maxOutputs = 0; + int safety_sum_in = 0; Map<int, int> safety_exess_fees = {}; - Map<int, List<int>> tierOutputs ={}; // not sure if this should be using outputs class. + Map<int, List<int>> tierOutputs = + {}; // not sure if this should be using outputs class. int inactiveTimeLimit = 0; int tier = 0; @@ -216,12 +207,12 @@ class Fusion { Uint8List covertDomainB = Uint8List(0); var txInputIndices; - Transaction tx= Transaction(); - List<int> myComponentIndexes=[]; - List<int> myCommitmentIndexes=[]; - Set<int> badComponents ={}; + Transaction tx = Transaction(); + List<int> myComponentIndexes = []; + List<int> myCommitmentIndexes = []; + Set<int> badComponents = {}; - Fusion () { + Fusion() { //initializeConnection(host, port) } /* @@ -239,59 +230,53 @@ class Fusion { } Future<void> fusion_run() async { - - print ("DEBUG FUSION 223...fusion run...."); + print("DEBUG FUSION 223...fusion run...."); try { - try { - // Check compatibility - This was done in python version to see if fast libsec installed. // For now , in dart, just pass this test. ; - } on Exception catch(e) { + } on Exception catch (e) { // handle exception, rethrow as a custom FusionError throw FusionError("Incompatible: " + e.toString()); } // Check if can connect to Tor proxy, if not, raise FusionError. Empty String treated as no host. - if (tor_host.isNotEmpty && tor_port != 0 && !await isTorPort(tor_host, tor_port)) { + if (tor_host.isNotEmpty && + tor_port != 0 && + !await isTorPort(tor_host, tor_port)) { throw FusionError("Can't connect to Tor proxy at $tor_host:$tor_port"); } try { // Check stop condition check_stop(running: false); - } - catch (e) { - print (e); + } catch (e) { + print(e); } try { // Check coins check_coins(); + } catch (e) { + print(e); } - catch (e) { - print (e); - } - - // Connect to server status = Tuple("connecting", ""); try { - connection = await openConnection(server_host, server_port, connTimeout: 5.0, defaultTimeout: 5.0, ssl: server_ssl); - } catch (e) { + connection = await openConnection(server_host, server_port, + connTimeout: 5.0, defaultTimeout: 5.0, ssl: server_ssl); + } catch (e) { print("Connect failed: $e"); String sslstr = server_ssl ? ' SSL ' : ''; - throw FusionError('Could not connect to $sslstr$server_host:$server_port'); + throw FusionError( + 'Could not connect to $sslstr$server_host:$server_port'); } - // Once connection is successful, wrap operations inside this block // Within this block, version checks, downloads server params, handles coins and runs rounds try { - - SocketWrapper socketwrapper = SocketWrapper(server_host, server_port); await socketwrapper.connect(); @@ -309,8 +294,7 @@ class Fusion { throw FusionError('Started with no coins'); return; } - } - catch (e) { + } catch (e) { print(e); return; } @@ -321,12 +305,10 @@ class Fusion { // Register for tiers, wait for a pool. await registerAndWait(socketwrapper); - - print ("FUSION DEBUG 273"); - print ("RETURNING early in fusion_run...."); + print("FUSION DEBUG 273"); + print("RETURNING early in fusion_run...."); return; - // launch the covert submitter CovertSubmitter covert = await start_covert(); try { @@ -361,15 +343,15 @@ class Fusion { // Wait for transaction to show up in wallets // Set status to 'complete' with txid - - } on FusionError catch(err) { + } on FusionError catch (err) { print('Failed: ${err}'); status.item1 = "failed"; - status.item2 = err.toString(); // setting the error message - } catch(exc) { + status.item2 = err.toString(); // setting the error message + } catch (exc) { print('Exception: ${exc}'); status.item1 = "failed"; - status.item2= "Exception: ${exc.toString()}"; // setting the exception message + status.item2 = + "Exception: ${exc.toString()}"; // setting the exception message } finally { clear_coins(); if (status.item1 != 'complete') { @@ -381,22 +363,15 @@ class Fusion { } } } - - - } // end fusion_run function. - - - - + } // end fusion_run function. Future<CovertSubmitter> start_covert() async { // Function implementation here... // For now, just return a new instance of CovertSubmitter - return CovertSubmitter("dummy",0,true,"some_host",0,0,0,0); + return CovertSubmitter("dummy", 0, true, "some_host", 0, 0, 0, 0); } - Future<bool> run_round(CovertSubmitter covert) async { // function implementation here... @@ -408,7 +383,6 @@ class Fusion { // Function implementation goes here } - void stop([String reason = 'stopped', bool notIfRunning = false]) { if (stopping) { return; @@ -433,18 +407,18 @@ class Fusion { } } -void check_coins() { + void check_coins() { // Implement by calling wallet layer to check the coins are ok. return; -} + } static void foo() { -print ("hello"); -} + print("hello"); + } - void clear_coins() { + void clear_coins() { coins = []; - } + } void addCoins(List<Input> newCoins) { coins.addAll(newCoins); @@ -454,35 +428,36 @@ print ("hello"); return; } -static bool walletCanFuse() { - return true; + static bool walletCanFuse() { + return true; - // Implement logic here to return false if the wallet can't fuse. (If its read only or non P2PKH) -} - -static double nextDoubleNonZero(Random rng) { - double value = 0.0; - while (value == 0.0) { - value = rng.nextDouble(); + // Implement logic here to return false if the wallet can't fuse. (If its read only or non P2PKH) } - return value; -} - static List<int>? randomOutputsForTier(Random rng, int inputAmount, int scale, int offset, int maxCount) { + static double nextDoubleNonZero(Random rng) { + double value = 0.0; + while (value == 0.0) { + value = rng.nextDouble(); + } + return value; + } + static List<int>? randomOutputsForTier( + Random rng, int inputAmount, int scale, int offset, int maxCount) { if (inputAmount < offset) { return []; } double lambd = 1.0 / scale; int remaining = inputAmount; - List<double> values = []; // list of fractional random values without offset - bool didBreak = false; // Add this flag to detect when a break is encountered + List<double> values = []; // list of fractional random values without offset + bool didBreak = + false; // Add this flag to detect when a break is encountered for (int i = 0; i < maxCount + 1; i++) { double val = -lambd * log(nextDoubleNonZero(rng)); remaining -= (val.ceil() + offset); if (remaining < 0) { - didBreak = true; // If you break, set this flag to true + didBreak = true; // If you break, set this flag to true break; } values.add(val); @@ -516,120 +491,115 @@ static double nextDoubleNonZero(Random rng) { double rescale = desiredRandomSum / cumsum[cumsum.length - 1]; List<int> normedCumsum = cumsum.map((v) => (rescale * v).round()).toList(); - assert(normedCumsum[normedCumsum.length - 1] == desiredRandomSum, 'Last element of normedCumsum is not equal to desiredRandomSum'); + assert(normedCumsum[normedCumsum.length - 1] == desiredRandomSum, + 'Last element of normedCumsum is not equal to desiredRandomSum'); List<int> differences = []; - differences.add(normedCumsum[0]); // First element + differences.add(normedCumsum[0]); // First element for (int i = 1; i < normedCumsum.length; i++) { differences.add(normedCumsum[i] - normedCumsum[i - 1]); } List<int> result = differences.map((d) => offset + d).toList(); - assert(result.reduce((a, b) => a + b) == inputAmount, 'Sum of result is not equal to inputAmount'); + assert(result.reduce((a, b) => a + b) == inputAmount, + 'Sum of result is not equal to inputAmount'); return result; - } + static List<ComponentResult> genComponents( + int numBlanks, List<Input> inputs, List<Output> outputs, int feerate) { + assert(numBlanks >= 0); - static List<ComponentResult> genComponents(int numBlanks, List<Input> inputs, List<Output> outputs, int feerate) { - assert(numBlanks >= 0); + List<Tuple<Component, int>> components = []; - List<Tuple<Component, int>> components = []; + // Set up Pedersen setup instance + Uint8List HBytes = Uint8List.fromList( + [0x02] + 'CashFusion gives us fungibility.'.codeUnits); + ECDomainParameters params = ECDomainParameters('secp256k1'); + ECPoint? HMaybe = params.curve.decodePoint(HBytes); + if (HMaybe == null) { + throw Exception('Failed to decode point'); + } + ECPoint H = HMaybe; + PedersenSetup setup = PedersenSetup(H); - // Set up Pedersen setup instance - Uint8List HBytes = Uint8List.fromList([0x02] + 'CashFusion gives us fungibility.'.codeUnits); - ECDomainParameters params = ECDomainParameters('secp256k1'); - ECPoint? HMaybe = params.curve.decodePoint(HBytes); - if (HMaybe == null) { - throw Exception('Failed to decode point'); - } - ECPoint H = HMaybe; - PedersenSetup setup = PedersenSetup(H); + for (Input input in inputs) { + int fee = Util.componentFee(input.sizeOfInput(), feerate); - for (Input input in inputs) { - int fee = Util.componentFee(input.sizeOfInput(), feerate); + var comp = Component(); + comp.input = InputComponent( + prevTxid: Uint8List.fromList(input.prevTxid.reversed.toList()), + prevIndex: input.prevIndex, + pubkey: input.pubKey, + amount: Int64(input.amount)); + components.add(Tuple<Component, int>(comp, input.amount - fee)); + } - var comp = Component(); - comp.input = InputComponent( - prevTxid: Uint8List.fromList(input.prevTxid.reversed.toList()), - prevIndex: input.prevIndex, - pubkey: input.pubKey, - amount: Int64(input.amount) - ); - components.add(Tuple<Component, int>(comp, input.amount - fee)); - } + for (Output output in outputs) { + var script = output.addr.toScript(); + int fee = Util.componentFee(output.sizeOfOutput(), feerate); - for (Output output in outputs) { - var script = output.addr.toScript(); - int fee = Util.componentFee(output.sizeOfOutput(), feerate); + var comp = Component(); + comp.output = + OutputComponent(scriptpubkey: script, amount: Int64(output.value)); + components.add(Tuple<Component, int>(comp, -output.value - fee)); + } - var comp = Component(); - comp.output = OutputComponent( - scriptpubkey: script, - amount: Int64(output.value) - ); - components.add(Tuple<Component, int>(comp, -output.value - fee)); - } + for (int i = 0; i < numBlanks; i++) { + var comp = Component(); + comp.blank = BlankComponent(); + components.add(Tuple<Component, int>(comp, 0)); + } - for (int i = 0; i < numBlanks; i++) { - var comp = Component(); - comp.blank = BlankComponent(); - components.add(Tuple<Component, int>(comp, 0)); - } + List<ComponentResult> resultList = []; - List<ComponentResult> resultList = []; + components.asMap().forEach((cnum, Tuple<Component, int> componentTuple) { + Uint8List salt = Util.tokenBytes(32); + componentTuple.item1.saltCommitment = Util.sha256(salt); + var compser = componentTuple.item1.writeToBuffer(); - components.asMap().forEach((cnum, Tuple<Component, int> componentTuple) { - Uint8List salt = Util.tokenBytes(32); - componentTuple.item1.saltCommitment = Util.sha256(salt); - var compser = componentTuple.item1.writeToBuffer(); - - Tuple<Uint8List, Uint8List> keyPair = Util.genKeypair(); - Uint8List privateKey = keyPair.item1; - Uint8List pubKey = keyPair.item2; - - Commitment commitmentInstance = setup.commit(BigInt.from(componentTuple.item2)); - Uint8List amountCommitment = commitmentInstance.PUncompressed; + Tuple<Uint8List, Uint8List> keyPair = Util.genKeypair(); + Uint8List privateKey = keyPair.item1; + Uint8List pubKey = keyPair.item2; + Commitment commitmentInstance = + setup.commit(BigInt.from(componentTuple.item2)); + Uint8List amountCommitment = commitmentInstance.PUncompressed; // Convert BigInt nonce to Uint8List - Uint8List pedersenNonce = Uint8List.fromList([int.parse(commitmentInstance.nonce.toRadixString(16), radix: 16)]); + Uint8List pedersenNonce = Uint8List.fromList( + [int.parse(commitmentInstance.nonce.toRadixString(16), radix: 16)]); // Generating initial commitment - InitialCommitment commitment = InitialCommitment( - saltedComponentHash: Util.sha256(Uint8List.fromList([...compser, ...salt])), - amountCommitment: amountCommitment, - communicationKey: pubKey - ); + InitialCommitment commitment = InitialCommitment( + saltedComponentHash: + Util.sha256(Uint8List.fromList([...compser, ...salt])), + amountCommitment: amountCommitment, + communicationKey: pubKey); - Uint8List commitser = commitment.writeToBuffer(); + Uint8List commitser = commitment.writeToBuffer(); - // Generating proof - Proof proof = Proof( - componentIdx: cnum, - salt: salt, - pedersenNonce: pedersenNonce - ); + // Generating proof + Proof proof = + Proof(componentIdx: cnum, salt: salt, pedersenNonce: pedersenNonce); - // Adding result to list - resultList.add(ComponentResult(commitser, cnum, compser, proof, privateKey)); - }); + // Adding result to list + resultList + .add(ComponentResult(commitser, cnum, compser, proof, privateKey)); + }); - return resultList; -} + return resultList; + } - - Future<GeneratedMessage> recv2(SocketWrapper socketwrapper, List<String> expectedMsgNames, {Duration? timeout}) async { + Future<GeneratedMessage> recv2( + SocketWrapper socketwrapper, List<String> expectedMsgNames, + {Duration? timeout}) async { if (connection == null) { throw FusionError('Connection not initialized'); } var result = await recvPb2( - socketwrapper, - connection!, - ServerMessage, - expectedMsgNames, - timeout: timeout - ); + socketwrapper, connection!, ServerMessage, expectedMsgNames, + timeout: timeout); var submsg = result.item1; var mtype = result.item2; @@ -641,20 +611,15 @@ static double nextDoubleNonZero(Random rng) { return submsg; } - - - Future<GeneratedMessage> recv(List<String> expectedMsgNames, {Duration? timeout}) async { + Future<GeneratedMessage> recv(List<String> expectedMsgNames, + {Duration? timeout}) async { // DEPRECATED if (connection == null) { throw FusionError('Connection not initialized'); } - var result = await recvPb( - connection!, - ServerMessage, - expectedMsgNames, - timeout: timeout - ); + var result = await recvPb(connection!, ServerMessage, expectedMsgNames, + timeout: timeout); var submsg = result.item1; var mtype = result.item2; @@ -666,7 +631,6 @@ static double nextDoubleNonZero(Random rng) { return submsg; } - Future<void> send(GeneratedMessage submsg, {Duration? timeout}) async { // DEPRECATED if (connection != null) { @@ -674,18 +638,16 @@ static double nextDoubleNonZero(Random rng) { } else { print('Connection is null'); } - } - - Future<void> send2(SocketWrapper socketwrapper, GeneratedMessage submsg, {Duration? timeout}) async { - + Future<void> send2(SocketWrapper socketwrapper, GeneratedMessage submsg, + {Duration? timeout}) async { if (connection != null) { - await sendPb2(socketwrapper, connection!, ClientMessage, submsg, timeout: timeout); + await sendPb2(socketwrapper, connection!, ClientMessage, submsg, + timeout: timeout); } else { print('Connection is null'); } - } Future<void> greet(SocketWrapper socketwrapper) async { @@ -693,8 +655,7 @@ static double nextDoubleNonZero(Random rng) { version: Uint8List.fromList(utf8.encode(Protocol.VERSION)), genesisHash: Util.get_current_genesis_hash()); - ClientMessage clientMessage = ClientMessage() - ..clienthello = clientHello; + ClientMessage clientMessage = ClientMessage()..clienthello = clientHello; //deprecated //Connection greet_connection_1 = Connection.withoutSocket(); @@ -704,42 +665,42 @@ static double nextDoubleNonZero(Random rng) { SocketWrapper socketwrapper = SocketWrapper(server_host, server_port); await socketwrapper.connect(); */ - send2(socketwrapper,clientMessage); - + send2(socketwrapper, clientMessage); var replyMsg = await recv2(socketwrapper, ['serverhello']); if (replyMsg is ServerMessage) { - ServerHello reply = replyMsg.serverhello; + ServerHello reply = replyMsg.serverhello; - numComponents = reply.numComponents; - componentFeeRate = reply.componentFeerate.toDouble(); - minExcessFee = reply.minExcessFee.toDouble(); - maxExcessFee = reply.maxExcessFee.toDouble(); - availableTiers = reply.tiers.map((tier) => tier.toInt()).toList(); + numComponents = reply.numComponents; + componentFeeRate = reply.componentFeerate.toDouble(); + minExcessFee = reply.minExcessFee.toDouble(); + maxExcessFee = reply.maxExcessFee.toDouble(); + availableTiers = reply.tiers.map((tier) => tier.toInt()).toList(); - // Enforce some sensible limits, in case server is crazy - if (componentFeeRate > Protocol.MAX_COMPONENT_FEERATE) { - throw FusionError('excessive component feerate from server'); - } - if (minExcessFee > 400) { // note this threshold should be far below MAX_EXCESS_FEE - throw FusionError('excessive min excess fee from server'); - } - if (minExcessFee > maxExcessFee) { - throw FusionError('bad config on server: fees'); - } - if (numComponents < Protocol.MIN_TX_COMPONENTS * 1.5) { - throw FusionError('bad config on server: num_components'); - } + // Enforce some sensible limits, in case server is crazy + if (componentFeeRate > Protocol.MAX_COMPONENT_FEERATE) { + throw FusionError('excessive component feerate from server'); + } + if (minExcessFee > 400) { + // note this threshold should be far below MAX_EXCESS_FEE + throw FusionError('excessive min excess fee from server'); + } + if (minExcessFee > maxExcessFee) { + throw FusionError('bad config on server: fees'); + } + if (numComponents < Protocol.MIN_TX_COMPONENTS * 1.5) { + throw FusionError('bad config on server: num_components'); + } } else { - throw Exception('Received unexpected message type: ${replyMsg.runtimeType}'); + throw Exception( + 'Received unexpected message type: ${replyMsg.runtimeType}'); } } - Future<void> allocateOutputs(socketwrapper) async { - print ("DBUG allocateoutputs 746"); + print("DBUG allocateoutputs 746"); - print ("CHECK socketwrapper 746"); + print("CHECK socketwrapper 746"); socketwrapper.status(); assert(['setup', 'connecting'].contains(status.item1)); @@ -760,12 +721,15 @@ static double nextDoubleNonZero(Random rng) { int numDistinct = inputs.map((e) => e.value).toSet().length; int minOutputs = max(Protocol.MIN_TX_COMPONENTS - numDistinct, 1); if (maxOutputs < minOutputs) { - throw FusionError('Too few distinct inputs selected ($numDistinct); cannot satisfy output count constraint (>= $minOutputs, <= $maxOutputs)'); + throw FusionError( + 'Too few distinct inputs selected ($numDistinct); cannot satisfy output count constraint (>= $minOutputs, <= $maxOutputs)'); } - int sumInputsValue = inputs.map((e) => e.value).reduce((a, b) => a + b); - int inputFees = inputs.map((e) => Util.componentFee(e.sizeOfInput(), componentFeeRate.toInt())).reduce((a, b) => a + b); + int inputFees = inputs + .map( + (e) => Util.componentFee(e.sizeOfInput(), componentFeeRate.toInt())) + .reduce((a, b) => a + b); int availForOutputs = sumInputsValue - inputFees - minExcessFee.toInt(); int feePerOutput = Util.componentFee(34, componentFeeRate.toInt()); @@ -779,12 +743,15 @@ static double nextDoubleNonZero(Random rng) { var rng = Random(); var seed = List<int>.generate(32, (_) => rng.nextInt(256)); - print ("DBUG allocateoutputs 785"); + print("DBUG allocateoutputs 785"); tierOutputs = {}; var excessFees = <int, int>{}; for (var scale in availableTiers) { int fuzzFeeMax = scale ~/ 1000000; - int fuzzFeeMaxReduced = min(fuzzFeeMax, min(Protocol.MAX_EXCESS_FEE - minExcessFee.toInt(), maxExcessFee.toInt())); + int fuzzFeeMaxReduced = min( + fuzzFeeMax, + min(Protocol.MAX_EXCESS_FEE - minExcessFee.toInt(), + maxExcessFee.toInt())); assert(fuzzFeeMaxReduced >= 0); int fuzzFee = rng.nextInt(fuzzFeeMaxReduced + 1); @@ -794,13 +761,12 @@ static double nextDoubleNonZero(Random rng) { continue; } - var outputs = randomOutputsForTier(rng, reducedAvailForOutputs, scale, offsetPerOutput, maxOutputs); + var outputs = randomOutputsForTier( + rng, reducedAvailForOutputs, scale, offsetPerOutput, maxOutputs); if (outputs != null) { - print (outputs); + print(outputs); } if (outputs == null || outputs.length < minOutputs) { - - continue; } outputs = outputs.map((o) => o - feePerOutput).toList(); @@ -811,20 +777,16 @@ static double nextDoubleNonZero(Random rng) { tierOutputs[scale] = outputs!; } - print('Possible tiers: $tierOutputs'); - print ("CHECK socketwrapper 839"); + print("CHECK socketwrapper 839"); socketwrapper.status(); safety_sum_in = sumInputsValue; safety_exess_fees = excessFees; return; } - - Future<void> registerAndWait(SocketWrapper socketwrapper) async { - // msg can be different classes depending on which protobuf msg is sent. dynamic? msg; @@ -832,44 +794,44 @@ static double nextDoubleNonZero(Random rng) { var tiersSorted = tierOutputs.keys.toList()..sort(); if (tierOutputs.isEmpty) { - throw FusionError('No outputs available at any tier (selected inputs were too small / too large).'); + throw FusionError( + 'No outputs available at any tier (selected inputs were too small / too large).'); } print('registering for tiers: $tiersSorted'); - int self_fuse = 1; // Temporary value for now - var cashfusionTag = [1];// temp value for now - - + int self_fuse = 1; // Temporary value for now + var cashfusionTag = [1]; // temp value for now check_stop(running: false); check_coins(); - var tags = [JoinPools_PoolTag(id: cashfusionTag, limit: self_fuse)]; // Create JoinPools message - JoinPools joinPools = JoinPools( - tiers: tiersSorted.map((i) => Int64(i)).toList(), - tags: tags - ); + JoinPools joinPools = + JoinPools(tiers: tiersSorted.map((i) => Int64(i)).toList(), tags: tags); // Wrap it in a ClientMessage - ClientMessage clientMessage = ClientMessage() - ..joinpools = joinPools; + ClientMessage clientMessage = ClientMessage()..joinpools = joinPools; send2(socketwrapper, clientMessage); - status = Tuple<String, String>('waiting', 'Registered for tiers'); - var tiersStrings = {for (var entry in tierOutputs.entries) entry.key: (entry.key * 1e-8).toStringAsFixed(8).replaceAll(RegExp(r'0+$'), '')}; + var tiersStrings = { + for (var entry in tierOutputs.entries) + entry.key: + (entry.key * 1e-8).toStringAsFixed(8).replaceAll(RegExp(r'0+$'), '') + }; while (true) { - var msg = await recv2(socketwrapper,['tierstatusupdate', 'fusionbegin'], timeout: Duration(seconds: 10)); + var msg = await recv2(socketwrapper, ['tierstatusupdate', 'fusionbegin'], + timeout: Duration(seconds: 10)); var fieldInfoFusionBegin = msg.info_.byName["fusionbegin"]; - if (fieldInfoFusionBegin != null && msg.hasField(fieldInfoFusionBegin.tagNumber)) { + if (fieldInfoFusionBegin != null && + msg.hasField(fieldInfoFusionBegin.tagNumber)) { break; } @@ -878,16 +840,14 @@ static double nextDoubleNonZero(Random rng) { // Define the bool variable - - var fieldInfo = msg.info_.byName["tierstatusupdate"]; if (fieldInfo == null) { - throw FusionError('Expected field not found in message: tierstatusupdate'); + throw FusionError( + 'Expected field not found in message: tierstatusupdate'); } bool messageIsTierStatusUpdate = msg.hasField(fieldInfo.tagNumber); - if (!messageIsTierStatusUpdate) { throw FusionError('Expected a TierStatusUpdate message'); } @@ -895,11 +855,11 @@ static double nextDoubleNonZero(Random rng) { late var statuses; if (messageIsTierStatusUpdate) { //TierStatusUpdate tierStatusUpdate = msg.tierstatusupdate; - var tierStatusUpdate = msg.getField(fieldInfo.tagNumber) as TierStatusUpdate; + var tierStatusUpdate = + msg.getField(fieldInfo.tagNumber) as TierStatusUpdate; statuses = tierStatusUpdate.statuses; } - double maxfraction = 0.0; var maxtiers = <int>[]; int? besttime; @@ -929,7 +889,8 @@ static double nextDoubleNonZero(Random rng) { if (statuses.containsKey(tier)) { var tierStr = tiersStrings[tier]; if (tierStr == null) { - throw FusionError('server reported status on tier we are not registered for'); + throw FusionError( + 'server reported status on tier we are not registered for'); } if (tier == besttimetier) { displayBest.insert(0, '**$tierStr**'); @@ -959,11 +920,14 @@ static double nextDoubleNonZero(Random rng) { } if (besttime != null) { - status = Tuple<String, String>('waiting', 'Starting in ${besttime}s. $tiersString'); + status = Tuple<String, String>( + 'waiting', 'Starting in ${besttime}s. $tiersString'); } else if (maxfraction >= 1) { - status = Tuple<String, String>('waiting', 'Starting soon. $tiersString'); + status = + Tuple<String, String>('waiting', 'Starting soon. $tiersString'); } else if (displayBest.isNotEmpty || displayMid.isNotEmpty) { - status = Tuple<String, String>('waiting', '${(maxfraction * 100).round()}% full. $tiersString'); + status = Tuple<String, String>( + 'waiting', '${(maxfraction * 100).round()}% full. $tiersString'); } else { status = Tuple<String, String>('waiting', tiersString); } @@ -979,15 +943,13 @@ static double nextDoubleNonZero(Random rng) { throw FusionError('Expected a FusionBegin message'); } + t_fusionBegin = DateTime.now(); - - - t_fusionBegin = DateTime.now(); - - - var clockMismatch = msg.serverTime - DateTime.now().millisecondsSinceEpoch / 1000; + var clockMismatch = + msg.serverTime - DateTime.now().millisecondsSinceEpoch / 1000; if (clockMismatch.abs() > Protocol.MAX_CLOCK_DISCREPANCY) { - throw FusionError("Clock mismatch too large: ${clockMismatch.toStringAsFixed(3)}."); + throw FusionError( + "Clock mismatch too large: ${clockMismatch.toStringAsFixed(3)}."); } tier = msg.tier; @@ -999,17 +961,21 @@ static double nextDoubleNonZero(Random rng) { covertSSL = msg.covertSSL; beginTime = msg.serverTime; - lastHash = Util.calcInitialHash(tier, covertDomainB, covertPort, covertSSL, beginTime); + lastHash = Util.calcInitialHash( + tier, covertDomainB, covertPort, covertSSL, beginTime); var outAmounts = tierOutputs[tier]; var outAddrs = Util.reserve_change_addresses(outAmounts?.length ?? 0); reservedAddresses = outAddrs; - outputs = Util.zip(outAmounts ?? [], outAddrs).map((pair) => Output(value: pair[0], addr: pair[1])).toList(); + outputs = Util.zip(outAmounts ?? [], outAddrs) + .map((pair) => Output(value: pair[0], addr: pair[1])) + .toList(); safetyExcessFee = safety_exess_fees[tier] ?? 0; - print("starting fusion rounds at tier $tier: ${coins.length} inputs and ${outputs.length} outputs"); + print( + "starting fusion rounds at tier $tier: ${coins.length} inputs and ${outputs.length} outputs"); } Future<CovertSubmitter> startCovert() async { @@ -1029,27 +995,27 @@ static double nextDoubleNonZero(Random rng) { tor_port, numComponents, Protocol.COVERT_SUBMIT_WINDOW, - Protocol.COVERT_SUBMIT_TIMEOUT - ); + Protocol.COVERT_SUBMIT_TIMEOUT); try { - covert.scheduleConnections( - t_fusionBegin, + covert.scheduleConnections(t_fusionBegin, Duration(seconds: Protocol.COVERT_CONNECT_WINDOW.toInt()), numSpares: Protocol.COVERT_CONNECT_SPARES.toInt(), - connectTimeout: Protocol.COVERT_CONNECT_TIMEOUT.toInt() - ); - + connectTimeout: Protocol.COVERT_CONNECT_TIMEOUT.toInt()); // loop until a just a bit before we're expecting startRound, watching for status updates - final tend = t_fusionBegin.add(Duration(seconds: (Protocol.WARMUP_TIME - Protocol.WARMUP_SLOP - 1).round())); + final tend = t_fusionBegin.add(Duration( + seconds: (Protocol.WARMUP_TIME - Protocol.WARMUP_SLOP - 1).round())); - while (DateTime.now().millisecondsSinceEpoch / 1000 < tend.millisecondsSinceEpoch / 1000) { + while (DateTime.now().millisecondsSinceEpoch / 1000 < + tend.millisecondsSinceEpoch / 1000) { + int numConnected = + covert.slots.where((s) => s.covConn?.connection != null).length; - int numConnected = covert.slots.where((s) => s.covConn?.connection != null).length; + int numSpareConnected = + covert.spareConnections.where((c) => c.connection != null).length; - int numSpareConnected = covert.spareConnections.where((c) => c.connection != null).length; - - status = Tuple('running', 'Setting up Tor connections ($numConnected+$numSpareConnected out of $numComponents)'); + status = Tuple('running', + 'Setting up Tor connections ($numConnected+$numSpareConnected out of $numComponents)'); await Future.delayed(Duration(seconds: 1)); @@ -1065,37 +1031,48 @@ static double nextDoubleNonZero(Random rng) { return covert; } - void runRound(CovertSubmitter covert) async { status = Tuple('running', 'Starting round ${roundcount.toString()}'); - int timeoutInSeconds = (2 * Protocol.WARMUP_SLOP + Protocol.STANDARD_TIMEOUT).toInt(); - var msg = await recv(['startround'], timeout: Duration(seconds: timeoutInSeconds)); + int timeoutInSeconds = + (2 * Protocol.WARMUP_SLOP + Protocol.STANDARD_TIMEOUT).toInt(); + var msg = await recv(['startround'], + timeout: Duration(seconds: timeoutInSeconds)); // Record the time we got this message; it forms the basis time for all covert activities. final covertT0 = DateTime.now().millisecondsSinceEpoch / 1000; - double covertClock() => (DateTime.now().millisecondsSinceEpoch / 1000) - covertT0; + double covertClock() => + (DateTime.now().millisecondsSinceEpoch / 1000) - covertT0; final roundTime = (msg as StartRound).serverTime; // Check the server's declared unix time, which will be committed. - final clockMismatch = (msg as StartRound).serverTime - DateTime.now().millisecondsSinceEpoch / 1000; + final clockMismatch = (msg as StartRound).serverTime - + DateTime.now().millisecondsSinceEpoch / 1000; if (clockMismatch.abs() > Protocol.MAX_CLOCK_DISCREPANCY) { - throw FusionError("Clock mismatch too large: ${clockMismatch.toInt().toStringAsPrecision(3)}."); + throw FusionError( + "Clock mismatch too large: ${clockMismatch.toInt().toStringAsPrecision(3)}."); } if (t_fusionBegin != null) { // On the first startround message, check that the warmup time was within acceptable bounds. - final lag = covertT0 - (t_fusionBegin.millisecondsSinceEpoch / 1000) - Protocol.WARMUP_TIME; + final lag = covertT0 - + (t_fusionBegin.millisecondsSinceEpoch / 1000) - + Protocol.WARMUP_TIME; if (lag.abs() > Protocol.WARMUP_SLOP) { - throw FusionError("Warmup period too different from expectation (|${lag.toStringAsFixed(3)}s| > ${Protocol.WARMUP_SLOP.toStringAsFixed(3)}s)."); + throw FusionError( + "Warmup period too different from expectation (|${lag.toStringAsFixed(3)}s| > ${Protocol.WARMUP_SLOP.toStringAsFixed(3)}s)."); } t_fusionBegin = DateTime.now(); } print("round starting at ${DateTime.now().millisecondsSinceEpoch / 1000}"); - final inputFees = coins.map((e) => Util.componentFee(e.sizeOfInput(), componentFeeRate.toInt())).reduce((a, b) => a + b); - final outputFees = outputs.length * Util.componentFee(34, componentFeeRate.toInt()); + final inputFees = coins + .map( + (e) => Util.componentFee(e.sizeOfInput(), componentFeeRate.toInt())) + .reduce((a, b) => a + b); + final outputFees = + outputs.length * Util.componentFee(34, componentFeeRate.toInt()); final sumIn = coins.map((e) => e.amount).reduce((a, b) => a + b); final sumOut = outputs.map((e) => e.value).reduce((a, b) => a + b); @@ -1110,7 +1087,8 @@ static double nextDoubleNonZero(Random rng) { ]; if (!safeties.every((element) => element)) { - throw Exception("(BUG!) Funds re-check failed -- aborting for safety. ${safeties.toString()}"); + throw Exception( + "(BUG!) Funds re-check failed -- aborting for safety. ${safeties.toString()}"); } final roundPubKey = (msg as StartRound).roundPubkey; @@ -1121,15 +1099,18 @@ static double nextDoubleNonZero(Random rng) { } final numBlanks = numComponents - coins.length - outputs.length; - final List<ComponentResult> genComponentsResults = genComponents(numBlanks, coins, outputs, componentFeeRate.toInt()); + final List<ComponentResult> genComponentsResults = + genComponents(numBlanks, coins, outputs, componentFeeRate.toInt()); final List<Uint8List> myCommitments = []; final List<int> myComponentSlots = []; final List<Uint8List> myComponents = []; final List<Proof> myProofs = []; final List<Uint8List> privKeys = []; - final List<dynamic> pedersenAmount = []; // replace dynamic with the actual type - final List<dynamic> pedersenNonce = []; // replace dynamic with the actual type + final List<dynamic> pedersenAmount = + []; // replace dynamic with the actual type + final List<dynamic> pedersenNonce = + []; // replace dynamic with the actual type for (var genComponentResult in genComponentsResults) { myCommitments.add(genComponentResult.commitment); @@ -1140,7 +1121,9 @@ static double nextDoubleNonZero(Random rng) { pedersenAmount.add(genComponentResult.pedersenAmount); pedersenNonce.add(genComponentResult.pedersenNonce); } - assert(excessFee == pedersenAmount.reduce((a, b) => a + b)); // sanity check that we didn't mess up the above + assert(excessFee == + pedersenAmount.reduce( + (a, b) => a + b)); // sanity check that we didn't mess up the above assert(myComponents.toSet().length == myComponents.length); // no duplicates // Need to implement this! schnorr is from EC schnorr.py @@ -1155,18 +1138,17 @@ static double nextDoubleNonZero(Random rng) { check_stop(); check_coins(); - await send(PlayerCommit( initialCommitments: myCommitments, excessFee: Int64(excessFee), pedersenTotalNonce: pedersenNonce.cast<int>(), randomNumberCommitment: sha256.convert(randomNumber).bytes, - blindSigRequests: blindSigRequests.map((r) => r.getRequest() as List<int>).toList(), + blindSigRequests: + blindSigRequests.map((r) => r.getRequest() as List<int>).toList(), )); - - msg = await recv(['blindsigresponses'], timeout: Duration(seconds: Protocol.T_START_COMPS.toInt())); - + msg = await recv(['blindsigresponses'], + timeout: Duration(seconds: Protocol.T_START_COMPS.toInt())); if (msg is BlindSigResponses) { var typedMsg = msg as BlindSigResponses; @@ -1178,10 +1160,11 @@ static double nextDoubleNonZero(Random rng) { final blindSigs = List.generate( blindSigRequests.length, - (index) { + (index) { if (msg is BlindSigResponses) { var typedMsg = msg as BlindSigResponses; - return blindSigRequests[index].finalize(typedMsg.scalars[index], check: true); + return blindSigRequests[index] + .finalize(typedMsg.scalars[index], check: true); } else { // Handle the case where msg is not of type BlindSigResponses throw Exception('Unexpected message type: ${msg.runtimeType}'); @@ -1189,7 +1172,6 @@ static double nextDoubleNonZero(Random rng) { }, ); - // Sleep until the covert component phase really starts, to catch covert connection failures. var remainingTime = Protocol.T_START_COMPS - covertClock(); if (remainingTime < 0) { @@ -1214,7 +1196,6 @@ static double nextDoubleNonZero(Random rng) { // provided our input components then it would be a leak to have them all drop at once. covert.setStopTime((covertT0 + Protocol.T_START_CLOSE).toInt()); - // Schedule covert submissions. List<CovertComponent?> messages = List.filled(myComponents.length, null); @@ -1222,34 +1203,35 @@ static double nextDoubleNonZero(Random rng) { messages[myComponentSlots[i]] = CovertComponent( roundPubkey: roundPubKey, signature: blindSigs[i], - component: myComponents[i] - ); + component: myComponents[i]); } if (messages.any((element) => element == null)) { throw FusionError('Messages list includes null values.'); } - final targetDateTime = DateTime.fromMillisecondsSinceEpoch(((covertT0 + Protocol.T_START_COMPS) * 1000).toInt()); + final targetDateTime = DateTime.fromMillisecondsSinceEpoch( + ((covertT0 + Protocol.T_START_COMPS) * 1000).toInt()); covert.scheduleSubmissions(targetDateTime, messages); - // While submitting, we download the (large) full commitment list. - msg = await recv(['allcommitments'], timeout: Duration(seconds: Protocol.T_START_SIGS.toInt())); + msg = await recv(['allcommitments'], + timeout: Duration(seconds: Protocol.T_START_SIGS.toInt())); AllCommitments allCommitmentsMsg = msg as AllCommitments; - List<InitialCommitment> allCommitments = allCommitmentsMsg.initialCommitments.map((commitmentBytes) { + List<InitialCommitment> allCommitments = + allCommitmentsMsg.initialCommitments.map((commitmentBytes) { return InitialCommitment.fromBuffer(commitmentBytes); }).toList(); - // Quick check on the commitment list. if (allCommitments.toSet().length != allCommitments.length) { throw FusionError('Commitments list includes duplicates.'); } try { - List<Uint8List> allCommitmentsBytes = allCommitments.map((commitment) => commitment.writeToBuffer()).toList(); - myCommitmentIndexes = myCommitments.map((c) => allCommitmentsBytes.indexOf(c)).toList(); - - + List<Uint8List> allCommitmentsBytes = allCommitments + .map((commitment) => commitment.writeToBuffer()) + .toList(); + myCommitmentIndexes = + myCommitments.map((c) => allCommitmentsBytes.indexOf(c)).toList(); } on Exception { throw FusionError('One or more of my commitments missing.'); } @@ -1260,9 +1242,11 @@ static double nextDoubleNonZero(Random rng) { } // Once all components are received, the server shares them with us: - msg = await recv(['sharecovertcomponents'], timeout: Duration(seconds: Protocol.T_START_SIGS.toInt())); + msg = await recv(['sharecovertcomponents'], + timeout: Duration(seconds: Protocol.T_START_SIGS.toInt())); - ShareCovertComponents shareCovertComponentsMsg = msg as ShareCovertComponents; + ShareCovertComponents shareCovertComponentsMsg = + msg as ShareCovertComponents; List<List<int>> allComponents = shareCovertComponentsMsg.components; bool skipSignatures = msg.getField(2); @@ -1274,7 +1258,10 @@ static double nextDoubleNonZero(Random rng) { covert.checkDone(); try { - myComponentIndexes = myComponents.map((c) => allComponents.indexWhere((element) => ListEquality().equals(element, c))).toList(); + myComponentIndexes = myComponents + .map((c) => allComponents + .indexWhere((element) => ListEquality().equals(element, c))) + .toList(); if (myComponentIndexes.contains(-1)) { throw FusionError('One or more of my components missing.'); } @@ -1285,12 +1272,15 @@ static double nextDoubleNonZero(Random rng) { // Need to implement: check the components list and see if there are enough inputs/outputs // for there to be significant privacy. - List<List<int>> allCommitmentsBytes = allCommitments.map((commitment) => commitment.writeToBuffer().toList()).toList(); - List<int> sessionHash = Util.calcRoundHash(lastHash, roundPubKey, roundTime.toInt(), allCommitmentsBytes, allComponents); - - - if (shareCovertComponentsMsg.sessionHash != null && !ListEquality().equals(shareCovertComponentsMsg.sessionHash, sessionHash)) { + List<List<int>> allCommitmentsBytes = allCommitments + .map((commitment) => commitment.writeToBuffer().toList()) + .toList(); + List<int> sessionHash = Util.calcRoundHash(lastHash, roundPubKey, + roundTime.toInt(), allCommitmentsBytes, allComponents); + if (shareCovertComponentsMsg.sessionHash != null && + !ListEquality() + .equals(shareCovertComponentsMsg.sessionHash, sessionHash)) { throw FusionError('Session hash mismatch (bug!)'); } @@ -1298,33 +1288,25 @@ static double nextDoubleNonZero(Random rng) { print("starting covert signature submission"); status = Tuple('running', 'covert submission: signatures'); - if (allComponents - .toSet() - .length != allComponents.length) { + if (allComponents.toSet().length != allComponents.length) { throw FusionError('Server component list includes duplicates.'); } - - var txInputIndices = Transaction.txFromComponents( - allComponents, sessionHash); - + var txInputIndices = + Transaction.txFromComponents(allComponents, sessionHash); Tuple txData = Transaction.txFromComponents(allComponents, sessionHash); tx = txData.item1; List<int> inputIndices = txData.item2; - - List< - CovertTransactionSignature?> covertTransactionSignatureMessages = List< - CovertTransactionSignature?>.filled(myComponents.length, null); + List<CovertTransactionSignature?> covertTransactionSignatureMessages = + List<CovertTransactionSignature?>.filled(myComponents.length, null); var my_combined = List<Tuple<int, Input>>.generate( inputIndices.length, - (index) => Tuple(inputIndices[index], tx.Inputs[index]), + (index) => Tuple(inputIndices[index], tx.Inputs[index]), ); - - for (var i = 0; i < my_combined.length; i++) { int cIdx = my_combined[i].item1; Input inp = my_combined[i].item2; @@ -1348,19 +1330,17 @@ static double nextDoubleNonZero(Random rng) { DateTime covertT0DateTime = DateTime.fromMillisecondsSinceEpoch( covertT0.toInt() * 1000); // covertT0 is in seconds covert.scheduleSubmissions( - covertT0DateTime.add( - Duration(milliseconds: Protocol.T_START_SIGS.toInt())), - covertTransactionSignatureMessages - ); - + covertT0DateTime + .add(Duration(milliseconds: Protocol.T_START_SIGS.toInt())), + covertTransactionSignatureMessages); // wait for result int timeoutMillis = (Protocol.T_EXPECTING_CONCLUSION - - Protocol.TS_EXPECTING_COVERT_COMPONENTS).toInt(); + Protocol.TS_EXPECTING_COVERT_COMPONENTS) + .toInt(); Duration timeout = Duration(milliseconds: timeoutMillis); msg = await recv(['fusionresult'], timeout: timeout); - // Critical check on server's response timing. if (covertClock() > Protocol.T_EXPECTING_CONCLUSION) { throw FusionError('Fusion result message arrived too slowly.'); @@ -1389,44 +1369,37 @@ static double nextDoubleNonZero(Random rng) { String txHex = tx.serialize(); txid = tx.txid(); - String sumInStr = Util.formatSatoshis(sumIn, - numZeros: 8); - String feeStr = totalFee - .toString(); + String sumInStr = Util.formatSatoshis(sumIn, numZeros: 8); + String feeStr = totalFee.toString(); String feeLoc = 'fee'; - String label = "CashFusion ${coins.length}⇢${outputs - .length}, ${sumInStr} BCH (−${feeStr} sats ${feeLoc})"; + String label = + "CashFusion ${coins.length}⇢${outputs.length}, ${sumInStr} BCH (−${feeStr} sats ${feeLoc})"; Util.updateWalletLabel(txid, label); - } - - else { - badComponents = msg.badComponents.toSet(); + } else { + badComponents = msg.badComponents.toSet(); if (badComponents.intersection(myComponentIndexes.toSet()).isNotEmpty) { - print("bad components: ${badComponents.toList()} mine: ${myComponentIndexes.toList()}"); + print( + "bad components: ${badComponents.toList()} mine: ${myComponentIndexes.toList()}"); throw FusionError("server thinks one of my components is bad!"); } } - - - } - else { // skip_signatures True - Set<int> badComponents = Set<int>(); + } else { + // skip_signatures True + Set<int> badComponents = Set<int>(); } // ### Blame phase ### - covert.setStopTime((covertT0 + Protocol.T_START_CLOSE_BLAME).floor()); print("sending proofs"); status = Tuple('running', 'round failed - sending proofs'); - // create a list of commitment indexes, but leaving out mine. List<int> othersCommitmentIdxes = []; - for(int i=0; i<allCommitments.length; i++) { + for (int i = 0; i < allCommitments.length; i++) { if (!myCommitmentIndexes.contains(i)) { othersCommitmentIdxes.add(i); } @@ -1434,26 +1407,28 @@ static double nextDoubleNonZero(Random rng) { int N = othersCommitmentIdxes.length; assert(N == allCommitments.length - myCommitments.length); if (N == 0) { - throw FusionError("Fusion failed with only me as player -- I can only blame myself."); + throw FusionError( + "Fusion failed with only me as player -- I can only blame myself."); } // where should I send my proofs? List<InitialCommitment> dstCommits = []; - for(int i=0; i<myCommitments.length; i++) { - dstCommits.add(allCommitments[othersCommitmentIdxes[Util.randPosition(randomNumber, N, i)]]); + for (int i = 0; i < myCommitments.length; i++) { + dstCommits.add(allCommitments[ + othersCommitmentIdxes[Util.randPosition(randomNumber, N, i)]]); } // generate the encrypted proofs List<String> encproofs = List<String>.filled(myCommitments.length, ''); - ECDomainParameters params = ECDomainParameters('secp256k1'); - for (int i=0; i<dstCommits.length; i++) { + for (int i = 0; i < dstCommits.length; i++) { InitialCommitment msg = dstCommits[i]; Proof proof = myProofs[i]; proof.componentIdx = myComponentIndexes[i]; - ECPoint? communicationKeyPointMaybe = params.curve.decodePoint(Uint8List.fromList(msg.communicationKey)); + ECPoint? communicationKeyPointMaybe = + params.curve.decodePoint(Uint8List.fromList(msg.communicationKey)); if (communicationKeyPointMaybe == null) { // handle the error case here, e.g., throw an exception or skip this iteration. continue; @@ -1461,7 +1436,9 @@ static double nextDoubleNonZero(Random rng) { ECPoint communicationKeyPoint = communicationKeyPointMaybe; try { - Uint8List encryptedData = await encrypt(proof.writeToBuffer(), communicationKeyPoint, padToLength: 80); + Uint8List encryptedData = await encrypt( + proof.writeToBuffer(), communicationKeyPoint, + padToLength: 80); encproofs[i] = String.fromCharCodes(encryptedData); } catch (EncryptionFailed) { // The communication key was bad (probably invalid x coordinate). @@ -1470,13 +1447,16 @@ static double nextDoubleNonZero(Random rng) { } } - List<Uint8List> encodedEncproofs = encproofs.map((e) => Uint8List.fromList(e.codeUnits)).toList(); - this.send(MyProofsList(encryptedProofs: encodedEncproofs, randomNumber: randomNumber)); + List<Uint8List> encodedEncproofs = + encproofs.map((e) => Uint8List.fromList(e.codeUnits)).toList(); + this.send(MyProofsList( + encryptedProofs: encodedEncproofs, randomNumber: randomNumber)); status = Tuple('running', 'round failed - checking proofs'); print("receiving proofs"); - msg = await this.recv(['theirproofslist'], timeout: Duration(seconds: (2 * Protocol.STANDARD_TIMEOUT).round())); + msg = await this.recv(['theirproofslist'], + timeout: Duration(seconds: (2 * Protocol.STANDARD_TIMEOUT).round())); List<Blames_BlameProof> blames = []; @@ -1498,22 +1478,22 @@ static double nextDoubleNonZero(Random rng) { var sKey; var proofBlob; - - try { - var result = await decrypt(Uint8List.fromList(rp.encryptedProof), privKey); - proofBlob = result.item1; // First item is the decrypted data - sKey = result.item2; // Second item is the symmetric key + var result = + await decrypt(Uint8List.fromList(rp.encryptedProof), privKey); + proofBlob = result.item1; // First item is the decrypted data + sKey = result.item2; // Second item is the symmetric key } on Exception catch (e) { print("found an undecryptable proof"); - blames.add(Blames_BlameProof(whichProof: i, privkey: privKey, blameReason: 'undecryptable')); + blames.add(Blames_BlameProof( + whichProof: i, privkey: privKey, blameReason: 'undecryptable')); continue; } - var commitment = InitialCommitment(); try { - commitment.mergeFromBuffer(commitmentBlob); // Method to parse protobuf data + commitment + .mergeFromBuffer(commitmentBlob); // Method to parse protobuf data } on FormatException catch (e) { throw FusionError("Server relayed bad commitment"); } @@ -1522,13 +1502,17 @@ static double nextDoubleNonZero(Random rng) { try { // Convert allComponents to List<Uint8List> - List<Uint8List> allComponentsUint8 = allComponents.map((component) => Uint8List.fromList(component)).toList(); + List<Uint8List> allComponentsUint8 = allComponents + .map((component) => Uint8List.fromList(component)) + .toList(); // Convert badComponents to List<int> List<int> badComponentsList = badComponents.toList(); // Convert componentFeeRate to int if it's double - int componentFeerateInt = componentFeeRate.round(); // or use .toInt() if you want to truncate instead of rounding + int componentFeerateInt = componentFeeRate + .round(); // or use .toInt() if you want to truncate instead of rounding - var inpComp = validateProofInternal(proofBlob, commitment, allComponentsUint8, badComponentsList, componentFeerateInt); + var inpComp = validateProofInternal(proofBlob, commitment, + allComponentsUint8, badComponentsList, componentFeerateInt); } on Exception catch (e) { print("found an erroneous proof: ${e.toString()}"); var blameProof = Blames_BlameProof(); @@ -1539,27 +1523,26 @@ static double nextDoubleNonZero(Random rng) { continue; } - if (inpComp != null) { countInputs++; try { Util.checkInputElectrumX(inpComp); } on Exception catch (e) { - print("found a bad input [${rp.srcCommitmentIdx}]: $e (${inpComp.prevTxid.reversed.toList().toHex()}:${inpComp.prevIndex})"); + print( + "found a bad input [${rp.srcCommitmentIdx}]: $e (${inpComp.prevTxid.reversed.toList().toHex()}:${inpComp.prevIndex})"); var blameProof = Blames_BlameProof(); blameProof.whichProof = i; blameProof.sessionKey = sKey; - blameProof.blameReason = 'input does not match blockchain: ' + e.toString(); + blameProof.blameReason = + 'input does not match blockchain: ' + e.toString(); blameProof.needLookupBlockchain = true; blames.add(blameProof); - } catch (e) { - print("verified an input internally, but was unable to check it against blockchain: ${e}"); + print( + "verified an input internally, but was unable to check it against blockchain: ${e}"); } } - - } print("checked ${msg.proofs.length} proofs, $countInputs of them inputs"); @@ -1571,13 +1554,10 @@ static double nextDoubleNonZero(Random rng) { // Await the final 'restartround' message. It might take some time // to arrive since other players might be slow, and then the server // itself needs to check blockchain. - await recv(['restartround'], timeout: Duration(seconds: 2 * (Protocol.STANDARD_TIMEOUT.round() + Protocol.BLAME_VERIFY_TIME.round()))); - - - } // end of run_round() function. - - - - + await recv(['restartround'], + timeout: Duration( + seconds: 2 * + (Protocol.STANDARD_TIMEOUT.round() + + Protocol.BLAME_VERIFY_TIME.round()))); + } // end of run_round() function. } // END OF CLASS - diff --git a/lib/services/cashfusion/main.dart b/lib/services/cashfusion/main.dart deleted file mode 100644 index 0f6218bbb..000000000 --- a/lib/services/cashfusion/main.dart +++ /dev/null @@ -1,122 +0,0 @@ -import 'package:flutter/material.dart'; -import 'fusion.dart'; -import 'pedersen.dart'; -import 'encrypt.dart'; -import 'validation.dart'; - -void main() { - - Fusion.foo(); - - runApp(const MyApp()); -} - -class MyApp extends StatelessWidget { - const MyApp({super.key}); - - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: const MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({super.key, required this.title}); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - State<MyHomePage> createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State<MyHomePage> { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: <Widget>[ - const Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headlineMedium, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } -} diff --git a/lib/services/cashfusion/pedersen.dart b/lib/services/cashfusion/pedersen.dart index df9bbfc18..d15ff7800 100644 --- a/lib/services/cashfusion/pedersen.dart +++ b/lib/services/cashfusion/pedersen.dart @@ -1,8 +1,8 @@ -import 'package:pointycastle/ecc/api.dart'; -import 'util.dart'; -import 'dart:math'; import 'dart:typed_data'; +import 'package:pointycastle/ecc/api.dart'; +import 'package:stackwallet/services/cashfusion/util.dart'; + ECDomainParameters getDefaultParams() { return ECDomainParameters("secp256k1"); } @@ -11,10 +11,10 @@ class NullPointError implements Exception { String errMsg() => 'NullPointError: Either Hpoint or HGpoint is null.'; } - class NonceRangeError implements Exception { final String message; - NonceRangeError([this.message = "Nonce value must be in the range 0 < nonce < order"]); + NonceRangeError( + [this.message = "Nonce value must be in the range 0 < nonce < order"]); String toString() => "NonceRangeError: $message"; } @@ -26,12 +26,12 @@ class ResultAtInfinity implements Exception { class InsecureHPoint implements Exception { final String message; - InsecureHPoint([this.message = "The H point has a known discrete logarithm, which means the commitment setup is broken"]); + InsecureHPoint( + [this.message = + "The H point has a known discrete logarithm, which means the commitment setup is broken"]); String toString() => "InsecureHPoint: $message"; } - - class PedersenSetup { late ECPoint _H; late ECPoint _HG; @@ -53,7 +53,6 @@ class PedersenSetup { Commitment commit(BigInt amount, {BigInt? nonce, Uint8List? PUncompressed}) { return Commitment(this, amount, nonce: nonce, PUncompressed: PUncompressed); } - } class Commitment { @@ -62,8 +61,8 @@ class Commitment { late BigInt nonce; late Uint8List PUncompressed; - - Commitment(this.setup, BigInt amount, {BigInt? nonce, Uint8List? PUncompressed}) { + Commitment(this.setup, BigInt amount, + {BigInt? nonce, Uint8List? PUncompressed}) { this.nonce = nonce ?? Util.secureRandomBigInt(setup.params.n.bitLength); amountMod = amount % setup.params.n; @@ -84,13 +83,16 @@ class Commitment { ECPoint? HpointMultiplied = Hpoint * multiplier1; ECPoint? HGpointMultiplied = HGpoint * multiplier2; - ECPoint? Ppoint = HpointMultiplied != null && HGpointMultiplied != null ? HpointMultiplied + HGpointMultiplied : null; + ECPoint? Ppoint = HpointMultiplied != null && HGpointMultiplied != null + ? HpointMultiplied + HGpointMultiplied + : null; if (Ppoint == setup.params.curve.infinity) { throw ResultAtInfinity(); } - this.PUncompressed = PUncompressed ?? Ppoint?.getEncoded(false) ?? Uint8List(0); + this.PUncompressed = + PUncompressed ?? Ppoint?.getEncoded(false) ?? Uint8List(0); } void calcInitial(PedersenSetup setup, BigInt amount) { @@ -114,7 +116,9 @@ class Commitment { ECPoint? HpointMultiplied = Hpoint * multiplier1; ECPoint? HGpointMultiplied = HGpoint * multiplier2; - ECPoint? Ppoint = HpointMultiplied != null && HGpointMultiplied != null ? HpointMultiplied + HGpointMultiplied : null; + ECPoint? Ppoint = HpointMultiplied != null && HGpointMultiplied != null + ? HpointMultiplied + HGpointMultiplied + : null; if (Ppoint == setup.params.curve.infinity) { throw ResultAtInfinity(); @@ -124,14 +128,17 @@ class Commitment { } static Uint8List add_points(Iterable<Uint8List> pointsIterable) { - ECDomainParameters params = getDefaultParams(); // Using helper function here - var pointList = pointsIterable.map((pser) => Util.ser_to_point(pser, params)).toList(); + ECDomainParameters params = + getDefaultParams(); // Using helper function here + var pointList = + pointsIterable.map((pser) => Util.ser_to_point(pser, params)).toList(); if (pointList.isEmpty) { throw ArgumentError('Empty list'); } - ECPoint pSum = pointList.first; // Initialize pSum with the first point in the list + ECPoint pSum = + pointList.first; // Initialize pSum with the first point in the list for (var i = 1; i < pointList.length; i++) { pSum = (pSum + pointList[i])!; @@ -144,7 +151,6 @@ class Commitment { return Util.point_to_ser(pSum, false); } - Commitment addCommitments(Iterable<Commitment> commitmentIterable) { BigInt ktotal = BigInt.zero; // Changed to BigInt from int BigInt atotal = BigInt.zero; // Changed to BigInt from int @@ -168,7 +174,8 @@ class Commitment { ktotal = ktotal % setup.params.n; // Changed order to setup.params.n - if (ktotal == BigInt.zero) { // Changed comparison from 0 to BigInt.zero + if (ktotal == BigInt.zero) { + // Changed comparison from 0 to BigInt.zero throw Exception('Nonce range error'); } @@ -182,6 +189,7 @@ class Commitment { } else { PUncompressed = null; } - return Commitment(setup, atotal, nonce: ktotal, PUncompressed: PUncompressed); + return Commitment(setup, atotal, + nonce: ktotal, PUncompressed: PUncompressed); } } diff --git a/lib/services/cashfusion/protocol.dart b/lib/services/cashfusion/protocol.dart index fa72ce7a5..65abb965c 100644 --- a/lib/services/cashfusion/protocol.dart +++ b/lib/services/cashfusion/protocol.dart @@ -1,11 +1,8 @@ - - class Protocol { static const VERSION = 'alpha13'; static const FUSE_ID = 'FUZ\x00'; - // Safety limits to prevent loss of funds / limit fees: //(Note that if we enter multiply into the same fusion, our limits apply //separately for each "player".) @@ -56,4 +53,3 @@ class Protocol { static const STANDARD_TIMEOUT = 3.0; static const BLAME_VERIFY_TIME = 5.0; } - diff --git a/lib/services/cashfusion/socketwrapper.dart b/lib/services/cashfusion/socketwrapper.dart index 54b8a105e..0a20670ab 100644 --- a/lib/services/cashfusion/socketwrapper.dart +++ b/lib/services/cashfusion/socketwrapper.dart @@ -5,16 +5,19 @@ class SocketWrapper { final String serverIP; final int serverPort; - late Stream<List<int>> _receiveStream; // create a field for the broadcast stream + late Stream<List<int>> + _receiveStream; // create a field for the broadcast stream SocketWrapper(this.serverIP, this.serverPort); Socket get socket => _socket; - Stream<List<int>> get receiveStream => _receiveStream; // expose the stream with a getter + Stream<List<int>> get receiveStream => + _receiveStream; // expose the stream with a getter Future<void> connect() async { _socket = await Socket.connect(serverIP, serverPort); - _receiveStream = _socket.asBroadcastStream(); // initialize the broadcast stream + _receiveStream = + _socket.asBroadcastStream(); // initialize the broadcast stream _socket.done.then((_) { print('......Socket has been closed'); }); @@ -25,7 +28,8 @@ class SocketWrapper { void status() { if (_socket != null) { - print("Socket connected to ${_socket.remoteAddress.address}:${_socket.remotePort}"); + print( + "Socket connected to ${_socket.remoteAddress.address}:${_socket.remotePort}"); } else { print("Socket is not connected"); } diff --git a/lib/services/cashfusion/util.dart b/lib/services/cashfusion/util.dart index cb8e5f621..f8cf75404 100644 --- a/lib/services/cashfusion/util.dart +++ b/lib/services/cashfusion/util.dart @@ -1,24 +1,24 @@ - -import 'package:stackwallet/services/cashfusion/fusion.dart'; -import 'package:pointycastle/ecc/api.dart'; +import 'dart:convert'; import 'dart:math'; import 'dart:typed_data'; -import 'dart:convert'; + import 'package:crypto/crypto.dart' as crypto; -import 'protocol.dart'; +import 'package:pointycastle/ecc/api.dart'; + import 'fusion.pb.dart'; -import 'dart:convert'; +import 'protocol.dart'; class Address { String addr = ""; - Address({required this.addr}); // Constructor updated to accept addr as a named parameter + Address( + {required this.addr}); // Constructor updated to accept addr as a named parameter Address._create({required this.addr}); static Address fromScriptPubKey(List<int> scriptPubKey) { // This is just a placeholder code - String addr = ""; // This should be computed from the scriptPubKey + String addr = ""; // This should be computed from the scriptPubKey return Address(addr: addr); } @@ -32,7 +32,6 @@ class Address { } } - class Tuple<T1, T2> { T1 item1; T2 item2; @@ -49,8 +48,6 @@ class Tuple<T1, T2> { } class Util { - - static Uint8List hexToBytes(String hex) { var result = new Uint8List(hex.length ~/ 2); for (var i = 0; i < hex.length; i += 2) { @@ -63,8 +60,7 @@ class Util { static void checkInputElectrumX(InputComponent inputComponent) { // Implementation needed here // - } - + } static int randPosition(Uint8List seed, int numPositions, int counter) { // counter to bytes @@ -77,7 +73,8 @@ class Util { // take the first 8 bytes var first8Bytes = digest.bytes.take(8).toList(); - var int64 = ByteData.sublistView(Uint8List.fromList(first8Bytes)).getUint64(0, Endian.big); + var int64 = ByteData.sublistView(Uint8List.fromList(first8Bytes)) + .getUint64(0, Endian.big); // perform the modulo operation return ((int64 * numPositions) >> 64).toInt(); @@ -93,7 +90,6 @@ class Util { return 500; } - static Address getAddressFromOutputScript(Uint8List scriptpubkey) { // Dummy implementation... @@ -102,23 +98,22 @@ class Util { return Address.fromString('dummy_address'); } - - static bool schnorrVerify(ECPoint pubkey, List<int> signature, Uint8List messageHash) { + static bool schnorrVerify( + ECPoint pubkey, List<int> signature, Uint8List messageHash) { // Implementation needed: actual Schnorr signature verification return true; } - - static String formatSatoshis(sats, {int numZeros=8}) { + static String formatSatoshis(sats, {int numZeros = 8}) { // To implement return ""; } - static void updateWalletLabel(String txid, String label) { + static void updateWalletLabel(String txid, String label) { // Call the wallet layer. } - static Uint8List getRandomBytes(int length) { + static Uint8List getRandomBytes(int length) { final rand = Random.secure(); final bytes = Uint8List(length); for (int i = 0; i < length; i++) { @@ -127,17 +122,18 @@ class Util { return bytes; } -static List<List<T>> zip<T>(List<T> list1, List<T> list2) { + static List<List<T>> zip<T>(List<T> list1, List<T> list2) { int length = min(list1.length, list2.length); return List<List<T>>.generate(length, (i) => [list1[i], list2[i]]); } - - static List<int> calcInitialHash(int tier, Uint8List covertDomainB, int covertPort, bool covertSsl, double beginTime) { + static List<int> calcInitialHash(int tier, Uint8List covertDomainB, + int covertPort, bool covertSsl, double beginTime) { // Converting int to bytes in BigEndian order var tierBytes = ByteData(8)..setInt64(0, tier, Endian.big); var covertPortBytes = ByteData(4)..setInt32(0, covertPort, Endian.big); - var beginTimeBytes = ByteData(8)..setInt64(0, beginTime.toInt(), Endian.big); + var beginTimeBytes = ByteData(8) + ..setInt64(0, beginTime.toInt(), Endian.big); // Define constants const version = Protocol.VERSION; @@ -159,16 +155,21 @@ static List<List<T>> zip<T>(List<T> list1, List<T> list2) { return digest.bytes; } -static List<int> calcRoundHash(List<int> lastHash, List<int> roundPubkey, int roundTime, List<List<int>> allCommitments, List<List<int>> allComponents) { - return listHash([ - utf8.encode('Cash Fusion Round'), - lastHash, - roundPubkey, - bigIntToBytes(BigInt.from(roundTime)), - listHash(allCommitments), - listHash(allComponents), - ]); -} + static List<int> calcRoundHash( + List<int> lastHash, + List<int> roundPubkey, + int roundTime, + List<List<int>> allCommitments, + List<List<int>> allComponents) { + return listHash([ + utf8.encode('Cash Fusion Round'), + lastHash, + roundPubkey, + bigIntToBytes(BigInt.from(roundTime)), + listHash(allCommitments), + listHash(allComponents), + ]); + } static List<int> listHash(Iterable<List<int>> iterable) { var bytes = <int>[]; @@ -179,12 +180,11 @@ static List<int> calcRoundHash(List<int> lastHash, List<int> roundPubkey, int ro bytes.addAll(x); } return crypto.sha256.convert(bytes).bytes; - } - static Uint8List get_current_genesis_hash() { - var GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"; + var GENESIS = + "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"; var _lastGenesisHash = hexToBytes(GENESIS).reversed.toList(); return Uint8List.fromList(_lastGenesisHash); } @@ -194,7 +194,6 @@ static List<int> calcRoundHash(List<int> lastHash, List<int> roundPubkey, int ro return []; } - static List<Address> reserve_change_addresses(int number_addresses) { //implement later based on wallet. return []; @@ -205,27 +204,26 @@ static List<int> calcRoundHash(List<int> lastHash, List<int> roundPubkey, int ro return true; } -static Uint8List bigIntToBytes(BigInt bigInt) { - return Uint8List.fromList(bigInt.toRadixString(16).padLeft(32, '0').codeUnits); + static Uint8List bigIntToBytes(BigInt bigInt) { + return Uint8List.fromList( + bigInt.toRadixString(16).padLeft(32, '0').codeUnits); } -static Tuple<Uint8List, Uint8List> genKeypair() { - var params = ECDomainParameters('secp256k1'); - var privKeyBigInt = _generatePrivateKey(params.n.bitLength); - var pubKeyPoint = params.G * privKeyBigInt; + static Tuple<Uint8List, Uint8List> genKeypair() { + var params = ECDomainParameters('secp256k1'); + var privKeyBigInt = _generatePrivateKey(params.n.bitLength); + var pubKeyPoint = params.G * privKeyBigInt; - if (pubKeyPoint == null) { - throw Exception("Error generating public key."); + if (pubKeyPoint == null) { + throw Exception("Error generating public key."); + } + + Uint8List privKey = bigIntToBytes(privKeyBigInt); + Uint8List pubKey = pubKeyPoint.getEncoded(true); + + return Tuple(privKey, pubKey); } - Uint8List privKey = bigIntToBytes(privKeyBigInt); - Uint8List pubKey = pubKeyPoint.getEncoded(true); - - return Tuple(privKey, pubKey); -} - - - // Generates a cryptographically secure private key static BigInt _generatePrivateKey(int bitLength) { final random = Random.secure(); @@ -236,7 +234,9 @@ static Tuple<Uint8List, Uint8List> genKeypair() { List<int> rnd = List<int>.generate(bytes, (_) => random.nextInt(256)); var rndBit = random.nextInt(1 << remBit); rnd.add(rndBit); - var privateKey = BigInt.parse(rnd.map((x) => x.toRadixString(16).padLeft(2, '0')).join(), radix: 16); + var privateKey = BigInt.parse( + rnd.map((x) => x.toRadixString(16).padLeft(2, '0')).join(), + radix: 16); return privateKey; } @@ -251,15 +251,16 @@ static Tuple<Uint8List, Uint8List> genKeypair() { return BigInt.parse(hexString, radix: 16); } - static Uint8List sha256(Uint8List bytes) { crypto.Digest digest = crypto.sha256.convert(bytes); return Uint8List.fromList(digest.bytes); } + static Uint8List tokenBytes([int nbytes = 32]) { final Random _random = Random.secure(); - return Uint8List.fromList(List<int>.generate(nbytes, (i) => _random.nextInt(256))); + return Uint8List.fromList( + List<int>.generate(nbytes, (i) => _random.nextInt(256))); } static int componentFee(int size, int feerate) { @@ -269,8 +270,8 @@ static Tuple<Uint8List, Uint8List> genKeypair() { return ((size * feerate) + 999) ~/ 1000; } - - static ECPoint ser_to_point(Uint8List serializedPoint, ECDomainParameters params) { + static ECPoint ser_to_point( + Uint8List serializedPoint, ECDomainParameters params) { var point = params.curve.decodePoint(serializedPoint); if (point == null) { throw FormatException('Point decoding failed'); @@ -282,7 +283,6 @@ static Tuple<Uint8List, Uint8List> genKeypair() { return point.getEncoded(compress); } - static BigInt secureRandomBigInt(int bitLength) { final random = Random.secure(); final bytes = (bitLength + 7) ~/ 8; // ceil division @@ -292,10 +292,13 @@ static Tuple<Uint8List, Uint8List> genKeypair() { randomBytes[i] = random.nextInt(256); } - BigInt randomNumber = BigInt.parse(randomBytes.map((e) => e.toRadixString(16).padLeft(2, '0')).join(), radix: 16); + BigInt randomNumber = BigInt.parse( + randomBytes.map((e) => e.toRadixString(16).padLeft(2, '0')).join(), + radix: 16); return randomNumber; } - static ECPoint combinePubKeys(List<ECPoint> pubKeys) { + + static ECPoint combinePubKeys(List<ECPoint> pubKeys) { if (pubKeys.isEmpty) throw ArgumentError('pubKeys cannot be empty'); ECPoint combined = pubKeys.first.curve.infinity!; @@ -310,7 +313,7 @@ static Tuple<Uint8List, Uint8List> genKeypair() { return combined; } - static bool isPointOnCurve(ECPoint point, ECCurve curve) { + static bool isPointOnCurve(ECPoint point, ECCurve curve) { var x = point.x!.toBigInteger()!; var y = point.y!.toBigInteger()!; var a = curve.a!.toBigInteger()!; @@ -323,8 +326,4 @@ static Tuple<Uint8List, Uint8List> genKeypair() { // Check if the point is on the curve return left == right; } - - - } // END OF CLASS - diff --git a/lib/services/cashfusion/validation.dart b/lib/services/cashfusion/validation.dart index 24555f7d8..95c2a6f5e 100644 --- a/lib/services/cashfusion/validation.dart +++ b/lib/services/cashfusion/validation.dart @@ -1,14 +1,12 @@ -import 'package:protobuf/protobuf.dart'; +import 'dart:typed_data'; + +import 'package:pointycastle/export.dart'; + +import 'encrypt.dart' as Encrypt; +import 'fusion.dart'; import 'fusion.pb.dart' as pb; import 'pedersen.dart'; import 'util.dart'; -import 'encrypt.dart' as Encrypt; -import 'protocol.dart'; -import 'fusion.dart'; -import 'dart:typed_data'; -import 'package:pointycastle/export.dart'; -import 'package:convert/convert.dart'; -import 'pedersen.dart'; class ValidationError implements Exception { final String message; @@ -31,13 +29,12 @@ int componentContrib(pb.Component component, int feerate) { } } - - void check(bool condition, String failMessage) { if (!condition) { throw ValidationError(failMessage); } } + dynamic protoStrictParse(dynamic msg, List<int> blob) { try { if (msg.mergeFromBuffer(blob) != blob.length) { @@ -63,21 +60,22 @@ dynamic protoStrictParse(dynamic msg, List<int> blob) { return msg; } +List<pb.InitialCommitment> checkPlayerCommit(pb.PlayerCommit msg, + int minExcessFee, int maxExcessFee, int numComponents) { + check(msg.initialCommitments.length == numComponents, + "wrong number of component commitments"); + check(msg.blindSigRequests.length == numComponents, + "wrong number of blind sig requests"); -List<pb.InitialCommitment> checkPlayerCommit( - pb.PlayerCommit msg, - int minExcessFee, - int maxExcessFee, - int numComponents - ) { - check(msg.initialCommitments.length == numComponents, "wrong number of component commitments"); - check(msg.blindSigRequests.length == numComponents, "wrong number of blind sig requests"); - - check(minExcessFee <= msg.excessFee.toInt() && msg.excessFee.toInt() <= maxExcessFee, "bad excess fee"); + check( + minExcessFee <= msg.excessFee.toInt() && + msg.excessFee.toInt() <= maxExcessFee, + "bad excess fee"); check(msg.randomNumberCommitment.length == 32, "bad random commit"); check(msg.pedersenTotalNonce.length == 32, "bad nonce"); - check(msg.blindSigRequests.every((r) => r.length == 32), "bad blind sig request"); + check(msg.blindSigRequests.every((r) => r.length == 32), + "bad blind sig request"); List<pb.InitialCommitment> commitMessages = []; for (var cblob in msg.initialCommitments) { @@ -85,11 +83,15 @@ List<pb.InitialCommitment> checkPlayerCommit( check(cmsg.saltedComponentHash.length == 32, "bad salted hash"); var P = cmsg.amountCommitment; check(P.length == 65 && P[0] == 4, "bad commitment point"); - check(cmsg.communicationKey.length == 33 && (cmsg.communicationKey[0] == 2 || cmsg.communicationKey[0] == 3), "bad communication key"); + check( + cmsg.communicationKey.length == 33 && + (cmsg.communicationKey[0] == 2 || cmsg.communicationKey[0] == 3), + "bad communication key"); commitMessages.add(cmsg); } - Uint8List HBytes = Uint8List.fromList([0x02] + 'CashFusion gives us fungibility.'.codeUnits); + Uint8List HBytes = + Uint8List.fromList([0x02] + 'CashFusion gives us fungibility.'.codeUnits); ECDomainParameters params = ECDomainParameters('secp256k1'); ECPoint? HMaybe = params.curve.decodePoint(HBytes); if (HMaybe == null) { @@ -102,26 +104,28 @@ List<pb.InitialCommitment> checkPlayerCommit( var pointsum; // Verify pedersen commitment try { - pointsum = Commitment.add_points(commitMessages.map((m) => Uint8List.fromList(m.amountCommitment)).toList()); - claimedCommit = setup.commit(BigInt.from(msg.excessFee.toInt()), nonce: Util.bytesToBigInt(Uint8List.fromList(msg.pedersenTotalNonce))); + pointsum = Commitment.add_points(commitMessages + .map((m) => Uint8List.fromList(m.amountCommitment)) + .toList()); + claimedCommit = setup.commit(BigInt.from(msg.excessFee.toInt()), + nonce: Util.bytesToBigInt(Uint8List.fromList(msg.pedersenTotalNonce))); - check(pointsum == claimedCommit.PUncompressed, "pedersen commitment mismatch"); + check(pointsum == claimedCommit.PUncompressed, + "pedersen commitment mismatch"); } catch (e) { throw ValidationError("pedersen commitment verification error"); } - check(pointsum == claimedCommit.PUncompressed, "pedersen commitment mismatch"); + check( + pointsum == claimedCommit.PUncompressed, "pedersen commitment mismatch"); return commitMessages; } - Tuple<String, int> checkCovertComponent( pb.CovertComponent msg, ECPoint roundPubkey, int componentFeerate) { var messageHash = Util.sha256(Uint8List.fromList(msg.component)); check(msg.signature.length == 64, "bad message signature"); - check( - Util.schnorrVerify( - roundPubkey, msg.signature, messageHash), + check(Util.schnorrVerify(roundPubkey, msg.signature, messageHash), "bad message signature"); var cmsg = protoStrictParse(pb.Component(), msg.component); @@ -133,7 +137,8 @@ Tuple<String, int> checkCovertComponent( var inp = cmsg.input; check(inp.prevTxid.length == 32, "bad txid"); check( - (inp.pubkey.length == 33 && (inp.pubkey[0] == 2 || inp.pubkey[0] == 3)) || + (inp.pubkey.length == 33 && + (inp.pubkey[0] == 2 || inp.pubkey[0] == 3)) || (inp.pubkey.length == 65 && inp.pubkey[0] == 4), "bad pubkey"); sortKey = 'i' + @@ -146,8 +151,7 @@ Tuple<String, int> checkCovertComponent( // Basically just checks if its ok address. should throw error if not. addr = Util.getAddressFromOutputScript(out.scriptpubkey); - check( - out.amount >= Util.dustLimit(out.scriptpubkey.length), "dust output"); + check(out.amount >= Util.dustLimit(out.scriptpubkey.length), "dust output"); sortKey = 'o' + out.amount.toString() + String.fromCharCodes(out.scriptpubkey) + @@ -162,14 +166,14 @@ Tuple<String, int> checkCovertComponent( } pb.InputComponent? validateProofInternal( - Uint8List proofBlob, - pb.InitialCommitment commitment, - List<Uint8List> allComponents, - List<int> badComponents, - int componentFeerate, - ) { - - Uint8List HBytes = Uint8List.fromList([0x02] + 'CashFusion gives us fungibility.'.codeUnits); + Uint8List proofBlob, + pb.InitialCommitment commitment, + List<Uint8List> allComponents, + List<int> badComponents, + int componentFeerate, +) { + Uint8List HBytes = + Uint8List.fromList([0x02] + 'CashFusion gives us fungibility.'.codeUnits); ECDomainParameters params = ECDomainParameters('secp256k1'); ECPoint? HMaybe = params.curve.decodePoint(HBytes); if (HMaybe == null) { @@ -218,7 +222,7 @@ pb.InputComponent? validateProofInternal( "pedersen commitment mismatch", ); - if(comp.hasInput()){ + if (comp.hasInput()) { return comp.input; } else { return null; @@ -226,14 +230,14 @@ pb.InputComponent? validateProofInternal( } Future<dynamic> validateBlame( - pb.Blames_BlameProof blame, - Uint8List encProof, - Uint8List srcCommitBlob, - Uint8List destCommitBlob, - List<Uint8List> allComponents, - List<int> badComponents, - int componentFeerate, - ) async { + pb.Blames_BlameProof blame, + Uint8List encProof, + Uint8List srcCommitBlob, + Uint8List destCommitBlob, + List<Uint8List> allComponents, + List<int> badComponents, + int componentFeerate, +) async { var destCommit = pb.InitialCommitment(); destCommit.mergeFromBuffer(destCommitBlob); var destPubkey = destCommit.communicationKey; @@ -246,8 +250,10 @@ Future<dynamic> validateBlame( if (decrypter == pb.Blames_BlameProof_Decrypter.privkey) { var privkey = Uint8List.fromList(blame.privkey); check(privkey.length == 32, 'bad blame privkey'); - var privkeyHexStr = Util.bytesToHex(privkey); // Convert bytes to hex string. - var privkeyBigInt = BigInt.parse(privkeyHexStr, radix: 16); // Convert hex string to BigInt. + var privkeyHexStr = + Util.bytesToHex(privkey); // Convert bytes to hex string. + var privkeyBigInt = + BigInt.parse(privkeyHexStr, radix: 16); // Convert hex string to BigInt. var privateKey = ECPrivateKey(privkeyBigInt, params); // Create ECPrivateKey var pubkeys = Util.pubkeysFromPrivkey(privkeyHexStr); check(destCommit.communicationKey == pubkeys[1], 'bad blame privkey'); @@ -282,11 +288,13 @@ Future<dynamic> validateBlame( } if (!blame.needLookupBlockchain) { - throw ValidationError('blame indicated internal inconsistency, none found!'); + throw ValidationError( + 'blame indicated internal inconsistency, none found!'); } if (inpComp == null) { - throw ValidationError('blame indicated blockchain error on a non-input component'); + throw ValidationError( + 'blame indicated blockchain error on a non-input component'); } return inpComp; From 143e1d821aa59ff9828e7d7e853bca0459476dd4 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 27 Jul 2023 11:35:44 -0600 Subject: [PATCH 012/379] remove duplicate map entries --- lib/services/cashfusion/comms.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/services/cashfusion/comms.dart b/lib/services/cashfusion/comms.dart index e219ff38f..98094a5ca 100644 --- a/lib/services/cashfusion/comms.dart +++ b/lib/services/cashfusion/comms.dart @@ -39,10 +39,8 @@ Map<Type, PbCreateFunc> pbClassCreators = { Error: () => Error(), Ping: () => Ping(), OK: () => OK(), - ClientMessage: () => ClientMessage(), ServerMessage: () => ServerMessage(), CovertMessage: () => CovertMessage(), - CovertResponse: () => CovertResponse() }; Future<void> sendPb( From 2e9c5bde8e3b5c11408ea222ab7617df0e04eeec Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 27 Jul 2023 12:11:30 -0600 Subject: [PATCH 013/379] clean up compile time errors only --- lib/services/cashfusion/covert.dart | 7 ++++--- lib/services/cashfusion/encrypt.dart | 10 +++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/services/cashfusion/covert.dart b/lib/services/cashfusion/covert.dart index d034f9e99..62e5ed5a1 100644 --- a/lib/services/cashfusion/covert.dart +++ b/lib/services/cashfusion/covert.dart @@ -82,7 +82,7 @@ class CovertConnection { int? slotNum; DateTime? tPing; int? connNumber; - Completer wakeup = Completer(); + Completer<bool> wakeup = Completer(); double? delay; Future<bool> waitWakeupOrTime(DateTime? t) async { @@ -258,7 +258,8 @@ class CovertSubmitter extends PrintError { } } - void scheduleSubmit(int slotNum, DateTime tStart, dynamic subMsg) { + void scheduleSubmit( + int slotNum, DateTime tStart, pb.GeneratedMessage subMsg) { var slot = slots[slotNum]; assert(slot.done, "tried to set new work when prior work not done"); @@ -290,7 +291,7 @@ class CovertSubmitter extends PrintError { // Then, notify the slots that there is a message to submit. for (var i = 0; i < slots.length; i++) { var slot = slots[i]; - var subMsg = slotMessages[i]; + var subMsg = slotMessages[i] as pb.GeneratedMessage; var covConn = slot.covConn; if (covConn != null) { diff --git a/lib/services/cashfusion/encrypt.dart b/lib/services/cashfusion/encrypt.dart index 2a6e00a6b..f6ffafe3e 100644 --- a/lib/services/cashfusion/encrypt.dart +++ b/lib/services/cashfusion/encrypt.dart @@ -121,16 +121,16 @@ Future<Tuple<Uint8List, Uint8List>> decrypt( // DOUBLE CHECK THIS IS RIGHT IDEA MATCHING PYTHON. ECPoint G = params.G; - var key; + final List<int> key; - if (privkey.d != null && noncePoint != null) { + if (privkey.d != null) { var point = (G * privkey.d)! + noncePoint; key = crypto.sha256.convert(Util.point_to_ser(point!, true)).bytes; // ... + var decryptedData = await decryptWithSymmkey(data, Uint8List.fromList(key)); + return Tuple(decryptedData, Uint8List.fromList(key)); } else { // Handle the situation where privkey.d or noncePoint is null + throw Exception("FIXME"); } - - var decryptedData = await decryptWithSymmkey(data, Uint8List.fromList(key)); - return Tuple(decryptedData, Uint8List.fromList(key)); } From 6ace23964743eb67ac85bfe7266220f38024bf03 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 27 Jul 2023 13:11:16 -0500 Subject: [PATCH 014/379] check if Exception --- lib/services/cashfusion/connection.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/services/cashfusion/connection.dart b/lib/services/cashfusion/connection.dart index 64780dfba..ee36a17dc 100644 --- a/lib/services/cashfusion/connection.dart +++ b/lib/services/cashfusion/connection.dart @@ -171,7 +171,11 @@ class Connection { }, onError: (e) { subscription?.cancel(); - throw e; + if (e is Exception) { + throw e; + } else { + throw Exception('Unknown error'); + } }, onDone: () { print("DEBUG ON DONE"); From 40d9a8aa9e5983d676850b44bff758dc0f5bd868 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 27 Jul 2023 13:14:19 -0500 Subject: [PATCH 015/379] include exception if non-null --- lib/services/cashfusion/connection.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/cashfusion/connection.dart b/lib/services/cashfusion/connection.dart index ee36a17dc..0d6953a71 100644 --- a/lib/services/cashfusion/connection.dart +++ b/lib/services/cashfusion/connection.dart @@ -174,7 +174,7 @@ class Connection { if (e is Exception) { throw e; } else { - throw Exception('Unknown error'); + throw Exception(e ?? 'Error in `subscription` socket!.listen'); } }, onDone: () { From e91ac3d355545b94480b3df4f78910d12e1d8451 Mon Sep 17 00:00:00 2001 From: Jonald Fyookball <jonaldfyookball@outlook.com> Date: Thu, 27 Jul 2023 14:29:03 -0400 Subject: [PATCH 016/379] Fixes for registerAndWait. --- lib/services/cashfusion/connection.dart | 10 +++++++--- lib/services/cashfusion/fusion.dart | 22 +++++++++++++++------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/lib/services/cashfusion/connection.dart b/lib/services/cashfusion/connection.dart index b9b4cc64b..970232855 100644 --- a/lib/services/cashfusion/connection.dart +++ b/lib/services/cashfusion/connection.dart @@ -199,6 +199,7 @@ class Connection { Future<List<int>> recv_message2(SocketWrapper socketwrapper, {Duration? timeout}) async { + print ("START OF RECV2"); if (timeout == null) { timeout = this.timeout; } @@ -244,6 +245,7 @@ class Connection { throw BadFrameError('Got a frame with msg_length=$messageLength > $MAX_MSG_LENGTH (max)'); } + /* print("DEBUG recv_message2 3 - about to read the message body, messageLength: $messageLength"); print ("DEBUG recvfbuf len is "); @@ -252,12 +254,14 @@ class Connection { print (bytesRead); print ("message length is "); print(messageLength); + + */ if (recvBuf.length == bytesRead && bytesRead == 12 + messageLength) { final message = recvBuf.sublist(12, 12 + messageLength); - print("DEBUG recv_message2 4 - message received, length: ${message.length}"); - print("DEBUG recv_message2 5 - message content: $message"); - + //print("DEBUG recv_message2 4 - message received, length: ${message.length}"); + //print("DEBUG recv_message2 5 - message content: $message"); + print ("END OF RECV2"); return message; } else { // Throwing exception if the length doesn't match diff --git a/lib/services/cashfusion/fusion.dart b/lib/services/cashfusion/fusion.dart index bcb03ac5a..ecef0f855 100644 --- a/lib/services/cashfusion/fusion.dart +++ b/lib/services/cashfusion/fusion.dart @@ -814,8 +814,6 @@ static double nextDoubleNonZero(Random rng) { print('Possible tiers: $tierOutputs'); - print ("CHECK socketwrapper 839"); - socketwrapper.status(); safety_sum_in = sumInputsValue; safety_exess_fees = excessFees; return; @@ -825,6 +823,7 @@ static double nextDoubleNonZero(Random rng) { Future<void> registerAndWait(SocketWrapper socketwrapper) async { + print ("DEBUG register and wait top."); // msg can be different classes depending on which protobuf msg is sent. dynamic? msg; @@ -866,6 +865,7 @@ static double nextDoubleNonZero(Random rng) { var tiersStrings = {for (var entry in tierOutputs.entries) entry.key: (entry.key * 1e-8).toStringAsFixed(8).replaceAll(RegExp(r'0+$'), '')}; while (true) { + print ("RECEIVE LOOP 870............DEBUG"); var msg = await recv2(socketwrapper,['tierstatusupdate', 'fusionbegin'], timeout: Duration(seconds: 10)); var fieldInfoFusionBegin = msg.info_.byName["fusionbegin"]; @@ -905,23 +905,31 @@ static double nextDoubleNonZero(Random rng) { int? besttime; int? besttimetier; for (var entry in statuses.entries) { - double frac = entry.value.players / entry.value.min_players; + double frac = entry.value.players.toInt() / entry.value.minPlayers.toInt(); if (frac >= maxfraction) { if (frac > maxfraction) { maxfraction = frac; maxtiers.clear(); } - maxtiers.add(entry.key); + maxtiers.add(entry.key.toInt()); } - if (entry.value.hasField('time_remaining')) { - int tr = entry.value.time_remaining; + + var fieldInfoTimeRemaining = entry.value.info_.byName["timeRemaining"]; + if (fieldInfoTimeRemaining == null) { + throw FusionError('Expected field not found in message: timeRemaining'); + } + + if (entry.value.hasField(fieldInfoTimeRemaining.tagNumber)) { + + int tr = entry.value.timeRemaining.toInt(); if (besttime == null || tr < besttime) { besttime = tr; - besttimetier = entry.key; + besttimetier = entry.key.toInt(); } } } + var displayBest = <String>[]; var displayMid = <String>[]; var displayQueued = <String>[]; From 571fd960b8fb9bfdb660553bd280518d06c4572a Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 27 Jul 2023 13:43:25 -0500 Subject: [PATCH 017/379] autoformatting --- lib/services/cashfusion/connection.dart | 10 ++++++---- lib/services/cashfusion/fusion.dart | 19 +++++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/services/cashfusion/connection.dart b/lib/services/cashfusion/connection.dart index 69da5fc7e..e6b9581c0 100644 --- a/lib/services/cashfusion/connection.dart +++ b/lib/services/cashfusion/connection.dart @@ -53,7 +53,9 @@ class Connection { static final Uint8List magic = Uint8List.fromList([0x76, 0x5b, 0xe8, 0xb4, 0xe4, 0x39, 0x6d, 0xcf]); final Uint8List recvbuf = Uint8List(0); + Connection({required this.socket, this.timeout = const Duration(seconds: 1)}); + Connection.withoutSocket({this.timeout = const Duration(seconds: 1)}); Future<void> sendMessageWithSocketWrapper( @@ -198,9 +200,9 @@ class Connection { return recvBuf; } - - Future<List<int>> recv_message2(SocketWrapper socketwrapper, {Duration? timeout}) async { - print ("START OF RECV2"); + Future<List<int>> recv_message2(SocketWrapper socketwrapper, + {Duration? timeout}) async { + print("START OF RECV2"); if (timeout == null) { timeout = this.timeout; } @@ -264,7 +266,7 @@ class Connection { //print("DEBUG recv_message2 4 - message received, length: ${message.length}"); //print("DEBUG recv_message2 5 - message content: $message"); - print ("END OF RECV2"); + print("END OF RECV2"); return message; } else { // Throwing exception if the length doesn't match diff --git a/lib/services/cashfusion/fusion.dart b/lib/services/cashfusion/fusion.dart index 4fab9fbaf..1ce397a71 100644 --- a/lib/services/cashfusion/fusion.dart +++ b/lib/services/cashfusion/fusion.dart @@ -23,7 +23,9 @@ import 'validation.dart'; class FusionError implements Exception { final String message; + FusionError(this.message); + String toString() => "FusionError: $message"; } @@ -215,6 +217,7 @@ class Fusion { Fusion() { //initializeConnection(host, port) } + /* Future<void> initializeConnection(String host, int port) async { Socket socket = await Socket.connect(host, port); @@ -785,8 +788,7 @@ class Fusion { } Future<void> registerAndWait(SocketWrapper socketwrapper) async { - - print ("DEBUG register and wait top."); + print("DEBUG register and wait top."); // msg can be different classes depending on which protobuf msg is sent. dynamic? msg; @@ -826,8 +828,9 @@ class Fusion { }; while (true) { - print ("RECEIVE LOOP 870............DEBUG"); - var msg = await recv2(socketwrapper,['tierstatusupdate', 'fusionbegin'], timeout: Duration(seconds: 10)); + print("RECEIVE LOOP 870............DEBUG"); + var msg = await recv2(socketwrapper, ['tierstatusupdate', 'fusionbegin'], + timeout: Duration(seconds: 10)); var fieldInfoFusionBegin = msg.info_.byName["fusionbegin"]; if (fieldInfoFusionBegin != null && @@ -865,7 +868,8 @@ class Fusion { int? besttime; int? besttimetier; for (var entry in statuses.entries) { - double frac = entry.value.players.toInt() / entry.value.minPlayers.toInt(); + double frac = + entry.value.players.toInt() / entry.value.minPlayers.toInt(); if (frac >= maxfraction) { if (frac > maxfraction) { maxfraction = frac; @@ -876,11 +880,11 @@ class Fusion { var fieldInfoTimeRemaining = entry.value.info_.byName["timeRemaining"]; if (fieldInfoTimeRemaining == null) { - throw FusionError('Expected field not found in message: timeRemaining'); + throw FusionError( + 'Expected field not found in message: timeRemaining'); } if (entry.value.hasField(fieldInfoTimeRemaining.tagNumber)) { - int tr = entry.value.timeRemaining.toInt(); if (besttime == null || tr < besttime) { besttime = tr; @@ -889,7 +893,6 @@ class Fusion { } } - var displayBest = <String>[]; var displayMid = <String>[]; var displayQueued = <String>[]; From d0e3474368407752cb85c5ec14031b0765ccd971 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 27 Jul 2023 14:39:36 -0500 Subject: [PATCH 018/379] move fusion dart code to fusiondart package as submodule https://github.com/cypherstack/fusiondart --- .gitmodules | 3 + fusiondart | 1 + lib/services/cashfusion/comms.dart | 178 -- lib/services/cashfusion/connection.dart | 290 -- lib/services/cashfusion/covert.dart | 484 ---- lib/services/cashfusion/encrypt.dart | 136 - lib/services/cashfusion/fusion.dart | 1574 ----------- lib/services/cashfusion/fusion.pb.dart | 2501 ----------------- lib/services/cashfusion/pedersen.dart | 195 -- .../cashfusion/protobuf/build-proto-fusion.sh | 11 - .../cashfusion/protobuf/fusion.pb.dart | 2501 ----------------- .../cashfusion/protobuf/fusion.pbenum.dart | 7 - .../cashfusion/protobuf/fusion.pbjson.dart | 427 --- lib/services/cashfusion/protobuf/fusion.proto | 281 -- lib/services/cashfusion/protocol.dart | 55 - lib/services/cashfusion/socketwrapper.dart | 50 - lib/services/cashfusion/util.dart | 329 --- lib/services/cashfusion/validation.dart | 301 -- lib/services/mixins/fusion_interface.dart | 5 +- pubspec.lock | 9 +- pubspec.yaml | 3 + 21 files changed, 18 insertions(+), 9323 deletions(-) create mode 160000 fusiondart delete mode 100644 lib/services/cashfusion/comms.dart delete mode 100644 lib/services/cashfusion/connection.dart delete mode 100644 lib/services/cashfusion/covert.dart delete mode 100644 lib/services/cashfusion/encrypt.dart delete mode 100644 lib/services/cashfusion/fusion.dart delete mode 100644 lib/services/cashfusion/fusion.pb.dart delete mode 100644 lib/services/cashfusion/pedersen.dart delete mode 100644 lib/services/cashfusion/protobuf/build-proto-fusion.sh delete mode 100644 lib/services/cashfusion/protobuf/fusion.pb.dart delete mode 100644 lib/services/cashfusion/protobuf/fusion.pbenum.dart delete mode 100644 lib/services/cashfusion/protobuf/fusion.pbjson.dart delete mode 100644 lib/services/cashfusion/protobuf/fusion.proto delete mode 100644 lib/services/cashfusion/protocol.dart delete mode 100644 lib/services/cashfusion/socketwrapper.dart delete mode 100644 lib/services/cashfusion/util.dart delete mode 100644 lib/services/cashfusion/validation.dart diff --git a/.gitmodules b/.gitmodules index 7474c8a54..66ee203f4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "crypto_plugins/flutter_liblelantus"] path = crypto_plugins/flutter_liblelantus url = https://github.com/cypherstack/flutter_liblelantus.git +[submodule "fusiondart"] + path = fusiondart + url = https://github.com/cypherstack/fusiondart diff --git a/fusiondart b/fusiondart new file mode 160000 index 000000000..ddf883749 --- /dev/null +++ b/fusiondart @@ -0,0 +1 @@ +Subproject commit ddf883749bf72eab6d0c61ac123f728dc47ec91f diff --git a/lib/services/cashfusion/comms.dart b/lib/services/cashfusion/comms.dart deleted file mode 100644 index 98094a5ca..000000000 --- a/lib/services/cashfusion/comms.dart +++ /dev/null @@ -1,178 +0,0 @@ -import 'dart:async'; -import 'dart:io'; - -import 'package:protobuf/protobuf.dart'; -import 'package:stackwallet/services/cashfusion/connection.dart'; -import 'package:stackwallet/services/cashfusion/fusion.dart'; -import 'package:stackwallet/services/cashfusion/fusion.pb.dart'; -import 'package:stackwallet/services/cashfusion/socketwrapper.dart'; -import 'package:stackwallet/services/cashfusion/util.dart'; - -typedef PbCreateFunc = GeneratedMessage Function(); - -Map<Type, PbCreateFunc> pbClassCreators = { - CovertResponse: () => CovertResponse(), - ClientMessage: () => ClientMessage(), - InputComponent: () => InputComponent(), - OutputComponent: () => OutputComponent(), - BlankComponent: () => BlankComponent(), - Component: () => Component(), - InitialCommitment: () => InitialCommitment(), - Proof: () => Proof(), - ClientHello: () => ClientHello(), - ServerHello: () => ServerHello(), - JoinPools: () => JoinPools(), - TierStatusUpdate: () => TierStatusUpdate(), - FusionBegin: () => FusionBegin(), - StartRound: () => StartRound(), - PlayerCommit: () => PlayerCommit(), - BlindSigResponses: () => BlindSigResponses(), - AllCommitments: () => AllCommitments(), - CovertComponent: () => CovertComponent(), - ShareCovertComponents: () => ShareCovertComponents(), - CovertTransactionSignature: () => CovertTransactionSignature(), - FusionResult: () => FusionResult(), - MyProofsList: () => MyProofsList(), - TheirProofsList: () => TheirProofsList(), - Blames: () => Blames(), - RestartRound: () => RestartRound(), - Error: () => Error(), - Ping: () => Ping(), - OK: () => OK(), - ServerMessage: () => ServerMessage(), - CovertMessage: () => CovertMessage(), -}; - -Future<void> sendPb( - Connection connection, Type pbClass, GeneratedMessage subMsg, - {Duration? timeout}) async { - // Construct the outer message with the submessage. - - if (pbClassCreators[pbClass] == null) { - print('pbClassCreators[pbClass] is null'); - return; - } - - var pbMessage = pbClassCreators[pbClass]!()..mergeFromMessage(subMsg); - final msgBytes = pbMessage.writeToBuffer(); - try { - await connection.sendMessage(msgBytes, timeout: timeout); - } on SocketException { - throw FusionError('Connection closed by remote'); - } on TimeoutException { - throw FusionError('Timed out during send'); - } catch (e) { - throw FusionError('Communications error: ${e.runtimeType}: $e'); - } -} - -Future<void> sendPb2(SocketWrapper socketwrapper, Connection connection, - Type pbClass, GeneratedMessage subMsg, - {Duration? timeout}) async { - // Construct the outer message with the submessage. - - if (pbClassCreators[pbClass] == null) { - print('pbClassCreators[pbClass] is null'); - return; - } - - var pbMessage = pbClassCreators[pbClass]!()..mergeFromMessage(subMsg); - final msgBytes = pbMessage.writeToBuffer(); - try { - await connection.sendMessageWithSocketWrapper(socketwrapper, msgBytes, - timeout: timeout); - } on SocketException { - throw FusionError('Connection closed by remote'); - } on TimeoutException { - throw FusionError('Timed out during send'); - } catch (e) { - throw FusionError('Communications error: ${e.runtimeType}: $e'); - } -} - -Future<Tuple<GeneratedMessage, String>> recvPb2(SocketWrapper socketwrapper, - Connection connection, Type pbClass, List<String> expectedFieldNames, - {Duration? timeout}) async { - try { - List<int> blob = - await connection.recv_message2(socketwrapper, timeout: timeout); - - var pbMessage = pbClassCreators[pbClass]!()..mergeFromBuffer(blob); - - if (!pbMessage.isInitialized()) { - throw FusionError('Incomplete message received'); - } - - for (var name in expectedFieldNames) { - var fieldInfo = pbMessage.info_.byName[name]; - - if (fieldInfo == null) { - throw FusionError('Expected field not found in message: $name'); - } - - if (pbMessage.hasField(fieldInfo.tagNumber)) { - return Tuple(pbMessage, name); - } - } - - throw FusionError( - 'None of the expected fields found in the received message'); - } catch (e) { - // Handle different exceptions here - if (e is SocketException) { - throw FusionError('Connection closed by remote'); - } else if (e is InvalidProtocolBufferException) { - throw FusionError('Message decoding error: ' + e.toString()); - } else if (e is TimeoutException) { - throw FusionError('Timed out during receive'); - } else if (e is OSError && e.errorCode == 9) { - throw FusionError('Connection closed by local'); - } else { - throw FusionError( - 'Communications error: ${e.runtimeType}: ${e.toString()}'); - } - } -} - -Future<Tuple<GeneratedMessage, String>> recvPb( - Connection connection, Type pbClass, List<String> expectedFieldNames, - {Duration? timeout}) async { - try { - List<int> blob = await connection.recv_message(timeout: timeout); - - var pbMessage = pbClassCreators[pbClass]!()..mergeFromBuffer(blob); - - if (!pbMessage.isInitialized()) { - throw FusionError('Incomplete message received'); - } - - for (var name in expectedFieldNames) { - var fieldInfo = pbMessage.info_.byName[name]; - - if (fieldInfo == null) { - throw FusionError('Expected field not found in message: $name'); - } - - if (pbMessage.hasField(fieldInfo.tagNumber)) { - return Tuple(pbMessage, name); - } - } - - throw FusionError( - 'None of the expected fields found in the received message'); - } catch (e) { - // Handle different exceptions here - if (e is SocketException) { - throw FusionError('Connection closed by remote'); - } else if (e is InvalidProtocolBufferException) { - throw FusionError('Message decoding error: ' + e.toString()); - } else if (e is TimeoutException) { - throw FusionError('Timed out during receive'); - } else if (e is OSError && e.errorCode == 9) { - throw FusionError('Connection closed by local'); - } else { - throw FusionError( - 'Communications error: ${e.runtimeType}: ${e.toString()}'); - } - } -} diff --git a/lib/services/cashfusion/connection.dart b/lib/services/cashfusion/connection.dart deleted file mode 100644 index e6b9581c0..000000000 --- a/lib/services/cashfusion/connection.dart +++ /dev/null @@ -1,290 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'dart:typed_data'; - -import 'package:collection/collection.dart'; -import 'package:convert/convert.dart'; -import 'package:stackwallet/services/cashfusion/socketwrapper.dart'; - -/* -This file might need some fixing up because each time we call fillBuf, we're trying to -remove data from a buffer but its a local copy , might not actually -remove the data from the socket buffer. We may need a wrapper class for the buffer?? - - */ - -class BadFrameError extends Error { - final String message; - - BadFrameError(this.message); - - @override - String toString() => message; -} - -Future<Connection> openConnection( - String host, - int port, { - double connTimeout = 5.0, - double defaultTimeout = 5.0, - bool ssl = false, - dynamic socksOpts, -}) async { - try { - // Dart's Socket class handles connection timeout internally. - Socket socket = await Socket.connect(host, port); - if (ssl) { - // We can use SecureSocket.secure to upgrade socket connection to SSL/TLS. - socket = await SecureSocket.secure(socket); - } - - return Connection( - socket: socket, timeout: Duration(seconds: defaultTimeout.toInt())); - } catch (e) { - throw 'Failed to open connection: $e'; - } -} - -class Connection { - Duration timeout = Duration(seconds: 1); - Socket? socket; - - static const int MAX_MSG_LENGTH = 200 * 1024; - static final Uint8List magic = - Uint8List.fromList([0x76, 0x5b, 0xe8, 0xb4, 0xe4, 0x39, 0x6d, 0xcf]); - final Uint8List recvbuf = Uint8List(0); - - Connection({required this.socket, this.timeout = const Duration(seconds: 1)}); - - Connection.withoutSocket({this.timeout = const Duration(seconds: 1)}); - - Future<void> sendMessageWithSocketWrapper( - SocketWrapper socketwrapper, List<int> msg, - {Duration? timeout}) async { - timeout ??= this.timeout; - print("DEBUG sendmessage msg sending "); - print(msg); - final lengthBytes = Uint8List(4); - final byteData = ByteData.view(lengthBytes.buffer); - byteData.setUint32(0, msg.length, Endian.big); - - final frame = <int>[] - ..addAll(Connection.magic) - ..addAll(lengthBytes) - ..addAll(msg); - - try { - socketwrapper.send(frame); - } on SocketException catch (e) { - throw TimeoutException('Socket write timed out', timeout); - } - } - - Future<void> sendMessage(List<int> msg, {Duration? timeout}) async { - timeout ??= this.timeout; - - final lengthBytes = Uint8List(4); - final byteData = ByteData.view(lengthBytes.buffer); - byteData.setUint32(0, msg.length, Endian.big); - - print(Connection.magic); - final frame = <int>[] - ..addAll(Connection.magic) - ..addAll(lengthBytes) - ..addAll(msg); - - try { - StreamController<List<int>> controller = StreamController(); - - controller.stream.listen((data) { - socket?.add(data); - }); - - try { - controller.add(frame); - // Remove the socket.flush() if it doesn't help. - // await socket?.flush(); - } catch (e) { - print('Error when adding to controller: $e'); - } finally { - controller.close(); - } - } on SocketException catch (e) { - throw TimeoutException('Socket write timed out', timeout); - } - } - - void close() { - socket?.close(); - } - - Future<List<int>> fillBuf2( - SocketWrapper socketwrapper, List<int> recvBuf, int n, - {Duration? timeout}) async { - final maxTime = timeout != null ? DateTime.now().add(timeout) : null; - - await for (var data in socketwrapper.socket!.cast<List<int>>()) { - print("DEBUG fillBuf2 1 - new data received: $data"); - if (maxTime != null && DateTime.now().isAfter(maxTime)) { - throw SocketException('Timeout'); - } - - if (data.isEmpty) { - if (recvBuf.isNotEmpty) { - throw SocketException('Connection ended mid-message.'); - } else { - throw SocketException('Connection ended while awaiting message.'); - } - } - - recvBuf.addAll(data); - print( - "DEBUG fillBuf2 2 - data added to recvBuf, new length: ${recvBuf.length}"); - - if (recvBuf.length >= n) { - print("DEBUG fillBuf2 3 - breaking loop, recvBuf is big enough"); - break; - } - } - - return recvBuf; - } - - Future<List<int>> fillBuf(int n, {Duration? timeout}) async { - var recvBuf = <int>[]; - socket?.listen((data) { - print('Received from server: $data'); - }, onDone: () { - print('Server closed connection.'); - socket?.destroy(); - }, onError: (error) { - print('Error: $error'); - socket?.destroy(); - }); - return recvBuf; - - StreamSubscription<List<int>>? subscription; // Declaration moved here - subscription = socket!.listen( - (List<int> data) { - recvBuf.addAll(data); - if (recvBuf.length >= n) { - subscription?.cancel(); - } - }, - onError: (e) { - subscription?.cancel(); - if (e is Exception) { - throw e; - } else { - throw Exception(e ?? 'Error in `subscription` socket!.listen'); - } - }, - onDone: () { - print("DEBUG ON DONE"); - if (recvBuf.length < n) { - throw SocketException( - 'Connection closed before enough data was received'); - } - }, - ); - - if (timeout != null) { - Future.delayed(timeout, () { - if (recvBuf.length < n) { - subscription?.cancel(); - throw SocketException('Timeout'); - } - }); - } - - return recvBuf; - } - - Future<List<int>> recv_message2(SocketWrapper socketwrapper, - {Duration? timeout}) async { - print("START OF RECV2"); - if (timeout == null) { - timeout = this.timeout; - } - - final maxTime = timeout != null ? DateTime.now().add(timeout) : null; - - List<int> recvBuf = []; - int bytesRead = 0; - - print("DEBUG recv_message2 1 - about to read the header"); - - try { - await for (var data in socketwrapper.receiveStream) { - if (maxTime != null && DateTime.now().isAfter(maxTime)) { - throw SocketException('Timeout'); - } - - if (data.isEmpty) { - if (recvBuf.isNotEmpty) { - throw SocketException('Connection ended mid-message.'); - } else { - throw SocketException('Connection ended while awaiting message.'); - } - } - - recvBuf.addAll(data); - - if (bytesRead < 12) { - bytesRead += data.length; - } - - if (recvBuf.length >= 12) { - final magic = recvBuf.sublist(0, 8); - - if (!ListEquality().equals(magic, Connection.magic)) { - throw BadFrameError('Bad magic in frame: ${hex.encode(magic)}'); - } - - final byteData = - ByteData.view(Uint8List.fromList(recvBuf.sublist(8, 12)).buffer); - final messageLength = byteData.getUint32(0, Endian.big); - - if (messageLength > MAX_MSG_LENGTH) { - throw BadFrameError( - 'Got a frame with msg_length=$messageLength > $MAX_MSG_LENGTH (max)'); - } - - /* - print("DEBUG recv_message2 3 - about to read the message body, messageLength: $messageLength"); - - print("DEBUG recvfbuf len is "); - print(recvBuf.length); - print("bytes read is "); - print(bytesRead); - print("message length is "); - print(messageLength); - - */ - if (recvBuf.length == bytesRead && bytesRead == 12 + messageLength) { - final message = recvBuf.sublist(12, 12 + messageLength); - - //print("DEBUG recv_message2 4 - message received, length: ${message.length}"); - //print("DEBUG recv_message2 5 - message content: $message"); - print("END OF RECV2"); - return message; - } else { - // Throwing exception if the length doesn't match - throw Exception( - 'Message length mismatch: expected ${12 + messageLength} bytes, received ${recvBuf.length} bytes.'); - } - } - } - } on SocketException catch (e) { - print('Socket exception: $e'); - } - - // This is a default return in case of exceptions. - return []; - } - - Future<List<int>> recv_message({Duration? timeout}) async { - // DEPRECATED - return []; - } -} // END OF CLASS diff --git a/lib/services/cashfusion/covert.dart b/lib/services/cashfusion/covert.dart deleted file mode 100644 index 62e5ed5a1..000000000 --- a/lib/services/cashfusion/covert.dart +++ /dev/null @@ -1,484 +0,0 @@ -import 'dart:async'; -import 'dart:collection'; -import 'dart:convert'; -import 'dart:io'; -import 'dart:math'; - -import 'package:protobuf/protobuf.dart' as pb; - -import 'comms.dart'; -import 'connection.dart'; -import 'fusion.pb.dart'; - -const int TOR_COOLDOWN_TIME = 660; -const int TIMEOUT_INACTIVE_CONNECTION = 120; - -class FusionError implements Exception { - String cause; - FusionError(this.cause); -} - -class Unrecoverable extends FusionError { - Unrecoverable(String cause) : super(cause); -} - -Future<bool> isTorPort(String host, int port) async { - if (port < 0 || port > 65535) { - return false; - } - - try { - Socket sock = - await Socket.connect(host, port, timeout: Duration(milliseconds: 100)); - sock.write("GET\n"); - List<int> data = await sock.first; - sock.destroy(); - if (utf8.decode(data).contains("Tor is not an HTTP Proxy")) { - return true; - } - } on SocketException { - return false; - } - - return false; -} - -class TorLimiter { - Queue<DateTime> deque = Queue<DateTime>(); - int lifetime; - // Declare a lock here, may need a special Dart package for this - int _count = 0; - - TorLimiter(this.lifetime); - - void cleanup() {} - - int get count { - // return some default value for now - return 0; - } - - void bump() {} -} - -TorLimiter limiter = TorLimiter(TOR_COOLDOWN_TIME); - -double randTrap(Random rng) { - final sixth = 1.0 / 6; - final f = rng.nextDouble(); - final fc = 1.0 - f; - - if (f < sixth) { - return sqrt(0.375 * f); - } else if (fc < sixth) { - return 1.0 - sqrt(0.375 * fc); - } else { - return 0.75 * f + 0.125; - } -} - -class CovertConnection { - Connection? connection; // replace dynamic with the type of your connection - int? slotNum; - DateTime? tPing; - int? connNumber; - Completer<bool> wakeup = Completer(); - double? delay; - - Future<bool> waitWakeupOrTime(DateTime? t) async { - if (t == null) { - return false; - } - - var remTime = t.difference(DateTime.now()).inMilliseconds; - remTime = remTime > 0 ? remTime : 0; - - await Future.delayed(Duration(milliseconds: remTime)); - wakeup.complete(true); - - var wasSet = await wakeup.future; - wakeup = Completer(); - return wasSet; - } - - void ping() { - if (this.connection != null) { - sendPb(this.connection!, CovertMessage, Ping(), - timeout: Duration(seconds: 1)); - } - - this.tPing = null; - } - - void inactive() { - throw Unrecoverable("Timed out from inactivity (this is a bug!)"); - } -} - -class CovertSlot { - int submitTimeout; - pb.GeneratedMessage? subMsg; // The work to be done. - bool done; // Whether last work requested is done. - CovertConnection? - covConn; // which CovertConnection is assigned to work on this slot - CovertSlot(this.submitTimeout) : done = true; - DateTime? t_submit; - - // Define a getter for tSubmit - DateTime? get tSubmit => t_submit; - - Future<void> submit() async { - var connection = covConn?.connection; - - if (connection == null) { - throw Unrecoverable('connection is null'); - } - - await sendPb(connection, CovertMessage, subMsg!, - timeout: Duration(seconds: submitTimeout)); - var result = await recvPb(connection, CovertResponse, ['ok', 'error'], - timeout: Duration(seconds: submitTimeout)); - - if (result.item1 == 'error') { - throw Unrecoverable('error from server: ${result.item2}'); - } - done = true; - t_submit = DateTime.fromMillisecondsSinceEpoch(0); - covConn?.tPing = DateTime.fromMillisecondsSinceEpoch( - 0); // if a submission is done, no ping is needed. - } -} - -class PrintError { - // Declare properties here -} - -class CovertSubmitter extends PrintError { - // Declare properties here - List<CovertSlot> slots; - bool done = true; - String failure_exception = ""; - int num_slots; - - bool stopping = false; - Map<String, dynamic>? proxyOpts; - String? randtag; - String? destAddr; - int? destPort; - bool ssl = false; - Object lock = Object(); - int countFailed = 0; - int countEstablished = 0; - int countAttempted = 0; - Random rng = Random.secure(); - int? randSpan; - DateTime? stopTStart; - List<CovertConnection> spareConnections = []; - String? failureException; - int submit_timeout = 0; - - CovertSubmitter( - String dest_addr, - int dest_port, - bool ssl, - String tor_host, - int tor_port, - this.num_slots, - double randSpan, // changed from int to double - double submit_timeout) // changed from int to double - : slots = List<CovertSlot>.generate( - num_slots, (index) => CovertSlot(submit_timeout.toInt())) { - // constructor body... - } - - void wakeAll() { - for (var s in slots) { - if (s.covConn != null) { - s.covConn!.wakeup.complete(); - } - } - for (var c in spareConnections) { - c.wakeup.complete(); - } - } - - void setStopTime(int tstart) { - this.stopTStart = DateTime.fromMillisecondsSinceEpoch(tstart * 1000); - if (this.stopping) { - this.wakeAll(); - } - } - - void stop([Exception? exception]) { - if (this.stopping) { - // already requested! - return; - } - this.failureException = exception?.toString(); - this.stopping = true; - var timeRemaining = - this.stopTStart?.difference(DateTime.now()).inSeconds ?? 0; - print( - "Stopping; connections will close in approximately $timeRemaining seconds"); - this.wakeAll(); - } - -// PYTHON USES MULTITHREADING, WHICH ISNT IMPLEMENTED HERE YET - void scheduleConnections(DateTime tStart, Duration tSpan, - {int numSpares = 0, int connectTimeout = 10}) { - var newConns = <CovertConnection>[]; - - for (var sNum = 0; sNum < this.slots.length; sNum++) { - var s = this.slots[sNum]; - if (s.covConn == null) { - s.covConn = CovertConnection(); - s.covConn?.slotNum = sNum; - CovertConnection? myCovConn = s.covConn; - if (myCovConn != null) { - newConns.add(myCovConn); - } - } - } - - var numNewSpares = max(0, numSpares - this.spareConnections.length); - var newSpares = List.generate(numNewSpares, (index) => CovertConnection()); - this.spareConnections = [...newSpares, ...this.spareConnections]; - - newConns.addAll(newSpares); - - for (var covConn in newConns) { - covConn.connNumber = this.countAttempted; - this.countAttempted++; - var connTime = tStart.add( - Duration(seconds: (tSpan.inSeconds * randTrap(this.rng)).round())); - var randDelay = (this.randSpan ?? 0) * randTrap(this.rng); - - runConnection( - covConn, connTime.millisecondsSinceEpoch, randDelay, connectTimeout); - } - } - - void scheduleSubmit( - int slotNum, DateTime tStart, pb.GeneratedMessage subMsg) { - var slot = slots[slotNum]; - - assert(slot.done, "tried to set new work when prior work not done"); - - slot.subMsg = subMsg; - slot.done = false; - slot.t_submit = tStart; - var covConn = slot.covConn; - if (covConn != null) { - covConn.wakeup.complete(); - } - } - - void scheduleSubmissions(DateTime tStart, List<dynamic> slotMessages) { - // Convert to list (Dart does not have tuples) - slotMessages = List.from(slotMessages); - - // Ensure that the number of slot messages equals the number of slots - assert(slotMessages.length == slots.length); - - // First, notify the spare connections that they will need to make a ping. - // Note that Dart does not require making a copy of the list before iteration, - // since Dart does not support mutation during iteration. - for (var c in spareConnections) { - c.tPing = tStart; - c.wakeup.complete(); - } - - // Then, notify the slots that there is a message to submit. - for (var i = 0; i < slots.length; i++) { - var slot = slots[i]; - var subMsg = slotMessages[i] as pb.GeneratedMessage; - var covConn = slot.covConn; - - if (covConn != null) { - if (subMsg == null) { - covConn.tPing = tStart; - } else { - slot.subMsg = subMsg; - slot.done = false; - slot.t_submit = tStart; - } - covConn.wakeup.complete(); - } - } - } - - Future runConnection(CovertConnection covConn, int connTime, double randDelay, - int connectTimeout) async { - // Main loop for connection thread - DateTime connDateTime = - DateTime.fromMillisecondsSinceEpoch(connTime * 1000); - while (await covConn.waitWakeupOrTime(connDateTime)) { - // if we are woken up before connection and stopping is happening, then just don't make a connection at all - if (this.stopping) { - return; - } - - final tBegin = DateTime.now().millisecondsSinceEpoch; - - try { - // STATE 1 - connecting - Map<String, dynamic> proxyOpts; - - if (this.proxyOpts == null) { - proxyOpts = {}; - } else { - final unique = 'CF${this.randtag}_${covConn.connNumber}'; - proxyOpts = { - 'proxy_username': unique, - 'proxy_password': unique, - }; - proxyOpts.addAll(this.proxyOpts!); - } - - limiter.bump(); - - try { - final connection = await openConnection( - this.destAddr!, this.destPort!, - connTimeout: connectTimeout.toDouble(), - ssl: this.ssl, - socksOpts: proxyOpts); - covConn.connection = connection; - } catch (e) { - this.countFailed++; - - final tEnd = DateTime.now().millisecondsSinceEpoch; - - print( - 'could not establish connection (after ${((tEnd - tBegin) / 1000).toStringAsFixed(3)}s): $e'); - rethrow; - } - - this.countEstablished++; - - final tEnd = DateTime.now().millisecondsSinceEpoch; - - print( - '[${covConn.connNumber}] connection established after ${((tEnd - tBegin) / 1000).toStringAsFixed(3)}s'); - - covConn.delay = (randTrap(this.rng) ?? 0) * (this.randSpan ?? 0); - - var lastActionTime = DateTime.now().millisecondsSinceEpoch; - - // STATE 2 - working - while (!this.stopping) { - DateTime? nextTime; - final slotNum = covConn.slotNum; - Function()? action; // callback to hold the action function - - // Second preference: submit something - if (slotNum != null) { - CovertSlot slot = this.slots[slotNum]; - nextTime = slot.tSubmit; - action = slot.submit; - } - // Third preference: send a ping - if (nextTime == null && covConn.tPing != null) { - nextTime = covConn.tPing; - action = covConn.ping; - } - // Last preference: wait doing nothing - if (nextTime == null) { - nextTime = DateTime.now() - .add(Duration(seconds: TIMEOUT_INACTIVE_CONNECTION)); - action = covConn.inactive; - } - - nextTime = nextTime.add(Duration(seconds: randDelay.toInt())); - - if (await covConn.waitWakeupOrTime(nextTime)) { - // got woken up ... let's go back and reevaluate what to do - continue; - } - - // reached action time, time to do it - final label = "[${covConn.connNumber}-$slotNum]"; - try { - await action?.call(); - } catch (e) { - print("$label error $e"); - rethrow; - } finally { - print("$label done"); - } - - lastActionTime = DateTime.now().millisecondsSinceEpoch; - } - - // STATE 3 - stopping - while (true) { - final stopTime = - this.stopTStart?.add(Duration(seconds: randDelay.toInt())) ?? - DateTime.now(); - - if (!(await covConn.waitWakeupOrTime(stopTime))) { - break; - } - } - - print("[${covConn.connNumber}] closing from stop"); - } catch (e) { - // in case of any problem, record the exception and if we have a slot, reassign it. - final exception = e; - - final slotNum = covConn.slotNum; - if (slotNum != null) { - try { - final spare = this.spareConnections.removeLast(); - // Found a spare. - this.slots[slotNum].covConn = spare; - spare.slotNum = slotNum; - spare.wakeup - .complete(); // python code is using set, possibly dealing wiht multi thread...double check this is ok. - - covConn.slotNum = null; - } catch (e) { - // We failed, and there are no spares. Party is over! - - if (exception is Exception) { - this.stop(exception); - } else { - // Handle the case where the exception is not an instance of Exception - } - } - } - } finally { - covConn.connection?.close(); - } - } - } - - void checkOk() { - // Implement checkOk logic here - var e = this.failure_exception; - if (e != null) { - throw FusionError('Covert connections failed: ${e.runtimeType} $e'); - } - } - - void checkConnected() { - // Implement checkConnected logic here - this.checkOk(); - var numMissing = - this.slots.where((s) => s.covConn?.connection == null).length; - if (numMissing > 0) { - throw FusionError( - "Covert connections were too slow ($numMissing incomplete out of ${this.slots.length})."); - } - } - - void checkDone() { - // Implement checkDone logic here - this.checkOk(); - var numMissing = this.slots.where((s) => !s.done).length; - if (numMissing > 0) { - throw FusionError( - "Covert submissions were too slow ($numMissing incomplete out of ${this.slots.length})."); - } - } -} diff --git a/lib/services/cashfusion/encrypt.dart b/lib/services/cashfusion/encrypt.dart deleted file mode 100644 index f6ffafe3e..000000000 --- a/lib/services/cashfusion/encrypt.dart +++ /dev/null @@ -1,136 +0,0 @@ -import 'dart:typed_data'; - -import 'package:crypto/crypto.dart' as crypto; -import 'package:cryptography/cryptography.dart'; -import 'package:pointycastle/pointycastle.dart' hide Mac; - -import 'util.dart'; - -final ECDomainParameters params = ECDomainParameters('secp256k1'); -final BigInt order = params.n; - -class EncryptionFailed implements Exception {} - -class DecryptionFailed implements Exception {} - -Future<Uint8List> encrypt(Uint8List message, ECPoint pubkey, - {int? padToLength}) async { - ECPoint pubpoint; - try { - pubpoint = Util.ser_to_point(pubkey.getEncoded(true), params); - } catch (_) { - throw EncryptionFailed(); - } - var nonceSec = Util.secureRandomBigInt(params.n.bitLength); - var G_times_nonceSec = params.G * nonceSec; - if (G_times_nonceSec == null) { - throw Exception('Multiplication of G with nonceSec resulted in null'); - } - var noncePub = Util.point_to_ser(G_times_nonceSec, true); - - var pubpoint_times_nonceSec = pubpoint * nonceSec; - if (pubpoint_times_nonceSec == null) { - throw Exception( - 'Multiplication of pubpoint with nonceSec resulted in null'); - } - var key = crypto.sha256 - .convert(Util.point_to_ser(pubpoint_times_nonceSec, true)) - .bytes; - - var plaintext = Uint8List(4 + message.length) - ..buffer.asByteData().setUint32(0, message.length, Endian.big) - ..setRange(4, 4 + message.length, message); - if (padToLength == null) { - padToLength = - ((plaintext.length + 15) ~/ 16) * 16; // round up to nearest 16 - } else if (padToLength % 16 != 0) { - throw ArgumentError('$padToLength not multiple of 16'); - } - if (padToLength < plaintext.length) { - throw ArgumentError('$padToLength < ${plaintext.length}'); - } - plaintext = Uint8List(padToLength) - ..setRange(0, message.length + 4, plaintext); - - final secretKey = SecretKey(key); - - final macAlgorithm = Hmac(Sha256()); - - final cipher = AesCbc.with128bits(macAlgorithm: macAlgorithm); - - final nonce = Uint8List(16); // Random nonce - final secretBox = - await cipher.encrypt(plaintext, secretKey: secretKey, nonce: nonce); - - final ciphertext = secretBox.cipherText; - - return Uint8List( - noncePub.length + ciphertext.length + secretBox.mac.bytes.length) - ..setRange(0, noncePub.length, noncePub) - ..setRange(noncePub.length, noncePub.length + ciphertext.length, ciphertext) - ..setRange( - noncePub.length + ciphertext.length, - noncePub.length + ciphertext.length + secretBox.mac.bytes.length, - secretBox.mac.bytes); -} - -Future<Uint8List> decryptWithSymmkey(Uint8List data, Uint8List key) async { - if (data.length < 33 + 16 + 16) { - throw DecryptionFailed(); - } - var ciphertext = data.sublist(33, data.length - 16); - if (ciphertext.length % 16 != 0) { - throw DecryptionFailed(); - } - - final secretKey = SecretKey(key); - final cipher = AesCbc.with128bits(macAlgorithm: Hmac.sha256()); - final nonce = Uint8List(16); // Random nonce - - final secretBox = SecretBox(ciphertext, - mac: Mac(data.sublist(data.length - 16)), nonce: nonce); - final plaintext = await cipher.decrypt(secretBox, secretKey: secretKey); - - if (plaintext.length < 4) { - throw DecryptionFailed(); - } - - Uint8List uint8list = Uint8List.fromList(plaintext); - ByteData byteData = ByteData.sublistView(uint8list); - var msgLength = byteData.getUint32(0, Endian.big); - - if (msgLength + 4 > plaintext.length) { - throw DecryptionFailed(); - } - return Uint8List.fromList(plaintext.sublist(4, 4 + msgLength)); -} - -Future<Tuple<Uint8List, Uint8List>> decrypt( - Uint8List data, ECPrivateKey privkey) async { - if (data.length < 33 + 16 + 16) { - throw DecryptionFailed(); - } - var noncePub = data.sublist(0, 33); - ECPoint noncePoint; - try { - noncePoint = Util.ser_to_point(noncePub, params); - } catch (_) { - throw DecryptionFailed(); - } - - // DOUBLE CHECK THIS IS RIGHT IDEA MATCHING PYTHON. - - ECPoint G = params.G; - final List<int> key; - - if (privkey.d != null) { - var point = (G * privkey.d)! + noncePoint; - key = crypto.sha256.convert(Util.point_to_ser(point!, true)).bytes; - // ... - var decryptedData = await decryptWithSymmkey(data, Uint8List.fromList(key)); - return Tuple(decryptedData, Uint8List.fromList(key)); - } else { - // Handle the situation where privkey.d or noncePoint is null - throw Exception("FIXME"); - } -} diff --git a/lib/services/cashfusion/fusion.dart b/lib/services/cashfusion/fusion.dart deleted file mode 100644 index 1ce397a71..000000000 --- a/lib/services/cashfusion/fusion.dart +++ /dev/null @@ -1,1574 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; -import 'dart:math'; -import 'dart:typed_data'; - -import 'package:collection/collection.dart'; -import 'package:crypto/crypto.dart'; -import 'package:fixnum/fixnum.dart'; -import "package:pointycastle/export.dart"; -import 'package:protobuf/protobuf.dart'; -import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; - -import 'comms.dart'; -import 'connection.dart'; -import 'covert.dart'; -import 'encrypt.dart'; -import 'fusion.pb.dart'; -import 'pedersen.dart'; -import 'protocol.dart'; -import 'socketwrapper.dart'; -import 'util.dart'; -import 'validation.dart'; - -class FusionError implements Exception { - final String message; - - FusionError(this.message); - - String toString() => "FusionError: $message"; -} - -class ComponentResult { - final Uint8List commitment; - final int counter; - final Uint8List component; - final Proof proof; - final Uint8List privateKey; - final dynamic pedersenAmount; // replace dynamic with actual type - final dynamic pedersenNonce; // replace dynamic with actual type - - ComponentResult(this.commitment, this.counter, this.component, this.proof, - this.privateKey, - {this.pedersenAmount, this.pedersenNonce}); -} - -class Transaction { - List<Input> Inputs = []; - List<Output> Outputs = []; - - Transaction(); - - static Tuple txFromComponents( - List<dynamic> allComponents, List<dynamic> sessionHash) { - Transaction tx = Transaction(); // Initialize a new Transaction - // This should be based on wallet layer... implement the logic of constructing the transaction from components - // For now, it just initializes Inputs and Outputs as empty lists - tx.Inputs = []; - tx.Outputs = []; - - // For now, just returning an empty list for inputIndices - List<int> inputIndices = []; - - return Tuple(tx, inputIndices); - } - - List<int> serializePreimage(int index, int hashType, {bool useCache = true}) { - // Add implementation here - // For now, returning an empty byte array - return []; - } - - String serialize() { - // To implement... - return ""; - } - - bool isComplete() { - // implement based on wallet. - return true; - } - - String txid() { - // To implement... - return ""; - } -} - -class Input { - List<int> prevTxid; - int prevIndex; - List<int> pubKey; - int amount; - List<dynamic> signatures = []; - - Input( - {required this.prevTxid, - required this.prevIndex, - required this.pubKey, - required this.amount}); - - int sizeOfInput() { - assert(1 < pubKey.length && - pubKey.length < 76); // need to assume regular push opcode - return 108 + pubKey.length; - } - - int get value { - return amount; - } - - String getPubKey(int pubkey_index) { - // TO BE IMPLEMENTED... - return ""; - } - - String getPrivKey(int pubkey_index) { - // TO BE IMPLEMENTED... - return ""; - } - - static Input fromInputComponent(InputComponent inputComponent) { - return Input( - prevTxid: inputComponent.prevTxid, // Make sure the types are matching - prevIndex: inputComponent.prevIndex.toInt(), - pubKey: inputComponent.pubkey, - amount: inputComponent.amount.toInt(), - ); - } - - static Input fromStackUTXO(UTXO utxo) { - return Input( - prevTxid: utf8.encode(utxo.txid), // Convert txid to a List<int> - prevIndex: utxo.vout, - pubKey: utf8.encode('0000'), // Placeholder - amount: utxo.value, - ); - } -} - -class Output { - int value; - Address addr; - - int amount = 0; - - Output({required this.value, required this.addr}); - - int sizeOfOutput() { - List<int> scriptpubkey = addr - .toScript(); // assuming addr.toScript() returns List<int> that represents the scriptpubkey - assert(scriptpubkey.length < 253); - return 9 + scriptpubkey.length; - } - - static Output fromOutputComponent(OutputComponent outputComponent) { - Address address = Address.fromScriptPubKey(outputComponent.scriptpubkey); - return Output( - value: outputComponent.amount.toInt(), - addr: address, - ); - } -} - -// Class to handle fusion -class Fusion { - List<Input> coins = - []; //"coins" and "inputs" are often synonmous in the original python code. - List<Output> outputs = []; - bool server_connected_and_greeted = false; - bool stopping = false; - bool stopping_if_not_running = false; - String stopReason = ""; - String tor_host = ""; - bool server_ssl = false; - String server_host = "cashfusion.stackwallet.com"; - int server_port = 8787; - - //String server_host = "fusion.servo.cash"; - //int server_port = 8789; - - int tor_port = 0; - int roundcount = 0; - String txid = ""; - - Tuple<String, String> status = Tuple("", ""); - Connection? connection; - - int numComponents = 0; - double componentFeeRate = 0; - double minExcessFee = 0; - double maxExcessFee = 0; - List<int> availableTiers = []; - - int maxOutputs = 0; - int safety_sum_in = 0; - Map<int, int> safety_exess_fees = {}; - Map<int, List<int>> tierOutputs = - {}; // not sure if this should be using outputs class. - - int inactiveTimeLimit = 0; - int tier = 0; - int covertPort = 0; - bool covertSSL = false; - double beginTime = 0.0; // represent time in seconds. - List<int> lastHash = <int>[]; - List<Address> reservedAddresses = <Address>[]; - int safetyExcessFee = 0; - DateTime t_fusionBegin = DateTime.now(); - Uint8List covertDomainB = Uint8List(0); - - var txInputIndices; - Transaction tx = Transaction(); - List<int> myComponentIndexes = []; - List<int> myCommitmentIndexes = []; - Set<int> badComponents = {}; - - Fusion() { - //initializeConnection(host, port) - } - - /* - Future<void> initializeConnection(String host, int port) async { - Socket socket = await Socket.connect(host, port); - connection = Connection()..socket = socket; - } -*/ - - Future<void> add_coins_from_wallet(List<UTXO> utxoList) async { - // Convert each UTXO to an Input and add to 'coins' - for (UTXO utxo in utxoList) { - coins.add(Input.fromStackUTXO(utxo)); - } - } - - Future<void> fusion_run() async { - print("DEBUG FUSION 223...fusion run...."); - try { - try { - // Check compatibility - This was done in python version to see if fast libsec installed. - // For now , in dart, just pass this test. - ; - } on Exception catch (e) { - // handle exception, rethrow as a custom FusionError - throw FusionError("Incompatible: " + e.toString()); - } - - // Check if can connect to Tor proxy, if not, raise FusionError. Empty String treated as no host. - if (tor_host.isNotEmpty && - tor_port != 0 && - !await isTorPort(tor_host, tor_port)) { - throw FusionError("Can't connect to Tor proxy at $tor_host:$tor_port"); - } - - try { - // Check stop condition - check_stop(running: false); - } catch (e) { - print(e); - } - - try { - // Check coins - check_coins(); - } catch (e) { - print(e); - } - - // Connect to server - status = Tuple("connecting", ""); - try { - connection = await openConnection(server_host, server_port, - connTimeout: 5.0, defaultTimeout: 5.0, ssl: server_ssl); - } catch (e) { - print("Connect failed: $e"); - String sslstr = server_ssl ? ' SSL ' : ''; - throw FusionError( - 'Could not connect to $sslstr$server_host:$server_port'); - } - - // Once connection is successful, wrap operations inside this block - // Within this block, version checks, downloads server params, handles coins and runs rounds - try { - SocketWrapper socketwrapper = SocketWrapper(server_host, server_port); - await socketwrapper.connect(); - - // Version check and download server params. - await greet(socketwrapper); - - socketwrapper.status(); - server_connected_and_greeted = true; - notify_server_status(true); - - // In principle we can hook a pause in here -- user can insert coins after seeing server params. - - try { - if (coins.isEmpty) { - throw FusionError('Started with no coins'); - return; - } - } catch (e) { - print(e); - return; - } - - await allocateOutputs(socketwrapper); - // In principle we can hook a pause in here -- user can tweak tier_outputs, perhaps cancelling some unwanted tiers. - - // Register for tiers, wait for a pool. - await registerAndWait(socketwrapper); - - print("FUSION DEBUG 273"); - print("RETURNING early in fusion_run...."); - return; - - // launch the covert submitter - CovertSubmitter covert = await start_covert(); - try { - // Pool started. Keep running rounds until fail or complete. - while (true) { - roundcount += 1; - if (await run_round(covert)) { - break; - } - } - } finally { - covert.stop(); - } - } finally { - (await connection)?.close(); - } - - for (int i = 0; i < 60; i++) { - if (stopping) { - break; // not an error - } - - if (Util.walletHasTransaction(txid)) { - break; - } - - await Future.delayed(Duration(seconds: 1)); - } - - // Set status to 'complete' with 'time_wait' - status = Tuple('complete', 'txid: $txid'); - - // Wait for transaction to show up in wallets - // Set status to 'complete' with txid - } on FusionError catch (err) { - print('Failed: ${err}'); - status.item1 = "failed"; - status.item2 = err.toString(); // setting the error message - } catch (exc) { - print('Exception: ${exc}'); - status.item1 = "failed"; - status.item2 = - "Exception: ${exc.toString()}"; // setting the exception message - } finally { - clear_coins(); - if (status.item1 != 'complete') { - for (var output in outputs) { - Util.unreserve_change_address(output.addr); - } - if (!server_connected_and_greeted) { - notify_server_status(false, tup: status); - } - } - } - } // end fusion_run function. - - Future<CovertSubmitter> start_covert() async { - // Function implementation here... - - // For now, just return a new instance of CovertSubmitter - return CovertSubmitter("dummy", 0, true, "some_host", 0, 0, 0, 0); - } - - Future<bool> run_round(CovertSubmitter covert) async { - // function implementation here... - - // placeholder return statement - return Future.value(false); - } - - void notify_server_status(bool b, {Tuple? tup}) { - // Function implementation goes here - } - - void stop([String reason = 'stopped', bool notIfRunning = false]) { - if (stopping) { - return; - } - if (notIfRunning) { - if (stopping_if_not_running) { - return; - } - stopReason = reason; - stopping_if_not_running = true; - } else { - stopReason = reason; - stopping = true; - } - // note the reason is only overwritten if we were not already stopping this way. - } - - void check_stop({bool running = true}) { - // Gets called occasionally from fusion thread to allow a stop point. - if (stopping || (!running && stopping_if_not_running)) { - throw FusionError(stopReason ?? 'Unknown stop reason'); - } - } - - void check_coins() { - // Implement by calling wallet layer to check the coins are ok. - return; - } - - static void foo() { - print("hello"); - } - - void clear_coins() { - coins = []; - } - - void addCoins(List<Input> newCoins) { - coins.addAll(newCoins); - } - - void notify_coins_UI() { - return; - } - - static bool walletCanFuse() { - return true; - - // Implement logic here to return false if the wallet can't fuse. (If its read only or non P2PKH) - } - - static double nextDoubleNonZero(Random rng) { - double value = 0.0; - while (value == 0.0) { - value = rng.nextDouble(); - } - return value; - } - - static List<int>? randomOutputsForTier( - Random rng, int inputAmount, int scale, int offset, int maxCount) { - if (inputAmount < offset) { - return []; - } - double lambd = 1.0 / scale; - int remaining = inputAmount; - List<double> values = []; // list of fractional random values without offset - bool didBreak = - false; // Add this flag to detect when a break is encountered - - for (int i = 0; i < maxCount + 1; i++) { - double val = -lambd * log(nextDoubleNonZero(rng)); - remaining -= (val.ceil() + offset); - if (remaining < 0) { - didBreak = true; // If you break, set this flag to true - break; - } - values.add(val); - } - - if (!didBreak && values.length > maxCount) { - values = values.sublist(0, maxCount); - } - - if (values.isEmpty) { - // Our first try put us over the limit, so we have nothing to work with. - // (most likely, scale was too large) - return []; - } - - int desiredRandomSum = inputAmount - values.length * offset; - assert(desiredRandomSum >= 0, 'desiredRandomSum is less than 0'); - - /*Now we need to rescale and round the values so they fill up the desired. - input amount exactly. We perform rounding in cumulative space so that the - sum is exact, and the rounding is distributed fairly. - */ - - // Dart equivalent of itertools.accumulate - List<double> cumsum = []; - double sum = 0; - for (double value in values) { - sum += value; - cumsum.add(sum); - } - - double rescale = desiredRandomSum / cumsum[cumsum.length - 1]; - List<int> normedCumsum = cumsum.map((v) => (rescale * v).round()).toList(); - assert(normedCumsum[normedCumsum.length - 1] == desiredRandomSum, - 'Last element of normedCumsum is not equal to desiredRandomSum'); - List<int> differences = []; - differences.add(normedCumsum[0]); // First element - for (int i = 1; i < normedCumsum.length; i++) { - differences.add(normedCumsum[i] - normedCumsum[i - 1]); - } - - List<int> result = differences.map((d) => offset + d).toList(); - assert(result.reduce((a, b) => a + b) == inputAmount, - 'Sum of result is not equal to inputAmount'); - return result; - } - - static List<ComponentResult> genComponents( - int numBlanks, List<Input> inputs, List<Output> outputs, int feerate) { - assert(numBlanks >= 0); - - List<Tuple<Component, int>> components = []; - - // Set up Pedersen setup instance - Uint8List HBytes = Uint8List.fromList( - [0x02] + 'CashFusion gives us fungibility.'.codeUnits); - ECDomainParameters params = ECDomainParameters('secp256k1'); - ECPoint? HMaybe = params.curve.decodePoint(HBytes); - if (HMaybe == null) { - throw Exception('Failed to decode point'); - } - ECPoint H = HMaybe; - PedersenSetup setup = PedersenSetup(H); - - for (Input input in inputs) { - int fee = Util.componentFee(input.sizeOfInput(), feerate); - - var comp = Component(); - comp.input = InputComponent( - prevTxid: Uint8List.fromList(input.prevTxid.reversed.toList()), - prevIndex: input.prevIndex, - pubkey: input.pubKey, - amount: Int64(input.amount)); - components.add(Tuple<Component, int>(comp, input.amount - fee)); - } - - for (Output output in outputs) { - var script = output.addr.toScript(); - int fee = Util.componentFee(output.sizeOfOutput(), feerate); - - var comp = Component(); - comp.output = - OutputComponent(scriptpubkey: script, amount: Int64(output.value)); - components.add(Tuple<Component, int>(comp, -output.value - fee)); - } - - for (int i = 0; i < numBlanks; i++) { - var comp = Component(); - comp.blank = BlankComponent(); - components.add(Tuple<Component, int>(comp, 0)); - } - - List<ComponentResult> resultList = []; - - components.asMap().forEach((cnum, Tuple<Component, int> componentTuple) { - Uint8List salt = Util.tokenBytes(32); - componentTuple.item1.saltCommitment = Util.sha256(salt); - var compser = componentTuple.item1.writeToBuffer(); - - Tuple<Uint8List, Uint8List> keyPair = Util.genKeypair(); - Uint8List privateKey = keyPair.item1; - Uint8List pubKey = keyPair.item2; - - Commitment commitmentInstance = - setup.commit(BigInt.from(componentTuple.item2)); - Uint8List amountCommitment = commitmentInstance.PUncompressed; - -// Convert BigInt nonce to Uint8List - Uint8List pedersenNonce = Uint8List.fromList( - [int.parse(commitmentInstance.nonce.toRadixString(16), radix: 16)]); - -// Generating initial commitment - InitialCommitment commitment = InitialCommitment( - saltedComponentHash: - Util.sha256(Uint8List.fromList([...compser, ...salt])), - amountCommitment: amountCommitment, - communicationKey: pubKey); - - Uint8List commitser = commitment.writeToBuffer(); - - // Generating proof - Proof proof = - Proof(componentIdx: cnum, salt: salt, pedersenNonce: pedersenNonce); - - // Adding result to list - resultList - .add(ComponentResult(commitser, cnum, compser, proof, privateKey)); - }); - - return resultList; - } - - Future<GeneratedMessage> recv2( - SocketWrapper socketwrapper, List<String> expectedMsgNames, - {Duration? timeout}) async { - if (connection == null) { - throw FusionError('Connection not initialized'); - } - - var result = await recvPb2( - socketwrapper, connection!, ServerMessage, expectedMsgNames, - timeout: timeout); - - var submsg = result.item1; - var mtype = result.item2; - - if (mtype == 'error') { - throw FusionError('server error: ${submsg.toString()}'); - } - - return submsg; - } - - Future<GeneratedMessage> recv(List<String> expectedMsgNames, - {Duration? timeout}) async { - // DEPRECATED - if (connection == null) { - throw FusionError('Connection not initialized'); - } - - var result = await recvPb(connection!, ServerMessage, expectedMsgNames, - timeout: timeout); - - var submsg = result.item1; - var mtype = result.item2; - - if (mtype == 'error') { - throw FusionError('server error: ${submsg.toString()}'); - } - - return submsg; - } - - Future<void> send(GeneratedMessage submsg, {Duration? timeout}) async { - // DEPRECATED - if (connection != null) { - await sendPb(connection!, ClientMessage, submsg, timeout: timeout); - } else { - print('Connection is null'); - } - } - - Future<void> send2(SocketWrapper socketwrapper, GeneratedMessage submsg, - {Duration? timeout}) async { - if (connection != null) { - await sendPb2(socketwrapper, connection!, ClientMessage, submsg, - timeout: timeout); - } else { - print('Connection is null'); - } - } - - Future<void> greet(SocketWrapper socketwrapper) async { - ClientHello clientHello = ClientHello( - version: Uint8List.fromList(utf8.encode(Protocol.VERSION)), - genesisHash: Util.get_current_genesis_hash()); - - ClientMessage clientMessage = ClientMessage()..clienthello = clientHello; - - //deprecated - //Connection greet_connection_1 = Connection.withoutSocket(); - - /* - lets move this up a level to the fusion_run and pass it in.... - SocketWrapper socketwrapper = SocketWrapper(server_host, server_port); - await socketwrapper.connect(); -*/ - send2(socketwrapper, clientMessage); - - var replyMsg = await recv2(socketwrapper, ['serverhello']); - if (replyMsg is ServerMessage) { - ServerHello reply = replyMsg.serverhello; - - numComponents = reply.numComponents; - componentFeeRate = reply.componentFeerate.toDouble(); - minExcessFee = reply.minExcessFee.toDouble(); - maxExcessFee = reply.maxExcessFee.toDouble(); - availableTiers = reply.tiers.map((tier) => tier.toInt()).toList(); - - // Enforce some sensible limits, in case server is crazy - if (componentFeeRate > Protocol.MAX_COMPONENT_FEERATE) { - throw FusionError('excessive component feerate from server'); - } - if (minExcessFee > 400) { - // note this threshold should be far below MAX_EXCESS_FEE - throw FusionError('excessive min excess fee from server'); - } - if (minExcessFee > maxExcessFee) { - throw FusionError('bad config on server: fees'); - } - if (numComponents < Protocol.MIN_TX_COMPONENTS * 1.5) { - throw FusionError('bad config on server: num_components'); - } - } else { - throw Exception( - 'Received unexpected message type: ${replyMsg.runtimeType}'); - } - } - - Future<void> allocateOutputs(socketwrapper) async { - print("DBUG allocateoutputs 746"); - - print("CHECK socketwrapper 746"); - socketwrapper.status(); - assert(['setup', 'connecting'].contains(status.item1)); - - List<Input> inputs = coins; - int numInputs = inputs.length; - - int maxComponents = min(numComponents, Protocol.MAX_COMPONENTS); - int maxOutputs = maxComponents - numInputs; - if (maxOutputs < 1) { - throw FusionError('Too many inputs ($numInputs >= $maxComponents)'); - } - - if (maxOutputs != null) { - assert(maxOutputs >= 1); - maxOutputs = min(maxOutputs, maxOutputs); - } - - int numDistinct = inputs.map((e) => e.value).toSet().length; - int minOutputs = max(Protocol.MIN_TX_COMPONENTS - numDistinct, 1); - if (maxOutputs < minOutputs) { - throw FusionError( - 'Too few distinct inputs selected ($numDistinct); cannot satisfy output count constraint (>= $minOutputs, <= $maxOutputs)'); - } - - int sumInputsValue = inputs.map((e) => e.value).reduce((a, b) => a + b); - int inputFees = inputs - .map( - (e) => Util.componentFee(e.sizeOfInput(), componentFeeRate.toInt())) - .reduce((a, b) => a + b); - int availForOutputs = sumInputsValue - inputFees - minExcessFee.toInt(); - - int feePerOutput = Util.componentFee(34, componentFeeRate.toInt()); - - int offsetPerOutput = Protocol.MIN_OUTPUT + feePerOutput; - - if (availForOutputs < offsetPerOutput) { - throw FusionError('Selected inputs had too little value'); - } - - var rng = Random(); - var seed = List<int>.generate(32, (_) => rng.nextInt(256)); - - print("DBUG allocateoutputs 785"); - tierOutputs = {}; - var excessFees = <int, int>{}; - for (var scale in availableTiers) { - int fuzzFeeMax = scale ~/ 1000000; - int fuzzFeeMaxReduced = min( - fuzzFeeMax, - min(Protocol.MAX_EXCESS_FEE - minExcessFee.toInt(), - maxExcessFee.toInt())); - - assert(fuzzFeeMaxReduced >= 0); - int fuzzFee = rng.nextInt(fuzzFeeMaxReduced + 1); - - int reducedAvailForOutputs = availForOutputs - fuzzFee; - if (reducedAvailForOutputs < offsetPerOutput) { - continue; - } - - var outputs = randomOutputsForTier( - rng, reducedAvailForOutputs, scale, offsetPerOutput, maxOutputs); - if (outputs != null) { - print(outputs); - } - if (outputs == null || outputs.length < minOutputs) { - continue; - } - outputs = outputs.map((o) => o - feePerOutput).toList(); - - assert(inputs.length + (outputs?.length ?? 0) <= Protocol.MAX_COMPONENTS); - - excessFees[scale] = sumInputsValue - inputFees - reducedAvailForOutputs; - tierOutputs[scale] = outputs!; - } - - print('Possible tiers: $tierOutputs'); - - safety_sum_in = sumInputsValue; - safety_exess_fees = excessFees; - return; - } - - Future<void> registerAndWait(SocketWrapper socketwrapper) async { - print("DEBUG register and wait top."); - // msg can be different classes depending on which protobuf msg is sent. - dynamic? msg; - - var tierOutputs = this.tierOutputs; - var tiersSorted = tierOutputs.keys.toList()..sort(); - - if (tierOutputs.isEmpty) { - throw FusionError( - 'No outputs available at any tier (selected inputs were too small / too large).'); - } - - print('registering for tiers: $tiersSorted'); - - int self_fuse = 1; // Temporary value for now - var cashfusionTag = [1]; // temp value for now - - check_stop(running: false); - check_coins(); - - var tags = [JoinPools_PoolTag(id: cashfusionTag, limit: self_fuse)]; - -// Create JoinPools message - JoinPools joinPools = - JoinPools(tiers: tiersSorted.map((i) => Int64(i)).toList(), tags: tags); - -// Wrap it in a ClientMessage - ClientMessage clientMessage = ClientMessage()..joinpools = joinPools; - - send2(socketwrapper, clientMessage); - - status = Tuple<String, String>('waiting', 'Registered for tiers'); - - var tiersStrings = { - for (var entry in tierOutputs.entries) - entry.key: - (entry.key * 1e-8).toStringAsFixed(8).replaceAll(RegExp(r'0+$'), '') - }; - - while (true) { - print("RECEIVE LOOP 870............DEBUG"); - var msg = await recv2(socketwrapper, ['tierstatusupdate', 'fusionbegin'], - timeout: Duration(seconds: 10)); - - var fieldInfoFusionBegin = msg.info_.byName["fusionbegin"]; - if (fieldInfoFusionBegin != null && - msg.hasField(fieldInfoFusionBegin.tagNumber)) { - break; - } - - check_stop(running: false); - check_coins(); - - // Define the bool variable - - var fieldInfo = msg.info_.byName["tierstatusupdate"]; - if (fieldInfo == null) { - throw FusionError( - 'Expected field not found in message: tierstatusupdate'); - } - - bool messageIsTierStatusUpdate = msg.hasField(fieldInfo.tagNumber); - - if (!messageIsTierStatusUpdate) { - throw FusionError('Expected a TierStatusUpdate message'); - } - - late var statuses; - if (messageIsTierStatusUpdate) { - //TierStatusUpdate tierStatusUpdate = msg.tierstatusupdate; - var tierStatusUpdate = - msg.getField(fieldInfo.tagNumber) as TierStatusUpdate; - statuses = tierStatusUpdate.statuses; - } - - double maxfraction = 0.0; - var maxtiers = <int>[]; - int? besttime; - int? besttimetier; - for (var entry in statuses.entries) { - double frac = - entry.value.players.toInt() / entry.value.minPlayers.toInt(); - if (frac >= maxfraction) { - if (frac > maxfraction) { - maxfraction = frac; - maxtiers.clear(); - } - maxtiers.add(entry.key.toInt()); - } - - var fieldInfoTimeRemaining = entry.value.info_.byName["timeRemaining"]; - if (fieldInfoTimeRemaining == null) { - throw FusionError( - 'Expected field not found in message: timeRemaining'); - } - - if (entry.value.hasField(fieldInfoTimeRemaining.tagNumber)) { - int tr = entry.value.timeRemaining.toInt(); - if (besttime == null || tr < besttime) { - besttime = tr; - besttimetier = entry.key.toInt(); - } - } - } - - var displayBest = <String>[]; - var displayMid = <String>[]; - var displayQueued = <String>[]; - for (var tier in tiersSorted) { - if (statuses.containsKey(tier)) { - var tierStr = tiersStrings[tier]; - if (tierStr == null) { - throw FusionError( - 'server reported status on tier we are not registered for'); - } - if (tier == besttimetier) { - displayBest.insert(0, '**$tierStr**'); - } else if (maxtiers.contains(tier)) { - displayBest.add('[$tierStr]'); - } else { - displayMid.add(tierStr); - } - } else { - displayQueued.add(tiersStrings[tier]!); - } - } - - var parts = <String>[]; - if (displayBest.isNotEmpty || displayMid.isNotEmpty) { - parts.add("Tiers: ${displayBest.join(', ')} ${displayMid.join(', ')}"); - } - if (displayQueued.isNotEmpty) { - parts.add("Queued: ${displayQueued.join(', ')}"); - } - var tiersString = parts.join(' '); - - if (besttime == null && inactiveTimeLimit != null) { - if (DateTime.now().millisecondsSinceEpoch > inactiveTimeLimit) { - throw FusionError('stopping due to inactivity'); - } - } - - if (besttime != null) { - status = Tuple<String, String>( - 'waiting', 'Starting in ${besttime}s. $tiersString'); - } else if (maxfraction >= 1) { - status = - Tuple<String, String>('waiting', 'Starting soon. $tiersString'); - } else if (displayBest.isNotEmpty || displayMid.isNotEmpty) { - status = Tuple<String, String>( - 'waiting', '${(maxfraction * 100).round()}% full. $tiersString'); - } else { - status = Tuple<String, String>('waiting', tiersString); - } - } - - var fieldInfoFusionBegin = msg.info_.byName["fusionbegin"]; - if (fieldInfoFusionBegin == null) { - throw FusionError('Expected field not found in message: fusionbegin'); - } - - bool messageIsFusionBegin = msg.hasField(fieldInfoFusionBegin.tagNumber); - if (!messageIsFusionBegin) { - throw FusionError('Expected a FusionBegin message'); - } - - t_fusionBegin = DateTime.now(); - - var clockMismatch = - msg.serverTime - DateTime.now().millisecondsSinceEpoch / 1000; - if (clockMismatch.abs() > Protocol.MAX_CLOCK_DISCREPANCY) { - throw FusionError( - "Clock mismatch too large: ${clockMismatch.toStringAsFixed(3)}."); - } - - tier = msg.tier; - if (msg is FusionBegin) { - covertDomainB = Uint8List.fromList(msg.covertDomain); - } - - covertPort = msg.covertPort; - covertSSL = msg.covertSSL; - beginTime = msg.serverTime; - - lastHash = Util.calcInitialHash( - tier, covertDomainB, covertPort, covertSSL, beginTime); - - var outAmounts = tierOutputs[tier]; - var outAddrs = Util.reserve_change_addresses(outAmounts?.length ?? 0); - - reservedAddresses = outAddrs; - outputs = Util.zip(outAmounts ?? [], outAddrs) - .map((pair) => Output(value: pair[0], addr: pair[1])) - .toList(); - - safetyExcessFee = safety_exess_fees[tier] ?? 0; - - print( - "starting fusion rounds at tier $tier: ${coins.length} inputs and ${outputs.length} outputs"); - } - - Future<CovertSubmitter> startCovert() async { - status = Tuple('running', 'Setting up Tor connections'); - - String covertDomain; - try { - covertDomain = utf8.decode(covertDomainB); - } catch (e) { - throw FusionError('badly encoded covert domain'); - } - CovertSubmitter covert = CovertSubmitter( - covertDomain, - covertPort, - covertSSL, - tor_host, - tor_port, - numComponents, - Protocol.COVERT_SUBMIT_WINDOW, - Protocol.COVERT_SUBMIT_TIMEOUT); - try { - covert.scheduleConnections(t_fusionBegin, - Duration(seconds: Protocol.COVERT_CONNECT_WINDOW.toInt()), - numSpares: Protocol.COVERT_CONNECT_SPARES.toInt(), - connectTimeout: Protocol.COVERT_CONNECT_TIMEOUT.toInt()); - - // loop until a just a bit before we're expecting startRound, watching for status updates - final tend = t_fusionBegin.add(Duration( - seconds: (Protocol.WARMUP_TIME - Protocol.WARMUP_SLOP - 1).round())); - - while (DateTime.now().millisecondsSinceEpoch / 1000 < - tend.millisecondsSinceEpoch / 1000) { - int numConnected = - covert.slots.where((s) => s.covConn?.connection != null).length; - - int numSpareConnected = - covert.spareConnections.where((c) => c.connection != null).length; - - status = Tuple('running', - 'Setting up Tor connections ($numConnected+$numSpareConnected out of $numComponents)'); - - await Future.delayed(Duration(seconds: 1)); - - covert.checkOk(); - this.check_stop(); - this.check_coins(); - } - } catch (e) { - covert.stop(); - rethrow; - } - - return covert; - } - - void runRound(CovertSubmitter covert) async { - status = Tuple('running', 'Starting round ${roundcount.toString()}'); - int timeoutInSeconds = - (2 * Protocol.WARMUP_SLOP + Protocol.STANDARD_TIMEOUT).toInt(); - var msg = await recv(['startround'], - timeout: Duration(seconds: timeoutInSeconds)); - - // Record the time we got this message; it forms the basis time for all covert activities. - final covertT0 = DateTime.now().millisecondsSinceEpoch / 1000; - double covertClock() => - (DateTime.now().millisecondsSinceEpoch / 1000) - covertT0; - - final roundTime = (msg as StartRound).serverTime; - - // Check the server's declared unix time, which will be committed. - final clockMismatch = (msg as StartRound).serverTime - - DateTime.now().millisecondsSinceEpoch / 1000; - if (clockMismatch.abs() > Protocol.MAX_CLOCK_DISCREPANCY) { - throw FusionError( - "Clock mismatch too large: ${clockMismatch.toInt().toStringAsPrecision(3)}."); - } - - if (t_fusionBegin != null) { - // On the first startround message, check that the warmup time was within acceptable bounds. - final lag = covertT0 - - (t_fusionBegin.millisecondsSinceEpoch / 1000) - - Protocol.WARMUP_TIME; - if (lag.abs() > Protocol.WARMUP_SLOP) { - throw FusionError( - "Warmup period too different from expectation (|${lag.toStringAsFixed(3)}s| > ${Protocol.WARMUP_SLOP.toStringAsFixed(3)}s)."); - } - t_fusionBegin = DateTime.now(); - } - - print("round starting at ${DateTime.now().millisecondsSinceEpoch / 1000}"); - - final inputFees = coins - .map( - (e) => Util.componentFee(e.sizeOfInput(), componentFeeRate.toInt())) - .reduce((a, b) => a + b); - final outputFees = - outputs.length * Util.componentFee(34, componentFeeRate.toInt()); - - final sumIn = coins.map((e) => e.amount).reduce((a, b) => a + b); - final sumOut = outputs.map((e) => e.value).reduce((a, b) => a + b); - - final totalFee = sumIn - sumOut; - final excessFee = totalFee - inputFees - outputFees; - final safeties = [ - sumIn == safety_sum_in, - excessFee == safetyExcessFee, - excessFee <= Protocol.MAX_EXCESS_FEE, - totalFee <= Protocol.MAX_FEE, - ]; - - if (!safeties.every((element) => element)) { - throw Exception( - "(BUG!) Funds re-check failed -- aborting for safety. ${safeties.toString()}"); - } - - final roundPubKey = (msg as StartRound).roundPubkey; - - final blindNoncePoints = (msg as StartRound).blindNoncePoints; - if (blindNoncePoints.length != numComponents) { - throw FusionError('blind nonce miscount'); - } - - final numBlanks = numComponents - coins.length - outputs.length; - final List<ComponentResult> genComponentsResults = - genComponents(numBlanks, coins, outputs, componentFeeRate.toInt()); - - final List<Uint8List> myCommitments = []; - final List<int> myComponentSlots = []; - final List<Uint8List> myComponents = []; - final List<Proof> myProofs = []; - final List<Uint8List> privKeys = []; - final List<dynamic> pedersenAmount = - []; // replace dynamic with the actual type - final List<dynamic> pedersenNonce = - []; // replace dynamic with the actual type - - for (var genComponentResult in genComponentsResults) { - myCommitments.add(genComponentResult.commitment); - myComponentSlots.add(genComponentResult.counter); - myComponents.add(genComponentResult.component); - myProofs.add(genComponentResult.proof); - privKeys.add(genComponentResult.privateKey); - pedersenAmount.add(genComponentResult.pedersenAmount); - pedersenNonce.add(genComponentResult.pedersenNonce); - } - assert(excessFee == - pedersenAmount.reduce( - (a, b) => a + b)); // sanity check that we didn't mess up the above - assert(myComponents.toSet().length == myComponents.length); // no duplicates - - // Need to implement this! schnorr is from EC schnorr.py - var blindSigRequests = <dynamic>[]; - - /* - final blindSigRequests = blindNoncePoints.map((e) => Schnorr.BlindSignatureRequest(roundPubKey, e, sha256(myComponents.elementAt(e)))).toList(); - -*/ - final randomNumber = Util.getRandomBytes(32); - covert.checkOk(); - check_stop(); - check_coins(); - - await send(PlayerCommit( - initialCommitments: myCommitments, - excessFee: Int64(excessFee), - pedersenTotalNonce: pedersenNonce.cast<int>(), - randomNumberCommitment: sha256.convert(randomNumber).bytes, - blindSigRequests: - blindSigRequests.map((r) => r.getRequest() as List<int>).toList(), - )); - - msg = await recv(['blindsigresponses'], - timeout: Duration(seconds: Protocol.T_START_COMPS.toInt())); - - if (msg is BlindSigResponses) { - var typedMsg = msg as BlindSigResponses; - assert(typedMsg.scalars.length == blindSigRequests.length); - } else { - // Handle the case where msg is not of type BlindSigResponses - throw Exception('Unexpected message type: ${msg.runtimeType}'); - } - - final blindSigs = List.generate( - blindSigRequests.length, - (index) { - if (msg is BlindSigResponses) { - var typedMsg = msg as BlindSigResponses; - return blindSigRequests[index] - .finalize(typedMsg.scalars[index], check: true); - } else { - // Handle the case where msg is not of type BlindSigResponses - throw Exception('Unexpected message type: ${msg.runtimeType}'); - } - }, - ); - -// Sleep until the covert component phase really starts, to catch covert connection failures. - var remainingTime = Protocol.T_START_COMPS - covertClock(); - if (remainingTime < 0) { - throw FusionError('Arrived at covert-component phase too slowly.'); - } - await Future.delayed(Duration(seconds: remainingTime.floor())); - -// Our final check to leave the fusion pool, before we start telling our -// components. This is much more annoying since it will cause the round -// to fail, but since we would end up killing the round anyway then it's -// best for our privacy if we just leave now. -// (This also is our first call to check_connected.) - covert.checkConnected(); - check_coins(); - -// Start covert component submissions - print("starting covert component submission"); - status = Tuple('running', 'covert submission: components'); - -// If we fail after this point, we want to stop connections gradually and -// randomly. We don't want to stop them all at once, since if we had already -// provided our input components then it would be a leak to have them all drop at once. - covert.setStopTime((covertT0 + Protocol.T_START_CLOSE).toInt()); - - // Schedule covert submissions. - List<CovertComponent?> messages = List.filled(myComponents.length, null); - - for (var i = 0; i < myComponents.length; i++) { - messages[myComponentSlots[i]] = CovertComponent( - roundPubkey: roundPubKey, - signature: blindSigs[i], - component: myComponents[i]); - } - if (messages.any((element) => element == null)) { - throw FusionError('Messages list includes null values.'); - } - - final targetDateTime = DateTime.fromMillisecondsSinceEpoch( - ((covertT0 + Protocol.T_START_COMPS) * 1000).toInt()); - covert.scheduleSubmissions(targetDateTime, messages); - - // While submitting, we download the (large) full commitment list. - msg = await recv(['allcommitments'], - timeout: Duration(seconds: Protocol.T_START_SIGS.toInt())); - AllCommitments allCommitmentsMsg = msg as AllCommitments; - List<InitialCommitment> allCommitments = - allCommitmentsMsg.initialCommitments.map((commitmentBytes) { - return InitialCommitment.fromBuffer(commitmentBytes); - }).toList(); - - // Quick check on the commitment list. - if (allCommitments.toSet().length != allCommitments.length) { - throw FusionError('Commitments list includes duplicates.'); - } - try { - List<Uint8List> allCommitmentsBytes = allCommitments - .map((commitment) => commitment.writeToBuffer()) - .toList(); - myCommitmentIndexes = - myCommitments.map((c) => allCommitmentsBytes.indexOf(c)).toList(); - } on Exception { - throw FusionError('One or more of my commitments missing.'); - } - - remainingTime = Protocol.T_START_SIGS - covertClock(); - if (remainingTime < 0) { - throw FusionError('took too long to download commitments list'); - } - - // Once all components are received, the server shares them with us: - msg = await recv(['sharecovertcomponents'], - timeout: Duration(seconds: Protocol.T_START_SIGS.toInt())); - - ShareCovertComponents shareCovertComponentsMsg = - msg as ShareCovertComponents; - List<List<int>> allComponents = shareCovertComponentsMsg.components; - bool skipSignatures = msg.getField(2); - - // Critical check on server's response timing. - if (covertClock() > Protocol.T_START_SIGS) { - throw FusionError('Shared components message arrived too slowly.'); - } - - covert.checkDone(); - - try { - myComponentIndexes = myComponents - .map((c) => allComponents - .indexWhere((element) => ListEquality().equals(element, c))) - .toList(); - if (myComponentIndexes.contains(-1)) { - throw FusionError('One or more of my components missing.'); - } - } on StateError { - throw FusionError('One or more of my components missing.'); - } - - // Need to implement: check the components list and see if there are enough inputs/outputs - // for there to be significant privacy. - - List<List<int>> allCommitmentsBytes = allCommitments - .map((commitment) => commitment.writeToBuffer().toList()) - .toList(); - List<int> sessionHash = Util.calcRoundHash(lastHash, roundPubKey, - roundTime.toInt(), allCommitmentsBytes, allComponents); - - if (shareCovertComponentsMsg.sessionHash != null && - !ListEquality() - .equals(shareCovertComponentsMsg.sessionHash, sessionHash)) { - throw FusionError('Session hash mismatch (bug!)'); - } - - if (!shareCovertComponentsMsg.skipSignatures) { - print("starting covert signature submission"); - status = Tuple('running', 'covert submission: signatures'); - - if (allComponents.toSet().length != allComponents.length) { - throw FusionError('Server component list includes duplicates.'); - } - - var txInputIndices = - Transaction.txFromComponents(allComponents, sessionHash); - - Tuple txData = Transaction.txFromComponents(allComponents, sessionHash); - tx = txData.item1; - List<int> inputIndices = txData.item2; - - List<CovertTransactionSignature?> covertTransactionSignatureMessages = - List<CovertTransactionSignature?>.filled(myComponents.length, null); - - var my_combined = List<Tuple<int, Input>>.generate( - inputIndices.length, - (index) => Tuple(inputIndices[index], tx.Inputs[index]), - ); - - for (var i = 0; i < my_combined.length; i++) { - int cIdx = my_combined[i].item1; - Input inp = my_combined[i].item2; - - int myCompIdx = myComponentIndexes.indexOf(cIdx); - if (myCompIdx == -1) continue; // not my input - - var pubKey = inp.getPubKey(0); - var sec = inp.getPrivKey(0); - - var preimageBytes = tx.serializePreimage(i, 0x41, useCache: true); - var sighash = sha256.convert(sha256.convert(preimageBytes).bytes); - - //var sig = schnorr.sign(sec, sighash); // Needs implementation - var sig = <int>[0, 1, 2, 3, 4]; // dummy placeholder - - covertTransactionSignatureMessages[myComponentSlots[myCompIdx]] = - CovertTransactionSignature(txsignature: sig, whichInput: i); - } - - DateTime covertT0DateTime = DateTime.fromMillisecondsSinceEpoch( - covertT0.toInt() * 1000); // covertT0 is in seconds - covert.scheduleSubmissions( - covertT0DateTime - .add(Duration(milliseconds: Protocol.T_START_SIGS.toInt())), - covertTransactionSignatureMessages); - - // wait for result - int timeoutMillis = (Protocol.T_EXPECTING_CONCLUSION - - Protocol.TS_EXPECTING_COVERT_COMPONENTS) - .toInt(); - Duration timeout = Duration(milliseconds: timeoutMillis); - msg = await recv(['fusionresult'], timeout: timeout); - - // Critical check on server's response timing. - if (covertClock() > Protocol.T_EXPECTING_CONCLUSION) { - throw FusionError('Fusion result message arrived too slowly.'); - } - - covert.checkDone(); - FusionResult fusionResultMsg = msg as FusionResult; - if (fusionResultMsg.ok) { - List<List<int>> allSigs = msg.txsignatures; - - // assemble the transaction. - if (allSigs.length != tx.Inputs.length) { - throw FusionError('Server gave wrong number of signatures.'); - } - for (var i = 0; i < allSigs.length; i++) { - List<int> sigBytes = allSigs[i]; - String sig = base64.encode(sigBytes); - Input inp = tx.Inputs[i]; - if (sig.length != 64) { - throw FusionError('server relayed bad signature'); - } - inp.signatures = [sig + '41']; - } - - assert(tx.isComplete()); - String txHex = tx.serialize(); - - txid = tx.txid(); - String sumInStr = Util.formatSatoshis(sumIn, numZeros: 8); - String feeStr = totalFee.toString(); - String feeLoc = 'fee'; - - String label = - "CashFusion ${coins.length}⇢${outputs.length}, ${sumInStr} BCH (−${feeStr} sats ${feeLoc})"; - - Util.updateWalletLabel(txid, label); - } else { - badComponents = msg.badComponents.toSet(); - if (badComponents.intersection(myComponentIndexes.toSet()).isNotEmpty) { - print( - "bad components: ${badComponents.toList()} mine: ${myComponentIndexes.toList()}"); - throw FusionError("server thinks one of my components is bad!"); - } - } - } else { - // skip_signatures True - Set<int> badComponents = Set<int>(); - } - -// ### Blame phase ### - - covert.setStopTime((covertT0 + Protocol.T_START_CLOSE_BLAME).floor()); - - print("sending proofs"); - status = Tuple('running', 'round failed - sending proofs'); - -// create a list of commitment indexes, but leaving out mine. - List<int> othersCommitmentIdxes = []; - for (int i = 0; i < allCommitments.length; i++) { - if (!myCommitmentIndexes.contains(i)) { - othersCommitmentIdxes.add(i); - } - } - int N = othersCommitmentIdxes.length; - assert(N == allCommitments.length - myCommitments.length); - if (N == 0) { - throw FusionError( - "Fusion failed with only me as player -- I can only blame myself."); - } - -// where should I send my proofs? - List<InitialCommitment> dstCommits = []; - for (int i = 0; i < myCommitments.length; i++) { - dstCommits.add(allCommitments[ - othersCommitmentIdxes[Util.randPosition(randomNumber, N, i)]]); - } - -// generate the encrypted proofs - List<String> encproofs = List<String>.filled(myCommitments.length, ''); - - ECDomainParameters params = ECDomainParameters('secp256k1'); - for (int i = 0; i < dstCommits.length; i++) { - InitialCommitment msg = dstCommits[i]; - Proof proof = myProofs[i]; - proof.componentIdx = myComponentIndexes[i]; - - ECPoint? communicationKeyPointMaybe = - params.curve.decodePoint(Uint8List.fromList(msg.communicationKey)); - if (communicationKeyPointMaybe == null) { - // handle the error case here, e.g., throw an exception or skip this iteration. - continue; - } - ECPoint communicationKeyPoint = communicationKeyPointMaybe; - - try { - Uint8List encryptedData = await encrypt( - proof.writeToBuffer(), communicationKeyPoint, - padToLength: 80); - encproofs[i] = String.fromCharCodes(encryptedData); - } catch (EncryptionFailed) { - // The communication key was bad (probably invalid x coordinate). - // We will just send a blank. They can't even blame us since there is no private key! :) - continue; - } - } - - List<Uint8List> encodedEncproofs = - encproofs.map((e) => Uint8List.fromList(e.codeUnits)).toList(); - this.send(MyProofsList( - encryptedProofs: encodedEncproofs, randomNumber: randomNumber)); - - status = Tuple('running', 'round failed - checking proofs'); - - print("receiving proofs"); - msg = await this.recv(['theirproofslist'], - timeout: Duration(seconds: (2 * Protocol.STANDARD_TIMEOUT).round())); - - List<Blames_BlameProof> blames = []; - - int countInputs = 0; - - TheirProofsList proofsList = msg as TheirProofsList; - - var privKey; - var commitmentBlob; - for (var i = 0; i < proofsList.proofs.length; i++) { - var rp = msg.proofs[i]; - try { - privKey = privKeys[rp.dstKeyIdx]; - commitmentBlob = allCommitments[rp.srcCommitmentIdx]; - } on RangeError catch (e) { - throw FusionError("Server relayed bad proof indices"); - } - - var sKey; - var proofBlob; - - try { - var result = - await decrypt(Uint8List.fromList(rp.encryptedProof), privKey); - proofBlob = result.item1; // First item is the decrypted data - sKey = result.item2; // Second item is the symmetric key - } on Exception catch (e) { - print("found an undecryptable proof"); - blames.add(Blames_BlameProof( - whichProof: i, privkey: privKey, blameReason: 'undecryptable')); - continue; - } - - var commitment = InitialCommitment(); - try { - commitment - .mergeFromBuffer(commitmentBlob); // Method to parse protobuf data - } on FormatException catch (e) { - throw FusionError("Server relayed bad commitment"); - } - - var inpComp; - - try { - // Convert allComponents to List<Uint8List> - List<Uint8List> allComponentsUint8 = allComponents - .map((component) => Uint8List.fromList(component)) - .toList(); - // Convert badComponents to List<int> - List<int> badComponentsList = badComponents.toList(); - // Convert componentFeeRate to int if it's double - int componentFeerateInt = componentFeeRate - .round(); // or use .toInt() if you want to truncate instead of rounding - - var inpComp = validateProofInternal(proofBlob, commitment, - allComponentsUint8, badComponentsList, componentFeerateInt); - } on Exception catch (e) { - print("found an erroneous proof: ${e.toString()}"); - var blameProof = Blames_BlameProof(); - blameProof.whichProof = i; - blameProof.sessionKey = sKey; - blameProof.blameReason = e.toString(); - blames.add(blameProof); - continue; - } - - if (inpComp != null) { - countInputs++; - try { - Util.checkInputElectrumX(inpComp); - } on Exception catch (e) { - print( - "found a bad input [${rp.srcCommitmentIdx}]: $e (${inpComp.prevTxid.reversed.toList().toHex()}:${inpComp.prevIndex})"); - - var blameProof = Blames_BlameProof(); - blameProof.whichProof = i; - blameProof.sessionKey = sKey; - blameProof.blameReason = - 'input does not match blockchain: ' + e.toString(); - blameProof.needLookupBlockchain = true; - blames.add(blameProof); - } catch (e) { - print( - "verified an input internally, but was unable to check it against blockchain: ${e}"); - } - } - } - print("checked ${msg.proofs.length} proofs, $countInputs of them inputs"); - - print("sending blames"); - send(Blames(blames: blames)); - - status = Tuple('running', 'awaiting restart'); - -// Await the final 'restartround' message. It might take some time -// to arrive since other players might be slow, and then the server -// itself needs to check blockchain. - await recv(['restartround'], - timeout: Duration( - seconds: 2 * - (Protocol.STANDARD_TIMEOUT.round() + - Protocol.BLAME_VERIFY_TIME.round()))); - } // end of run_round() function. -} // END OF CLASS diff --git a/lib/services/cashfusion/fusion.pb.dart b/lib/services/cashfusion/fusion.pb.dart deleted file mode 100644 index dac659f95..000000000 --- a/lib/services/cashfusion/fusion.pb.dart +++ /dev/null @@ -1,2501 +0,0 @@ -/// -// Generated code. Do not modify. -// source: fusion.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name - -import 'dart:core' as $core; - -import 'package:fixnum/fixnum.dart' as $fixnum; -import 'package:protobuf/protobuf.dart' as $pb; - -class InputComponent extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'InputComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'prevTxid', $pb.PbFieldType.QY) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'prevIndex', $pb.PbFieldType.QU3) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pubkey', $pb.PbFieldType.QY) - ..a<$fixnum.Int64>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amount', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ; - - InputComponent._() : super(); - factory InputComponent({ - $core.List<$core.int>? prevTxid, - $core.int? prevIndex, - $core.List<$core.int>? pubkey, - $fixnum.Int64? amount, - }) { - final _result = create(); - if (prevTxid != null) { - _result.prevTxid = prevTxid; - } - if (prevIndex != null) { - _result.prevIndex = prevIndex; - } - if (pubkey != null) { - _result.pubkey = pubkey; - } - if (amount != null) { - _result.amount = amount; - } - return _result; - } - factory InputComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory InputComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - InputComponent clone() => InputComponent()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - InputComponent copyWith(void Function(InputComponent) updates) => super.copyWith((message) => updates(message as InputComponent)) as InputComponent; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static InputComponent create() => InputComponent._(); - InputComponent createEmptyInstance() => create(); - static $pb.PbList<InputComponent> createRepeated() => $pb.PbList<InputComponent>(); - @$core.pragma('dart2js:noInline') - static InputComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<InputComponent>(create); - static InputComponent? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get prevTxid => $_getN(0); - @$pb.TagNumber(1) - set prevTxid($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasPrevTxid() => $_has(0); - @$pb.TagNumber(1) - void clearPrevTxid() => clearField(1); - - @$pb.TagNumber(2) - $core.int get prevIndex => $_getIZ(1); - @$pb.TagNumber(2) - set prevIndex($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasPrevIndex() => $_has(1); - @$pb.TagNumber(2) - void clearPrevIndex() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get pubkey => $_getN(2); - @$pb.TagNumber(3) - set pubkey($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasPubkey() => $_has(2); - @$pb.TagNumber(3) - void clearPubkey() => clearField(3); - - @$pb.TagNumber(4) - $fixnum.Int64 get amount => $_getI64(3); - @$pb.TagNumber(4) - set amount($fixnum.Int64 v) { $_setInt64(3, v); } - @$pb.TagNumber(4) - $core.bool hasAmount() => $_has(3); - @$pb.TagNumber(4) - void clearAmount() => clearField(4); -} - -class OutputComponent extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'OutputComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scriptpubkey', $pb.PbFieldType.QY) - ..a<$fixnum.Int64>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amount', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ; - - OutputComponent._() : super(); - factory OutputComponent({ - $core.List<$core.int>? scriptpubkey, - $fixnum.Int64? amount, - }) { - final _result = create(); - if (scriptpubkey != null) { - _result.scriptpubkey = scriptpubkey; - } - if (amount != null) { - _result.amount = amount; - } - return _result; - } - factory OutputComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory OutputComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - OutputComponent clone() => OutputComponent()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - OutputComponent copyWith(void Function(OutputComponent) updates) => super.copyWith((message) => updates(message as OutputComponent)) as OutputComponent; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static OutputComponent create() => OutputComponent._(); - OutputComponent createEmptyInstance() => create(); - static $pb.PbList<OutputComponent> createRepeated() => $pb.PbList<OutputComponent>(); - @$core.pragma('dart2js:noInline') - static OutputComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OutputComponent>(create); - static OutputComponent? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get scriptpubkey => $_getN(0); - @$pb.TagNumber(1) - set scriptpubkey($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasScriptpubkey() => $_has(0); - @$pb.TagNumber(1) - void clearScriptpubkey() => clearField(1); - - @$pb.TagNumber(2) - $fixnum.Int64 get amount => $_getI64(1); - @$pb.TagNumber(2) - set amount($fixnum.Int64 v) { $_setInt64(1, v); } - @$pb.TagNumber(2) - $core.bool hasAmount() => $_has(1); - @$pb.TagNumber(2) - void clearAmount() => clearField(2); -} - -class BlankComponent extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlankComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..hasRequiredFields = false - ; - - BlankComponent._() : super(); - factory BlankComponent() => create(); - factory BlankComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory BlankComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - BlankComponent clone() => BlankComponent()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - BlankComponent copyWith(void Function(BlankComponent) updates) => super.copyWith((message) => updates(message as BlankComponent)) as BlankComponent; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static BlankComponent create() => BlankComponent._(); - BlankComponent createEmptyInstance() => create(); - static $pb.PbList<BlankComponent> createRepeated() => $pb.PbList<BlankComponent>(); - @$core.pragma('dart2js:noInline') - static BlankComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BlankComponent>(create); - static BlankComponent? _defaultInstance; -} - -enum Component_Component { - input, - output, - blank, - notSet -} - -class Component extends $pb.GeneratedMessage { - static const $core.Map<$core.int, Component_Component> _Component_ComponentByTag = { - 2 : Component_Component.input, - 3 : Component_Component.output, - 4 : Component_Component.blank, - 0 : Component_Component.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Component', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [2, 3, 4]) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'saltCommitment', $pb.PbFieldType.QY) - ..aOM<InputComponent>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'input', subBuilder: InputComponent.create) - ..aOM<OutputComponent>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'output', subBuilder: OutputComponent.create) - ..aOM<BlankComponent>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blank', subBuilder: BlankComponent.create) - ; - - Component._() : super(); - factory Component({ - $core.List<$core.int>? saltCommitment, - InputComponent? input, - OutputComponent? output, - BlankComponent? blank, - }) { - final _result = create(); - if (saltCommitment != null) { - _result.saltCommitment = saltCommitment; - } - if (input != null) { - _result.input = input; - } - if (output != null) { - _result.output = output; - } - if (blank != null) { - _result.blank = blank; - } - return _result; - } - factory Component.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Component.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Component clone() => Component()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Component copyWith(void Function(Component) updates) => super.copyWith((message) => updates(message as Component)) as Component; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Component create() => Component._(); - Component createEmptyInstance() => create(); - static $pb.PbList<Component> createRepeated() => $pb.PbList<Component>(); - @$core.pragma('dart2js:noInline') - static Component getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Component>(create); - static Component? _defaultInstance; - - Component_Component whichComponent() => _Component_ComponentByTag[$_whichOneof(0)]!; - void clearComponent() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - $core.List<$core.int> get saltCommitment => $_getN(0); - @$pb.TagNumber(1) - set saltCommitment($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasSaltCommitment() => $_has(0); - @$pb.TagNumber(1) - void clearSaltCommitment() => clearField(1); - - @$pb.TagNumber(2) - InputComponent get input => $_getN(1); - @$pb.TagNumber(2) - set input(InputComponent v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasInput() => $_has(1); - @$pb.TagNumber(2) - void clearInput() => clearField(2); - @$pb.TagNumber(2) - InputComponent ensureInput() => $_ensure(1); - - @$pb.TagNumber(3) - OutputComponent get output => $_getN(2); - @$pb.TagNumber(3) - set output(OutputComponent v) { setField(3, v); } - @$pb.TagNumber(3) - $core.bool hasOutput() => $_has(2); - @$pb.TagNumber(3) - void clearOutput() => clearField(3); - @$pb.TagNumber(3) - OutputComponent ensureOutput() => $_ensure(2); - - @$pb.TagNumber(4) - BlankComponent get blank => $_getN(3); - @$pb.TagNumber(4) - set blank(BlankComponent v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasBlank() => $_has(3); - @$pb.TagNumber(4) - void clearBlank() => clearField(4); - @$pb.TagNumber(4) - BlankComponent ensureBlank() => $_ensure(3); -} - -class InitialCommitment extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'InitialCommitment', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'saltedComponentHash', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amountCommitment', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'communicationKey', $pb.PbFieldType.QY) - ; - - InitialCommitment._() : super(); - factory InitialCommitment({ - $core.List<$core.int>? saltedComponentHash, - $core.List<$core.int>? amountCommitment, - $core.List<$core.int>? communicationKey, - }) { - final _result = create(); - if (saltedComponentHash != null) { - _result.saltedComponentHash = saltedComponentHash; - } - if (amountCommitment != null) { - _result.amountCommitment = amountCommitment; - } - if (communicationKey != null) { - _result.communicationKey = communicationKey; - } - return _result; - } - factory InitialCommitment.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory InitialCommitment.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - InitialCommitment clone() => InitialCommitment()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - InitialCommitment copyWith(void Function(InitialCommitment) updates) => super.copyWith((message) => updates(message as InitialCommitment)) as InitialCommitment; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static InitialCommitment create() => InitialCommitment._(); - InitialCommitment createEmptyInstance() => create(); - static $pb.PbList<InitialCommitment> createRepeated() => $pb.PbList<InitialCommitment>(); - @$core.pragma('dart2js:noInline') - static InitialCommitment getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<InitialCommitment>(create); - static InitialCommitment? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get saltedComponentHash => $_getN(0); - @$pb.TagNumber(1) - set saltedComponentHash($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasSaltedComponentHash() => $_has(0); - @$pb.TagNumber(1) - void clearSaltedComponentHash() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get amountCommitment => $_getN(1); - @$pb.TagNumber(2) - set amountCommitment($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasAmountCommitment() => $_has(1); - @$pb.TagNumber(2) - void clearAmountCommitment() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get communicationKey => $_getN(2); - @$pb.TagNumber(3) - set communicationKey($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasCommunicationKey() => $_has(2); - @$pb.TagNumber(3) - void clearCommunicationKey() => clearField(3); -} - -class Proof extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Proof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'componentIdx', $pb.PbFieldType.QF3) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'salt', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pedersenNonce', $pb.PbFieldType.QY) - ; - - Proof._() : super(); - factory Proof({ - $core.int? componentIdx, - $core.List<$core.int>? salt, - $core.List<$core.int>? pedersenNonce, - }) { - final _result = create(); - if (componentIdx != null) { - _result.componentIdx = componentIdx; - } - if (salt != null) { - _result.salt = salt; - } - if (pedersenNonce != null) { - _result.pedersenNonce = pedersenNonce; - } - return _result; - } - factory Proof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Proof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Proof clone() => Proof()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Proof copyWith(void Function(Proof) updates) => super.copyWith((message) => updates(message as Proof)) as Proof; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Proof create() => Proof._(); - Proof createEmptyInstance() => create(); - static $pb.PbList<Proof> createRepeated() => $pb.PbList<Proof>(); - @$core.pragma('dart2js:noInline') - static Proof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Proof>(create); - static Proof? _defaultInstance; - - @$pb.TagNumber(1) - $core.int get componentIdx => $_getIZ(0); - @$pb.TagNumber(1) - set componentIdx($core.int v) { $_setUnsignedInt32(0, v); } - @$pb.TagNumber(1) - $core.bool hasComponentIdx() => $_has(0); - @$pb.TagNumber(1) - void clearComponentIdx() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get salt => $_getN(1); - @$pb.TagNumber(2) - set salt($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasSalt() => $_has(1); - @$pb.TagNumber(2) - void clearSalt() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get pedersenNonce => $_getN(2); - @$pb.TagNumber(3) - set pedersenNonce($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasPedersenNonce() => $_has(2); - @$pb.TagNumber(3) - void clearPedersenNonce() => clearField(3); -} - -class ClientHello extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ClientHello', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'version', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'genesisHash', $pb.PbFieldType.OY) - ; - - ClientHello._() : super(); - factory ClientHello({ - $core.List<$core.int>? version, - $core.List<$core.int>? genesisHash, - }) { - final _result = create(); - if (version != null) { - _result.version = version; - } - if (genesisHash != null) { - _result.genesisHash = genesisHash; - } - return _result; - } - factory ClientHello.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ClientHello.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - ClientHello clone() => ClientHello()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - ClientHello copyWith(void Function(ClientHello) updates) => super.copyWith((message) => updates(message as ClientHello)) as ClientHello; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static ClientHello create() => ClientHello._(); - ClientHello createEmptyInstance() => create(); - static $pb.PbList<ClientHello> createRepeated() => $pb.PbList<ClientHello>(); - @$core.pragma('dart2js:noInline') - static ClientHello getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ClientHello>(create); - static ClientHello? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get version => $_getN(0); - @$pb.TagNumber(1) - set version($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasVersion() => $_has(0); - @$pb.TagNumber(1) - void clearVersion() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get genesisHash => $_getN(1); - @$pb.TagNumber(2) - set genesisHash($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasGenesisHash() => $_has(1); - @$pb.TagNumber(2) - void clearGenesisHash() => clearField(2); -} - -class ServerHello extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ServerHello', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tiers', $pb.PbFieldType.PU6) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'numComponents', $pb.PbFieldType.QU3) - ..a<$fixnum.Int64>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'componentFeerate', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'minExcessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ..a<$fixnum.Int64>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'maxExcessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ..aOS(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'donationAddress') - ; - - ServerHello._() : super(); - factory ServerHello({ - $core.Iterable<$fixnum.Int64>? tiers, - $core.int? numComponents, - $fixnum.Int64? componentFeerate, - $fixnum.Int64? minExcessFee, - $fixnum.Int64? maxExcessFee, - $core.String? donationAddress, - }) { - final _result = create(); - if (tiers != null) { - _result.tiers.addAll(tiers); - } - if (numComponents != null) { - _result.numComponents = numComponents; - } - if (componentFeerate != null) { - _result.componentFeerate = componentFeerate; - } - if (minExcessFee != null) { - _result.minExcessFee = minExcessFee; - } - if (maxExcessFee != null) { - _result.maxExcessFee = maxExcessFee; - } - if (donationAddress != null) { - _result.donationAddress = donationAddress; - } - return _result; - } - factory ServerHello.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ServerHello.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - ServerHello clone() => ServerHello()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - ServerHello copyWith(void Function(ServerHello) updates) => super.copyWith((message) => updates(message as ServerHello)) as ServerHello; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static ServerHello create() => ServerHello._(); - ServerHello createEmptyInstance() => create(); - static $pb.PbList<ServerHello> createRepeated() => $pb.PbList<ServerHello>(); - @$core.pragma('dart2js:noInline') - static ServerHello getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ServerHello>(create); - static ServerHello? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$fixnum.Int64> get tiers => $_getList(0); - - @$pb.TagNumber(2) - $core.int get numComponents => $_getIZ(1); - @$pb.TagNumber(2) - set numComponents($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasNumComponents() => $_has(1); - @$pb.TagNumber(2) - void clearNumComponents() => clearField(2); - - @$pb.TagNumber(4) - $fixnum.Int64 get componentFeerate => $_getI64(2); - @$pb.TagNumber(4) - set componentFeerate($fixnum.Int64 v) { $_setInt64(2, v); } - @$pb.TagNumber(4) - $core.bool hasComponentFeerate() => $_has(2); - @$pb.TagNumber(4) - void clearComponentFeerate() => clearField(4); - - @$pb.TagNumber(5) - $fixnum.Int64 get minExcessFee => $_getI64(3); - @$pb.TagNumber(5) - set minExcessFee($fixnum.Int64 v) { $_setInt64(3, v); } - @$pb.TagNumber(5) - $core.bool hasMinExcessFee() => $_has(3); - @$pb.TagNumber(5) - void clearMinExcessFee() => clearField(5); - - @$pb.TagNumber(6) - $fixnum.Int64 get maxExcessFee => $_getI64(4); - @$pb.TagNumber(6) - set maxExcessFee($fixnum.Int64 v) { $_setInt64(4, v); } - @$pb.TagNumber(6) - $core.bool hasMaxExcessFee() => $_has(4); - @$pb.TagNumber(6) - void clearMaxExcessFee() => clearField(6); - - @$pb.TagNumber(15) - $core.String get donationAddress => $_getSZ(5); - @$pb.TagNumber(15) - set donationAddress($core.String v) { $_setString(5, v); } - @$pb.TagNumber(15) - $core.bool hasDonationAddress() => $_has(5); - @$pb.TagNumber(15) - void clearDonationAddress() => clearField(15); -} - -class JoinPools_PoolTag extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'JoinPools.PoolTag', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id', $pb.PbFieldType.QY) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'limit', $pb.PbFieldType.QU3) - ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'noIp') - ; - - JoinPools_PoolTag._() : super(); - factory JoinPools_PoolTag({ - $core.List<$core.int>? id, - $core.int? limit, - $core.bool? noIp, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (limit != null) { - _result.limit = limit; - } - if (noIp != null) { - _result.noIp = noIp; - } - return _result; - } - factory JoinPools_PoolTag.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory JoinPools_PoolTag.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - JoinPools_PoolTag clone() => JoinPools_PoolTag()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - JoinPools_PoolTag copyWith(void Function(JoinPools_PoolTag) updates) => super.copyWith((message) => updates(message as JoinPools_PoolTag)) as JoinPools_PoolTag; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static JoinPools_PoolTag create() => JoinPools_PoolTag._(); - JoinPools_PoolTag createEmptyInstance() => create(); - static $pb.PbList<JoinPools_PoolTag> createRepeated() => $pb.PbList<JoinPools_PoolTag>(); - @$core.pragma('dart2js:noInline') - static JoinPools_PoolTag getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<JoinPools_PoolTag>(create); - static JoinPools_PoolTag? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get id => $_getN(0); - @$pb.TagNumber(1) - set id($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.int get limit => $_getIZ(1); - @$pb.TagNumber(2) - set limit($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasLimit() => $_has(1); - @$pb.TagNumber(2) - void clearLimit() => clearField(2); - - @$pb.TagNumber(3) - $core.bool get noIp => $_getBF(2); - @$pb.TagNumber(3) - set noIp($core.bool v) { $_setBool(2, v); } - @$pb.TagNumber(3) - $core.bool hasNoIp() => $_has(2); - @$pb.TagNumber(3) - void clearNoIp() => clearField(3); -} - -class JoinPools extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'JoinPools', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tiers', $pb.PbFieldType.PU6) - ..pc<JoinPools_PoolTag>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tags', $pb.PbFieldType.PM, subBuilder: JoinPools_PoolTag.create) - ; - - JoinPools._() : super(); - factory JoinPools({ - $core.Iterable<$fixnum.Int64>? tiers, - $core.Iterable<JoinPools_PoolTag>? tags, - }) { - final _result = create(); - if (tiers != null) { - _result.tiers.addAll(tiers); - } - if (tags != null) { - _result.tags.addAll(tags); - } - return _result; - } - factory JoinPools.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory JoinPools.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - JoinPools clone() => JoinPools()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - JoinPools copyWith(void Function(JoinPools) updates) => super.copyWith((message) => updates(message as JoinPools)) as JoinPools; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static JoinPools create() => JoinPools._(); - JoinPools createEmptyInstance() => create(); - static $pb.PbList<JoinPools> createRepeated() => $pb.PbList<JoinPools>(); - @$core.pragma('dart2js:noInline') - static JoinPools getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<JoinPools>(create); - static JoinPools? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$fixnum.Int64> get tiers => $_getList(0); - - @$pb.TagNumber(2) - $core.List<JoinPools_PoolTag> get tags => $_getList(1); -} - -class TierStatusUpdate_TierStatus extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TierStatusUpdate.TierStatus', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'players', $pb.PbFieldType.OU3) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'minPlayers', $pb.PbFieldType.OU3) - ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'maxPlayers', $pb.PbFieldType.OU3) - ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeRemaining', $pb.PbFieldType.OU3) - ..hasRequiredFields = false - ; - - TierStatusUpdate_TierStatus._() : super(); - factory TierStatusUpdate_TierStatus({ - $core.int? players, - $core.int? minPlayers, - $core.int? maxPlayers, - $core.int? timeRemaining, - }) { - final _result = create(); - if (players != null) { - _result.players = players; - } - if (minPlayers != null) { - _result.minPlayers = minPlayers; - } - if (maxPlayers != null) { - _result.maxPlayers = maxPlayers; - } - if (timeRemaining != null) { - _result.timeRemaining = timeRemaining; - } - return _result; - } - factory TierStatusUpdate_TierStatus.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory TierStatusUpdate_TierStatus.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - TierStatusUpdate_TierStatus clone() => TierStatusUpdate_TierStatus()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - TierStatusUpdate_TierStatus copyWith(void Function(TierStatusUpdate_TierStatus) updates) => super.copyWith((message) => updates(message as TierStatusUpdate_TierStatus)) as TierStatusUpdate_TierStatus; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static TierStatusUpdate_TierStatus create() => TierStatusUpdate_TierStatus._(); - TierStatusUpdate_TierStatus createEmptyInstance() => create(); - static $pb.PbList<TierStatusUpdate_TierStatus> createRepeated() => $pb.PbList<TierStatusUpdate_TierStatus>(); - @$core.pragma('dart2js:noInline') - static TierStatusUpdate_TierStatus getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TierStatusUpdate_TierStatus>(create); - static TierStatusUpdate_TierStatus? _defaultInstance; - - @$pb.TagNumber(1) - $core.int get players => $_getIZ(0); - @$pb.TagNumber(1) - set players($core.int v) { $_setUnsignedInt32(0, v); } - @$pb.TagNumber(1) - $core.bool hasPlayers() => $_has(0); - @$pb.TagNumber(1) - void clearPlayers() => clearField(1); - - @$pb.TagNumber(2) - $core.int get minPlayers => $_getIZ(1); - @$pb.TagNumber(2) - set minPlayers($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasMinPlayers() => $_has(1); - @$pb.TagNumber(2) - void clearMinPlayers() => clearField(2); - - @$pb.TagNumber(3) - $core.int get maxPlayers => $_getIZ(2); - @$pb.TagNumber(3) - set maxPlayers($core.int v) { $_setUnsignedInt32(2, v); } - @$pb.TagNumber(3) - $core.bool hasMaxPlayers() => $_has(2); - @$pb.TagNumber(3) - void clearMaxPlayers() => clearField(3); - - @$pb.TagNumber(4) - $core.int get timeRemaining => $_getIZ(3); - @$pb.TagNumber(4) - set timeRemaining($core.int v) { $_setUnsignedInt32(3, v); } - @$pb.TagNumber(4) - $core.bool hasTimeRemaining() => $_has(3); - @$pb.TagNumber(4) - void clearTimeRemaining() => clearField(4); -} - -class TierStatusUpdate extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TierStatusUpdate', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..m<$fixnum.Int64, TierStatusUpdate_TierStatus>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'statuses', entryClassName: 'TierStatusUpdate.StatusesEntry', keyFieldType: $pb.PbFieldType.OU6, valueFieldType: $pb.PbFieldType.OM, valueCreator: TierStatusUpdate_TierStatus.create, packageName: const $pb.PackageName('fusion')) - ..hasRequiredFields = false - ; - - TierStatusUpdate._() : super(); - factory TierStatusUpdate({ - $core.Map<$fixnum.Int64, TierStatusUpdate_TierStatus>? statuses, - }) { - final _result = create(); - if (statuses != null) { - _result.statuses.addAll(statuses); - } - return _result; - } - factory TierStatusUpdate.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory TierStatusUpdate.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - TierStatusUpdate clone() => TierStatusUpdate()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - TierStatusUpdate copyWith(void Function(TierStatusUpdate) updates) => super.copyWith((message) => updates(message as TierStatusUpdate)) as TierStatusUpdate; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static TierStatusUpdate create() => TierStatusUpdate._(); - TierStatusUpdate createEmptyInstance() => create(); - static $pb.PbList<TierStatusUpdate> createRepeated() => $pb.PbList<TierStatusUpdate>(); - @$core.pragma('dart2js:noInline') - static TierStatusUpdate getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TierStatusUpdate>(create); - static TierStatusUpdate? _defaultInstance; - - @$pb.TagNumber(1) - $core.Map<$fixnum.Int64, TierStatusUpdate_TierStatus> get statuses => $_getMap(0); -} - -class FusionBegin extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FusionBegin', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tier', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertDomain', $pb.PbFieldType.QY) - ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertPort', $pb.PbFieldType.QU3) - ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertSsl') - ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverTime', $pb.PbFieldType.QF6, defaultOrMaker: $fixnum.Int64.ZERO) - ; - - FusionBegin._() : super(); - factory FusionBegin({ - $fixnum.Int64? tier, - $core.List<$core.int>? covertDomain, - $core.int? covertPort, - $core.bool? covertSsl, - $fixnum.Int64? serverTime, - }) { - final _result = create(); - if (tier != null) { - _result.tier = tier; - } - if (covertDomain != null) { - _result.covertDomain = covertDomain; - } - if (covertPort != null) { - _result.covertPort = covertPort; - } - if (covertSsl != null) { - _result.covertSsl = covertSsl; - } - if (serverTime != null) { - _result.serverTime = serverTime; - } - return _result; - } - factory FusionBegin.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory FusionBegin.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - FusionBegin clone() => FusionBegin()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - FusionBegin copyWith(void Function(FusionBegin) updates) => super.copyWith((message) => updates(message as FusionBegin)) as FusionBegin; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static FusionBegin create() => FusionBegin._(); - FusionBegin createEmptyInstance() => create(); - static $pb.PbList<FusionBegin> createRepeated() => $pb.PbList<FusionBegin>(); - @$core.pragma('dart2js:noInline') - static FusionBegin getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FusionBegin>(create); - static FusionBegin? _defaultInstance; - - @$pb.TagNumber(1) - $fixnum.Int64 get tier => $_getI64(0); - @$pb.TagNumber(1) - set tier($fixnum.Int64 v) { $_setInt64(0, v); } - @$pb.TagNumber(1) - $core.bool hasTier() => $_has(0); - @$pb.TagNumber(1) - void clearTier() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get covertDomain => $_getN(1); - @$pb.TagNumber(2) - set covertDomain($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasCovertDomain() => $_has(1); - @$pb.TagNumber(2) - void clearCovertDomain() => clearField(2); - - @$pb.TagNumber(3) - $core.int get covertPort => $_getIZ(2); - @$pb.TagNumber(3) - set covertPort($core.int v) { $_setUnsignedInt32(2, v); } - @$pb.TagNumber(3) - $core.bool hasCovertPort() => $_has(2); - @$pb.TagNumber(3) - void clearCovertPort() => clearField(3); - - @$pb.TagNumber(4) - $core.bool get covertSsl => $_getBF(3); - @$pb.TagNumber(4) - set covertSsl($core.bool v) { $_setBool(3, v); } - @$pb.TagNumber(4) - $core.bool hasCovertSsl() => $_has(3); - @$pb.TagNumber(4) - void clearCovertSsl() => clearField(4); - - @$pb.TagNumber(5) - $fixnum.Int64 get serverTime => $_getI64(4); - @$pb.TagNumber(5) - set serverTime($fixnum.Int64 v) { $_setInt64(4, v); } - @$pb.TagNumber(5) - $core.bool hasServerTime() => $_has(4); - @$pb.TagNumber(5) - void clearServerTime() => clearField(5); -} - -class StartRound extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'StartRound', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.QY) - ..p<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindNoncePoints', $pb.PbFieldType.PY) - ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverTime', $pb.PbFieldType.QF6, defaultOrMaker: $fixnum.Int64.ZERO) - ; - - StartRound._() : super(); - factory StartRound({ - $core.List<$core.int>? roundPubkey, - $core.Iterable<$core.List<$core.int>>? blindNoncePoints, - $fixnum.Int64? serverTime, - }) { - final _result = create(); - if (roundPubkey != null) { - _result.roundPubkey = roundPubkey; - } - if (blindNoncePoints != null) { - _result.blindNoncePoints.addAll(blindNoncePoints); - } - if (serverTime != null) { - _result.serverTime = serverTime; - } - return _result; - } - factory StartRound.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory StartRound.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - StartRound clone() => StartRound()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - StartRound copyWith(void Function(StartRound) updates) => super.copyWith((message) => updates(message as StartRound)) as StartRound; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static StartRound create() => StartRound._(); - StartRound createEmptyInstance() => create(); - static $pb.PbList<StartRound> createRepeated() => $pb.PbList<StartRound>(); - @$core.pragma('dart2js:noInline') - static StartRound getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<StartRound>(create); - static StartRound? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get roundPubkey => $_getN(0); - @$pb.TagNumber(1) - set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasRoundPubkey() => $_has(0); - @$pb.TagNumber(1) - void clearRoundPubkey() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.List<$core.int>> get blindNoncePoints => $_getList(1); - - @$pb.TagNumber(5) - $fixnum.Int64 get serverTime => $_getI64(2); - @$pb.TagNumber(5) - set serverTime($fixnum.Int64 v) { $_setInt64(2, v); } - @$pb.TagNumber(5) - $core.bool hasServerTime() => $_has(2); - @$pb.TagNumber(5) - void clearServerTime() => clearField(5); -} - -class PlayerCommit extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'PlayerCommit', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'initialCommitments', $pb.PbFieldType.PY) - ..a<$fixnum.Int64>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'excessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pedersenTotalNonce', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'randomNumberCommitment', $pb.PbFieldType.QY) - ..p<$core.List<$core.int>>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindSigRequests', $pb.PbFieldType.PY) - ; - - PlayerCommit._() : super(); - factory PlayerCommit({ - $core.Iterable<$core.List<$core.int>>? initialCommitments, - $fixnum.Int64? excessFee, - $core.List<$core.int>? pedersenTotalNonce, - $core.List<$core.int>? randomNumberCommitment, - $core.Iterable<$core.List<$core.int>>? blindSigRequests, - }) { - final _result = create(); - if (initialCommitments != null) { - _result.initialCommitments.addAll(initialCommitments); - } - if (excessFee != null) { - _result.excessFee = excessFee; - } - if (pedersenTotalNonce != null) { - _result.pedersenTotalNonce = pedersenTotalNonce; - } - if (randomNumberCommitment != null) { - _result.randomNumberCommitment = randomNumberCommitment; - } - if (blindSigRequests != null) { - _result.blindSigRequests.addAll(blindSigRequests); - } - return _result; - } - factory PlayerCommit.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory PlayerCommit.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - PlayerCommit clone() => PlayerCommit()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - PlayerCommit copyWith(void Function(PlayerCommit) updates) => super.copyWith((message) => updates(message as PlayerCommit)) as PlayerCommit; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static PlayerCommit create() => PlayerCommit._(); - PlayerCommit createEmptyInstance() => create(); - static $pb.PbList<PlayerCommit> createRepeated() => $pb.PbList<PlayerCommit>(); - @$core.pragma('dart2js:noInline') - static PlayerCommit getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<PlayerCommit>(create); - static PlayerCommit? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.List<$core.int>> get initialCommitments => $_getList(0); - - @$pb.TagNumber(2) - $fixnum.Int64 get excessFee => $_getI64(1); - @$pb.TagNumber(2) - set excessFee($fixnum.Int64 v) { $_setInt64(1, v); } - @$pb.TagNumber(2) - $core.bool hasExcessFee() => $_has(1); - @$pb.TagNumber(2) - void clearExcessFee() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get pedersenTotalNonce => $_getN(2); - @$pb.TagNumber(3) - set pedersenTotalNonce($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasPedersenTotalNonce() => $_has(2); - @$pb.TagNumber(3) - void clearPedersenTotalNonce() => clearField(3); - - @$pb.TagNumber(4) - $core.List<$core.int> get randomNumberCommitment => $_getN(3); - @$pb.TagNumber(4) - set randomNumberCommitment($core.List<$core.int> v) { $_setBytes(3, v); } - @$pb.TagNumber(4) - $core.bool hasRandomNumberCommitment() => $_has(3); - @$pb.TagNumber(4) - void clearRandomNumberCommitment() => clearField(4); - - @$pb.TagNumber(5) - $core.List<$core.List<$core.int>> get blindSigRequests => $_getList(4); -} - -class BlindSigResponses extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlindSigResponses', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scalars', $pb.PbFieldType.PY) - ..hasRequiredFields = false - ; - - BlindSigResponses._() : super(); - factory BlindSigResponses({ - $core.Iterable<$core.List<$core.int>>? scalars, - }) { - final _result = create(); - if (scalars != null) { - _result.scalars.addAll(scalars); - } - return _result; - } - factory BlindSigResponses.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory BlindSigResponses.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - BlindSigResponses clone() => BlindSigResponses()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - BlindSigResponses copyWith(void Function(BlindSigResponses) updates) => super.copyWith((message) => updates(message as BlindSigResponses)) as BlindSigResponses; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static BlindSigResponses create() => BlindSigResponses._(); - BlindSigResponses createEmptyInstance() => create(); - static $pb.PbList<BlindSigResponses> createRepeated() => $pb.PbList<BlindSigResponses>(); - @$core.pragma('dart2js:noInline') - static BlindSigResponses getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BlindSigResponses>(create); - static BlindSigResponses? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.List<$core.int>> get scalars => $_getList(0); -} - -class AllCommitments extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AllCommitments', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'initialCommitments', $pb.PbFieldType.PY) - ..hasRequiredFields = false - ; - - AllCommitments._() : super(); - factory AllCommitments({ - $core.Iterable<$core.List<$core.int>>? initialCommitments, - }) { - final _result = create(); - if (initialCommitments != null) { - _result.initialCommitments.addAll(initialCommitments); - } - return _result; - } - factory AllCommitments.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory AllCommitments.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - AllCommitments clone() => AllCommitments()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - AllCommitments copyWith(void Function(AllCommitments) updates) => super.copyWith((message) => updates(message as AllCommitments)) as AllCommitments; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static AllCommitments create() => AllCommitments._(); - AllCommitments createEmptyInstance() => create(); - static $pb.PbList<AllCommitments> createRepeated() => $pb.PbList<AllCommitments>(); - @$core.pragma('dart2js:noInline') - static AllCommitments getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AllCommitments>(create); - static AllCommitments? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.List<$core.int>> get initialCommitments => $_getList(0); -} - -class CovertComponent extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.OY) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signature', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'component', $pb.PbFieldType.QY) - ; - - CovertComponent._() : super(); - factory CovertComponent({ - $core.List<$core.int>? roundPubkey, - $core.List<$core.int>? signature, - $core.List<$core.int>? component, - }) { - final _result = create(); - if (roundPubkey != null) { - _result.roundPubkey = roundPubkey; - } - if (signature != null) { - _result.signature = signature; - } - if (component != null) { - _result.component = component; - } - return _result; - } - factory CovertComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CovertComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CovertComponent clone() => CovertComponent()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CovertComponent copyWith(void Function(CovertComponent) updates) => super.copyWith((message) => updates(message as CovertComponent)) as CovertComponent; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CovertComponent create() => CovertComponent._(); - CovertComponent createEmptyInstance() => create(); - static $pb.PbList<CovertComponent> createRepeated() => $pb.PbList<CovertComponent>(); - @$core.pragma('dart2js:noInline') - static CovertComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertComponent>(create); - static CovertComponent? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get roundPubkey => $_getN(0); - @$pb.TagNumber(1) - set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasRoundPubkey() => $_has(0); - @$pb.TagNumber(1) - void clearRoundPubkey() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get signature => $_getN(1); - @$pb.TagNumber(2) - set signature($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasSignature() => $_has(1); - @$pb.TagNumber(2) - void clearSignature() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get component => $_getN(2); - @$pb.TagNumber(3) - set component($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasComponent() => $_has(2); - @$pb.TagNumber(3) - void clearComponent() => clearField(3); -} - -class ShareCovertComponents extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ShareCovertComponents', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$core.List<$core.int>>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'components', $pb.PbFieldType.PY) - ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'skipSignatures') - ..a<$core.List<$core.int>>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sessionHash', $pb.PbFieldType.OY) - ..hasRequiredFields = false - ; - - ShareCovertComponents._() : super(); - factory ShareCovertComponents({ - $core.Iterable<$core.List<$core.int>>? components, - $core.bool? skipSignatures, - $core.List<$core.int>? sessionHash, - }) { - final _result = create(); - if (components != null) { - _result.components.addAll(components); - } - if (skipSignatures != null) { - _result.skipSignatures = skipSignatures; - } - if (sessionHash != null) { - _result.sessionHash = sessionHash; - } - return _result; - } - factory ShareCovertComponents.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ShareCovertComponents.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - ShareCovertComponents clone() => ShareCovertComponents()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - ShareCovertComponents copyWith(void Function(ShareCovertComponents) updates) => super.copyWith((message) => updates(message as ShareCovertComponents)) as ShareCovertComponents; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static ShareCovertComponents create() => ShareCovertComponents._(); - ShareCovertComponents createEmptyInstance() => create(); - static $pb.PbList<ShareCovertComponents> createRepeated() => $pb.PbList<ShareCovertComponents>(); - @$core.pragma('dart2js:noInline') - static ShareCovertComponents getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ShareCovertComponents>(create); - static ShareCovertComponents? _defaultInstance; - - @$pb.TagNumber(4) - $core.List<$core.List<$core.int>> get components => $_getList(0); - - @$pb.TagNumber(5) - $core.bool get skipSignatures => $_getBF(1); - @$pb.TagNumber(5) - set skipSignatures($core.bool v) { $_setBool(1, v); } - @$pb.TagNumber(5) - $core.bool hasSkipSignatures() => $_has(1); - @$pb.TagNumber(5) - void clearSkipSignatures() => clearField(5); - - @$pb.TagNumber(6) - $core.List<$core.int> get sessionHash => $_getN(2); - @$pb.TagNumber(6) - set sessionHash($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(6) - $core.bool hasSessionHash() => $_has(2); - @$pb.TagNumber(6) - void clearSessionHash() => clearField(6); -} - -class CovertTransactionSignature extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertTransactionSignature', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.OY) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'whichInput', $pb.PbFieldType.QU3) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'txsignature', $pb.PbFieldType.QY) - ; - - CovertTransactionSignature._() : super(); - factory CovertTransactionSignature({ - $core.List<$core.int>? roundPubkey, - $core.int? whichInput, - $core.List<$core.int>? txsignature, - }) { - final _result = create(); - if (roundPubkey != null) { - _result.roundPubkey = roundPubkey; - } - if (whichInput != null) { - _result.whichInput = whichInput; - } - if (txsignature != null) { - _result.txsignature = txsignature; - } - return _result; - } - factory CovertTransactionSignature.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CovertTransactionSignature.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CovertTransactionSignature clone() => CovertTransactionSignature()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CovertTransactionSignature copyWith(void Function(CovertTransactionSignature) updates) => super.copyWith((message) => updates(message as CovertTransactionSignature)) as CovertTransactionSignature; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CovertTransactionSignature create() => CovertTransactionSignature._(); - CovertTransactionSignature createEmptyInstance() => create(); - static $pb.PbList<CovertTransactionSignature> createRepeated() => $pb.PbList<CovertTransactionSignature>(); - @$core.pragma('dart2js:noInline') - static CovertTransactionSignature getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertTransactionSignature>(create); - static CovertTransactionSignature? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get roundPubkey => $_getN(0); - @$pb.TagNumber(1) - set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasRoundPubkey() => $_has(0); - @$pb.TagNumber(1) - void clearRoundPubkey() => clearField(1); - - @$pb.TagNumber(2) - $core.int get whichInput => $_getIZ(1); - @$pb.TagNumber(2) - set whichInput($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasWhichInput() => $_has(1); - @$pb.TagNumber(2) - void clearWhichInput() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get txsignature => $_getN(2); - @$pb.TagNumber(3) - set txsignature($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasTxsignature() => $_has(2); - @$pb.TagNumber(3) - void clearTxsignature() => clearField(3); -} - -class FusionResult extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FusionResult', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.bool>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ok', $pb.PbFieldType.QB) - ..p<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'txsignatures', $pb.PbFieldType.PY) - ..p<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'badComponents', $pb.PbFieldType.PU3) - ; - - FusionResult._() : super(); - factory FusionResult({ - $core.bool? ok, - $core.Iterable<$core.List<$core.int>>? txsignatures, - $core.Iterable<$core.int>? badComponents, - }) { - final _result = create(); - if (ok != null) { - _result.ok = ok; - } - if (txsignatures != null) { - _result.txsignatures.addAll(txsignatures); - } - if (badComponents != null) { - _result.badComponents.addAll(badComponents); - } - return _result; - } - factory FusionResult.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory FusionResult.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - FusionResult clone() => FusionResult()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - FusionResult copyWith(void Function(FusionResult) updates) => super.copyWith((message) => updates(message as FusionResult)) as FusionResult; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static FusionResult create() => FusionResult._(); - FusionResult createEmptyInstance() => create(); - static $pb.PbList<FusionResult> createRepeated() => $pb.PbList<FusionResult>(); - @$core.pragma('dart2js:noInline') - static FusionResult getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FusionResult>(create); - static FusionResult? _defaultInstance; - - @$pb.TagNumber(1) - $core.bool get ok => $_getBF(0); - @$pb.TagNumber(1) - set ok($core.bool v) { $_setBool(0, v); } - @$pb.TagNumber(1) - $core.bool hasOk() => $_has(0); - @$pb.TagNumber(1) - void clearOk() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.List<$core.int>> get txsignatures => $_getList(1); - - @$pb.TagNumber(3) - $core.List<$core.int> get badComponents => $_getList(2); -} - -class MyProofsList extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MyProofsList', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'encryptedProofs', $pb.PbFieldType.PY) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'randomNumber', $pb.PbFieldType.QY) - ; - - MyProofsList._() : super(); - factory MyProofsList({ - $core.Iterable<$core.List<$core.int>>? encryptedProofs, - $core.List<$core.int>? randomNumber, - }) { - final _result = create(); - if (encryptedProofs != null) { - _result.encryptedProofs.addAll(encryptedProofs); - } - if (randomNumber != null) { - _result.randomNumber = randomNumber; - } - return _result; - } - factory MyProofsList.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory MyProofsList.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - MyProofsList clone() => MyProofsList()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - MyProofsList copyWith(void Function(MyProofsList) updates) => super.copyWith((message) => updates(message as MyProofsList)) as MyProofsList; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static MyProofsList create() => MyProofsList._(); - MyProofsList createEmptyInstance() => create(); - static $pb.PbList<MyProofsList> createRepeated() => $pb.PbList<MyProofsList>(); - @$core.pragma('dart2js:noInline') - static MyProofsList getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<MyProofsList>(create); - static MyProofsList? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.List<$core.int>> get encryptedProofs => $_getList(0); - - @$pb.TagNumber(2) - $core.List<$core.int> get randomNumber => $_getN(1); - @$pb.TagNumber(2) - set randomNumber($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasRandomNumber() => $_has(1); - @$pb.TagNumber(2) - void clearRandomNumber() => clearField(2); -} - -class TheirProofsList_RelayedProof extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TheirProofsList.RelayedProof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'encryptedProof', $pb.PbFieldType.QY) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'srcCommitmentIdx', $pb.PbFieldType.QU3) - ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dstKeyIdx', $pb.PbFieldType.QU3) - ; - - TheirProofsList_RelayedProof._() : super(); - factory TheirProofsList_RelayedProof({ - $core.List<$core.int>? encryptedProof, - $core.int? srcCommitmentIdx, - $core.int? dstKeyIdx, - }) { - final _result = create(); - if (encryptedProof != null) { - _result.encryptedProof = encryptedProof; - } - if (srcCommitmentIdx != null) { - _result.srcCommitmentIdx = srcCommitmentIdx; - } - if (dstKeyIdx != null) { - _result.dstKeyIdx = dstKeyIdx; - } - return _result; - } - factory TheirProofsList_RelayedProof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory TheirProofsList_RelayedProof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - TheirProofsList_RelayedProof clone() => TheirProofsList_RelayedProof()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - TheirProofsList_RelayedProof copyWith(void Function(TheirProofsList_RelayedProof) updates) => super.copyWith((message) => updates(message as TheirProofsList_RelayedProof)) as TheirProofsList_RelayedProof; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static TheirProofsList_RelayedProof create() => TheirProofsList_RelayedProof._(); - TheirProofsList_RelayedProof createEmptyInstance() => create(); - static $pb.PbList<TheirProofsList_RelayedProof> createRepeated() => $pb.PbList<TheirProofsList_RelayedProof>(); - @$core.pragma('dart2js:noInline') - static TheirProofsList_RelayedProof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TheirProofsList_RelayedProof>(create); - static TheirProofsList_RelayedProof? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get encryptedProof => $_getN(0); - @$pb.TagNumber(1) - set encryptedProof($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasEncryptedProof() => $_has(0); - @$pb.TagNumber(1) - void clearEncryptedProof() => clearField(1); - - @$pb.TagNumber(2) - $core.int get srcCommitmentIdx => $_getIZ(1); - @$pb.TagNumber(2) - set srcCommitmentIdx($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasSrcCommitmentIdx() => $_has(1); - @$pb.TagNumber(2) - void clearSrcCommitmentIdx() => clearField(2); - - @$pb.TagNumber(3) - $core.int get dstKeyIdx => $_getIZ(2); - @$pb.TagNumber(3) - set dstKeyIdx($core.int v) { $_setUnsignedInt32(2, v); } - @$pb.TagNumber(3) - $core.bool hasDstKeyIdx() => $_has(2); - @$pb.TagNumber(3) - void clearDstKeyIdx() => clearField(3); -} - -class TheirProofsList extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TheirProofsList', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..pc<TheirProofsList_RelayedProof>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'proofs', $pb.PbFieldType.PM, subBuilder: TheirProofsList_RelayedProof.create) - ; - - TheirProofsList._() : super(); - factory TheirProofsList({ - $core.Iterable<TheirProofsList_RelayedProof>? proofs, - }) { - final _result = create(); - if (proofs != null) { - _result.proofs.addAll(proofs); - } - return _result; - } - factory TheirProofsList.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory TheirProofsList.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - TheirProofsList clone() => TheirProofsList()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - TheirProofsList copyWith(void Function(TheirProofsList) updates) => super.copyWith((message) => updates(message as TheirProofsList)) as TheirProofsList; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static TheirProofsList create() => TheirProofsList._(); - TheirProofsList createEmptyInstance() => create(); - static $pb.PbList<TheirProofsList> createRepeated() => $pb.PbList<TheirProofsList>(); - @$core.pragma('dart2js:noInline') - static TheirProofsList getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TheirProofsList>(create); - static TheirProofsList? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<TheirProofsList_RelayedProof> get proofs => $_getList(0); -} - -enum Blames_BlameProof_Decrypter { - sessionKey, - privkey, - notSet -} - -class Blames_BlameProof extends $pb.GeneratedMessage { - static const $core.Map<$core.int, Blames_BlameProof_Decrypter> _Blames_BlameProof_DecrypterByTag = { - 2 : Blames_BlameProof_Decrypter.sessionKey, - 3 : Blames_BlameProof_Decrypter.privkey, - 0 : Blames_BlameProof_Decrypter.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Blames.BlameProof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [2, 3]) - ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'whichProof', $pb.PbFieldType.QU3) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sessionKey', $pb.PbFieldType.OY) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'privkey', $pb.PbFieldType.OY) - ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'needLookupBlockchain') - ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blameReason') - ; - - Blames_BlameProof._() : super(); - factory Blames_BlameProof({ - $core.int? whichProof, - $core.List<$core.int>? sessionKey, - $core.List<$core.int>? privkey, - $core.bool? needLookupBlockchain, - $core.String? blameReason, - }) { - final _result = create(); - if (whichProof != null) { - _result.whichProof = whichProof; - } - if (sessionKey != null) { - _result.sessionKey = sessionKey; - } - if (privkey != null) { - _result.privkey = privkey; - } - if (needLookupBlockchain != null) { - _result.needLookupBlockchain = needLookupBlockchain; - } - if (blameReason != null) { - _result.blameReason = blameReason; - } - return _result; - } - factory Blames_BlameProof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Blames_BlameProof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Blames_BlameProof clone() => Blames_BlameProof()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Blames_BlameProof copyWith(void Function(Blames_BlameProof) updates) => super.copyWith((message) => updates(message as Blames_BlameProof)) as Blames_BlameProof; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Blames_BlameProof create() => Blames_BlameProof._(); - Blames_BlameProof createEmptyInstance() => create(); - static $pb.PbList<Blames_BlameProof> createRepeated() => $pb.PbList<Blames_BlameProof>(); - @$core.pragma('dart2js:noInline') - static Blames_BlameProof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Blames_BlameProof>(create); - static Blames_BlameProof? _defaultInstance; - - Blames_BlameProof_Decrypter whichDecrypter() => _Blames_BlameProof_DecrypterByTag[$_whichOneof(0)]!; - void clearDecrypter() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - $core.int get whichProof => $_getIZ(0); - @$pb.TagNumber(1) - set whichProof($core.int v) { $_setUnsignedInt32(0, v); } - @$pb.TagNumber(1) - $core.bool hasWhichProof() => $_has(0); - @$pb.TagNumber(1) - void clearWhichProof() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get sessionKey => $_getN(1); - @$pb.TagNumber(2) - set sessionKey($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasSessionKey() => $_has(1); - @$pb.TagNumber(2) - void clearSessionKey() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get privkey => $_getN(2); - @$pb.TagNumber(3) - set privkey($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasPrivkey() => $_has(2); - @$pb.TagNumber(3) - void clearPrivkey() => clearField(3); - - @$pb.TagNumber(4) - $core.bool get needLookupBlockchain => $_getBF(3); - @$pb.TagNumber(4) - set needLookupBlockchain($core.bool v) { $_setBool(3, v); } - @$pb.TagNumber(4) - $core.bool hasNeedLookupBlockchain() => $_has(3); - @$pb.TagNumber(4) - void clearNeedLookupBlockchain() => clearField(4); - - @$pb.TagNumber(5) - $core.String get blameReason => $_getSZ(4); - @$pb.TagNumber(5) - set blameReason($core.String v) { $_setString(4, v); } - @$pb.TagNumber(5) - $core.bool hasBlameReason() => $_has(4); - @$pb.TagNumber(5) - void clearBlameReason() => clearField(5); -} - -class Blames extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Blames', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..pc<Blames_BlameProof>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blames', $pb.PbFieldType.PM, subBuilder: Blames_BlameProof.create) - ; - - Blames._() : super(); - factory Blames({ - $core.Iterable<Blames_BlameProof>? blames, - }) { - final _result = create(); - if (blames != null) { - _result.blames.addAll(blames); - } - return _result; - } - factory Blames.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Blames.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Blames clone() => Blames()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Blames copyWith(void Function(Blames) updates) => super.copyWith((message) => updates(message as Blames)) as Blames; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Blames create() => Blames._(); - Blames createEmptyInstance() => create(); - static $pb.PbList<Blames> createRepeated() => $pb.PbList<Blames>(); - @$core.pragma('dart2js:noInline') - static Blames getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Blames>(create); - static Blames? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<Blames_BlameProof> get blames => $_getList(0); -} - -class RestartRound extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RestartRound', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..hasRequiredFields = false - ; - - RestartRound._() : super(); - factory RestartRound() => create(); - factory RestartRound.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RestartRound.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RestartRound clone() => RestartRound()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RestartRound copyWith(void Function(RestartRound) updates) => super.copyWith((message) => updates(message as RestartRound)) as RestartRound; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RestartRound create() => RestartRound._(); - RestartRound createEmptyInstance() => create(); - static $pb.PbList<RestartRound> createRepeated() => $pb.PbList<RestartRound>(); - @$core.pragma('dart2js:noInline') - static RestartRound getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RestartRound>(create); - static RestartRound? _defaultInstance; -} - -class Error extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Error', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'message') - ..hasRequiredFields = false - ; - - Error._() : super(); - factory Error({ - $core.String? message, - }) { - final _result = create(); - if (message != null) { - _result.message = message; - } - return _result; - } - factory Error.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Error.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Error clone() => Error()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Error copyWith(void Function(Error) updates) => super.copyWith((message) => updates(message as Error)) as Error; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Error create() => Error._(); - Error createEmptyInstance() => create(); - static $pb.PbList<Error> createRepeated() => $pb.PbList<Error>(); - @$core.pragma('dart2js:noInline') - static Error getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Error>(create); - static Error? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get message => $_getSZ(0); - @$pb.TagNumber(1) - set message($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasMessage() => $_has(0); - @$pb.TagNumber(1) - void clearMessage() => clearField(1); -} - -class Ping extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Ping', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..hasRequiredFields = false - ; - - Ping._() : super(); - factory Ping() => create(); - factory Ping.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Ping.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Ping clone() => Ping()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Ping copyWith(void Function(Ping) updates) => super.copyWith((message) => updates(message as Ping)) as Ping; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Ping create() => Ping._(); - Ping createEmptyInstance() => create(); - static $pb.PbList<Ping> createRepeated() => $pb.PbList<Ping>(); - @$core.pragma('dart2js:noInline') - static Ping getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Ping>(create); - static Ping? _defaultInstance; -} - -class OK extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'OK', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..hasRequiredFields = false - ; - - OK._() : super(); - factory OK() => create(); - factory OK.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory OK.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - OK clone() => OK()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - OK copyWith(void Function(OK) updates) => super.copyWith((message) => updates(message as OK)) as OK; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static OK create() => OK._(); - OK createEmptyInstance() => create(); - static $pb.PbList<OK> createRepeated() => $pb.PbList<OK>(); - @$core.pragma('dart2js:noInline') - static OK getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OK>(create); - static OK? _defaultInstance; -} - -enum ClientMessage_Msg { - clienthello, - joinpools, - playercommit, - myproofslist, - blames, - notSet -} - -class ClientMessage extends $pb.GeneratedMessage { - static const $core.Map<$core.int, ClientMessage_Msg> _ClientMessage_MsgByTag = { - 1 : ClientMessage_Msg.clienthello, - 2 : ClientMessage_Msg.joinpools, - 3 : ClientMessage_Msg.playercommit, - 5 : ClientMessage_Msg.myproofslist, - 6 : ClientMessage_Msg.blames, - 0 : ClientMessage_Msg.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ClientMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [1, 2, 3, 5, 6]) - ..aOM<ClientHello>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'clienthello', subBuilder: ClientHello.create) - ..aOM<JoinPools>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'joinpools', subBuilder: JoinPools.create) - ..aOM<PlayerCommit>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'playercommit', subBuilder: PlayerCommit.create) - ..aOM<MyProofsList>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'myproofslist', subBuilder: MyProofsList.create) - ..aOM<Blames>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blames', subBuilder: Blames.create) - ; - - ClientMessage._() : super(); - factory ClientMessage({ - ClientHello? clienthello, - JoinPools? joinpools, - PlayerCommit? playercommit, - MyProofsList? myproofslist, - Blames? blames, - }) { - final _result = create(); - if (clienthello != null) { - _result.clienthello = clienthello; - } - if (joinpools != null) { - _result.joinpools = joinpools; - } - if (playercommit != null) { - _result.playercommit = playercommit; - } - if (myproofslist != null) { - _result.myproofslist = myproofslist; - } - if (blames != null) { - _result.blames = blames; - } - return _result; - } - factory ClientMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ClientMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - ClientMessage clone() => ClientMessage()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - ClientMessage copyWith(void Function(ClientMessage) updates) => super.copyWith((message) => updates(message as ClientMessage)) as ClientMessage; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static ClientMessage create() => ClientMessage._(); - ClientMessage createEmptyInstance() => create(); - static $pb.PbList<ClientMessage> createRepeated() => $pb.PbList<ClientMessage>(); - @$core.pragma('dart2js:noInline') - static ClientMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ClientMessage>(create); - static ClientMessage? _defaultInstance; - - ClientMessage_Msg whichMsg() => _ClientMessage_MsgByTag[$_whichOneof(0)]!; - void clearMsg() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - ClientHello get clienthello => $_getN(0); - @$pb.TagNumber(1) - set clienthello(ClientHello v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasClienthello() => $_has(0); - @$pb.TagNumber(1) - void clearClienthello() => clearField(1); - @$pb.TagNumber(1) - ClientHello ensureClienthello() => $_ensure(0); - - @$pb.TagNumber(2) - JoinPools get joinpools => $_getN(1); - @$pb.TagNumber(2) - set joinpools(JoinPools v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasJoinpools() => $_has(1); - @$pb.TagNumber(2) - void clearJoinpools() => clearField(2); - @$pb.TagNumber(2) - JoinPools ensureJoinpools() => $_ensure(1); - - @$pb.TagNumber(3) - PlayerCommit get playercommit => $_getN(2); - @$pb.TagNumber(3) - set playercommit(PlayerCommit v) { setField(3, v); } - @$pb.TagNumber(3) - $core.bool hasPlayercommit() => $_has(2); - @$pb.TagNumber(3) - void clearPlayercommit() => clearField(3); - @$pb.TagNumber(3) - PlayerCommit ensurePlayercommit() => $_ensure(2); - - @$pb.TagNumber(5) - MyProofsList get myproofslist => $_getN(3); - @$pb.TagNumber(5) - set myproofslist(MyProofsList v) { setField(5, v); } - @$pb.TagNumber(5) - $core.bool hasMyproofslist() => $_has(3); - @$pb.TagNumber(5) - void clearMyproofslist() => clearField(5); - @$pb.TagNumber(5) - MyProofsList ensureMyproofslist() => $_ensure(3); - - @$pb.TagNumber(6) - Blames get blames => $_getN(4); - @$pb.TagNumber(6) - set blames(Blames v) { setField(6, v); } - @$pb.TagNumber(6) - $core.bool hasBlames() => $_has(4); - @$pb.TagNumber(6) - void clearBlames() => clearField(6); - @$pb.TagNumber(6) - Blames ensureBlames() => $_ensure(4); -} - -enum ServerMessage_Msg { - serverhello, - tierstatusupdate, - fusionbegin, - startround, - blindsigresponses, - allcommitments, - sharecovertcomponents, - fusionresult, - theirproofslist, - restartround, - error, - notSet -} - -class ServerMessage extends $pb.GeneratedMessage { - static const $core.Map<$core.int, ServerMessage_Msg> _ServerMessage_MsgByTag = { - 1 : ServerMessage_Msg.serverhello, - 2 : ServerMessage_Msg.tierstatusupdate, - 3 : ServerMessage_Msg.fusionbegin, - 4 : ServerMessage_Msg.startround, - 5 : ServerMessage_Msg.blindsigresponses, - 6 : ServerMessage_Msg.allcommitments, - 7 : ServerMessage_Msg.sharecovertcomponents, - 8 : ServerMessage_Msg.fusionresult, - 9 : ServerMessage_Msg.theirproofslist, - 14 : ServerMessage_Msg.restartround, - 15 : ServerMessage_Msg.error, - 0 : ServerMessage_Msg.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ServerMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15]) - ..aOM<ServerHello>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverhello', subBuilder: ServerHello.create) - ..aOM<TierStatusUpdate>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tierstatusupdate', subBuilder: TierStatusUpdate.create) - ..aOM<FusionBegin>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fusionbegin', subBuilder: FusionBegin.create) - ..aOM<StartRound>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startround', subBuilder: StartRound.create) - ..aOM<BlindSigResponses>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindsigresponses', subBuilder: BlindSigResponses.create) - ..aOM<AllCommitments>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'allcommitments', subBuilder: AllCommitments.create) - ..aOM<ShareCovertComponents>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sharecovertcomponents', subBuilder: ShareCovertComponents.create) - ..aOM<FusionResult>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fusionresult', subBuilder: FusionResult.create) - ..aOM<TheirProofsList>(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'theirproofslist', subBuilder: TheirProofsList.create) - ..aOM<RestartRound>(14, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'restartround', subBuilder: RestartRound.create) - ..aOM<Error>(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'error', subBuilder: Error.create) - ; - - ServerMessage._() : super(); - factory ServerMessage({ - ServerHello? serverhello, - TierStatusUpdate? tierstatusupdate, - FusionBegin? fusionbegin, - StartRound? startround, - BlindSigResponses? blindsigresponses, - AllCommitments? allcommitments, - ShareCovertComponents? sharecovertcomponents, - FusionResult? fusionresult, - TheirProofsList? theirproofslist, - RestartRound? restartround, - Error? error, - }) { - final _result = create(); - if (serverhello != null) { - _result.serverhello = serverhello; - } - if (tierstatusupdate != null) { - _result.tierstatusupdate = tierstatusupdate; - } - if (fusionbegin != null) { - _result.fusionbegin = fusionbegin; - } - if (startround != null) { - _result.startround = startround; - } - if (blindsigresponses != null) { - _result.blindsigresponses = blindsigresponses; - } - if (allcommitments != null) { - _result.allcommitments = allcommitments; - } - if (sharecovertcomponents != null) { - _result.sharecovertcomponents = sharecovertcomponents; - } - if (fusionresult != null) { - _result.fusionresult = fusionresult; - } - if (theirproofslist != null) { - _result.theirproofslist = theirproofslist; - } - if (restartround != null) { - _result.restartround = restartround; - } - if (error != null) { - _result.error = error; - } - return _result; - } - factory ServerMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ServerMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - ServerMessage clone() => ServerMessage()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - ServerMessage copyWith(void Function(ServerMessage) updates) => super.copyWith((message) => updates(message as ServerMessage)) as ServerMessage; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static ServerMessage create() => ServerMessage._(); - ServerMessage createEmptyInstance() => create(); - static $pb.PbList<ServerMessage> createRepeated() => $pb.PbList<ServerMessage>(); - @$core.pragma('dart2js:noInline') - static ServerMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ServerMessage>(create); - static ServerMessage? _defaultInstance; - - ServerMessage_Msg whichMsg() => _ServerMessage_MsgByTag[$_whichOneof(0)]!; - void clearMsg() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - ServerHello get serverhello => $_getN(0); - @$pb.TagNumber(1) - set serverhello(ServerHello v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasServerhello() => $_has(0); - @$pb.TagNumber(1) - void clearServerhello() => clearField(1); - @$pb.TagNumber(1) - ServerHello ensureServerhello() => $_ensure(0); - - @$pb.TagNumber(2) - TierStatusUpdate get tierstatusupdate => $_getN(1); - @$pb.TagNumber(2) - set tierstatusupdate(TierStatusUpdate v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasTierstatusupdate() => $_has(1); - @$pb.TagNumber(2) - void clearTierstatusupdate() => clearField(2); - @$pb.TagNumber(2) - TierStatusUpdate ensureTierstatusupdate() => $_ensure(1); - - @$pb.TagNumber(3) - FusionBegin get fusionbegin => $_getN(2); - @$pb.TagNumber(3) - set fusionbegin(FusionBegin v) { setField(3, v); } - @$pb.TagNumber(3) - $core.bool hasFusionbegin() => $_has(2); - @$pb.TagNumber(3) - void clearFusionbegin() => clearField(3); - @$pb.TagNumber(3) - FusionBegin ensureFusionbegin() => $_ensure(2); - - @$pb.TagNumber(4) - StartRound get startround => $_getN(3); - @$pb.TagNumber(4) - set startround(StartRound v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasStartround() => $_has(3); - @$pb.TagNumber(4) - void clearStartround() => clearField(4); - @$pb.TagNumber(4) - StartRound ensureStartround() => $_ensure(3); - - @$pb.TagNumber(5) - BlindSigResponses get blindsigresponses => $_getN(4); - @$pb.TagNumber(5) - set blindsigresponses(BlindSigResponses v) { setField(5, v); } - @$pb.TagNumber(5) - $core.bool hasBlindsigresponses() => $_has(4); - @$pb.TagNumber(5) - void clearBlindsigresponses() => clearField(5); - @$pb.TagNumber(5) - BlindSigResponses ensureBlindsigresponses() => $_ensure(4); - - @$pb.TagNumber(6) - AllCommitments get allcommitments => $_getN(5); - @$pb.TagNumber(6) - set allcommitments(AllCommitments v) { setField(6, v); } - @$pb.TagNumber(6) - $core.bool hasAllcommitments() => $_has(5); - @$pb.TagNumber(6) - void clearAllcommitments() => clearField(6); - @$pb.TagNumber(6) - AllCommitments ensureAllcommitments() => $_ensure(5); - - @$pb.TagNumber(7) - ShareCovertComponents get sharecovertcomponents => $_getN(6); - @$pb.TagNumber(7) - set sharecovertcomponents(ShareCovertComponents v) { setField(7, v); } - @$pb.TagNumber(7) - $core.bool hasSharecovertcomponents() => $_has(6); - @$pb.TagNumber(7) - void clearSharecovertcomponents() => clearField(7); - @$pb.TagNumber(7) - ShareCovertComponents ensureSharecovertcomponents() => $_ensure(6); - - @$pb.TagNumber(8) - FusionResult get fusionresult => $_getN(7); - @$pb.TagNumber(8) - set fusionresult(FusionResult v) { setField(8, v); } - @$pb.TagNumber(8) - $core.bool hasFusionresult() => $_has(7); - @$pb.TagNumber(8) - void clearFusionresult() => clearField(8); - @$pb.TagNumber(8) - FusionResult ensureFusionresult() => $_ensure(7); - - @$pb.TagNumber(9) - TheirProofsList get theirproofslist => $_getN(8); - @$pb.TagNumber(9) - set theirproofslist(TheirProofsList v) { setField(9, v); } - @$pb.TagNumber(9) - $core.bool hasTheirproofslist() => $_has(8); - @$pb.TagNumber(9) - void clearTheirproofslist() => clearField(9); - @$pb.TagNumber(9) - TheirProofsList ensureTheirproofslist() => $_ensure(8); - - @$pb.TagNumber(14) - RestartRound get restartround => $_getN(9); - @$pb.TagNumber(14) - set restartround(RestartRound v) { setField(14, v); } - @$pb.TagNumber(14) - $core.bool hasRestartround() => $_has(9); - @$pb.TagNumber(14) - void clearRestartround() => clearField(14); - @$pb.TagNumber(14) - RestartRound ensureRestartround() => $_ensure(9); - - @$pb.TagNumber(15) - Error get error => $_getN(10); - @$pb.TagNumber(15) - set error(Error v) { setField(15, v); } - @$pb.TagNumber(15) - $core.bool hasError() => $_has(10); - @$pb.TagNumber(15) - void clearError() => clearField(15); - @$pb.TagNumber(15) - Error ensureError() => $_ensure(10); -} - -enum CovertMessage_Msg { - component, - signature, - ping, - notSet -} - -class CovertMessage extends $pb.GeneratedMessage { - static const $core.Map<$core.int, CovertMessage_Msg> _CovertMessage_MsgByTag = { - 1 : CovertMessage_Msg.component, - 2 : CovertMessage_Msg.signature, - 3 : CovertMessage_Msg.ping, - 0 : CovertMessage_Msg.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [1, 2, 3]) - ..aOM<CovertComponent>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'component', subBuilder: CovertComponent.create) - ..aOM<CovertTransactionSignature>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signature', subBuilder: CovertTransactionSignature.create) - ..aOM<Ping>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ping', subBuilder: Ping.create) - ; - - CovertMessage._() : super(); - factory CovertMessage({ - CovertComponent? component, - CovertTransactionSignature? signature, - Ping? ping, - }) { - final _result = create(); - if (component != null) { - _result.component = component; - } - if (signature != null) { - _result.signature = signature; - } - if (ping != null) { - _result.ping = ping; - } - return _result; - } - factory CovertMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CovertMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CovertMessage clone() => CovertMessage()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CovertMessage copyWith(void Function(CovertMessage) updates) => super.copyWith((message) => updates(message as CovertMessage)) as CovertMessage; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CovertMessage create() => CovertMessage._(); - CovertMessage createEmptyInstance() => create(); - static $pb.PbList<CovertMessage> createRepeated() => $pb.PbList<CovertMessage>(); - @$core.pragma('dart2js:noInline') - static CovertMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertMessage>(create); - static CovertMessage? _defaultInstance; - - CovertMessage_Msg whichMsg() => _CovertMessage_MsgByTag[$_whichOneof(0)]!; - void clearMsg() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - CovertComponent get component => $_getN(0); - @$pb.TagNumber(1) - set component(CovertComponent v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasComponent() => $_has(0); - @$pb.TagNumber(1) - void clearComponent() => clearField(1); - @$pb.TagNumber(1) - CovertComponent ensureComponent() => $_ensure(0); - - @$pb.TagNumber(2) - CovertTransactionSignature get signature => $_getN(1); - @$pb.TagNumber(2) - set signature(CovertTransactionSignature v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasSignature() => $_has(1); - @$pb.TagNumber(2) - void clearSignature() => clearField(2); - @$pb.TagNumber(2) - CovertTransactionSignature ensureSignature() => $_ensure(1); - - @$pb.TagNumber(3) - Ping get ping => $_getN(2); - @$pb.TagNumber(3) - set ping(Ping v) { setField(3, v); } - @$pb.TagNumber(3) - $core.bool hasPing() => $_has(2); - @$pb.TagNumber(3) - void clearPing() => clearField(3); - @$pb.TagNumber(3) - Ping ensurePing() => $_ensure(2); -} - -enum CovertResponse_Msg { - ok, - error, - notSet -} - -class CovertResponse extends $pb.GeneratedMessage { - static const $core.Map<$core.int, CovertResponse_Msg> _CovertResponse_MsgByTag = { - 1 : CovertResponse_Msg.ok, - 15 : CovertResponse_Msg.error, - 0 : CovertResponse_Msg.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [1, 15]) - ..aOM<OK>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ok', subBuilder: OK.create) - ..aOM<Error>(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'error', subBuilder: Error.create) - ..hasRequiredFields = false - ; - - CovertResponse._() : super(); - factory CovertResponse({ - OK? ok, - Error? error, - }) { - final _result = create(); - if (ok != null) { - _result.ok = ok; - } - if (error != null) { - _result.error = error; - } - return _result; - } - factory CovertResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CovertResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CovertResponse clone() => CovertResponse()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CovertResponse copyWith(void Function(CovertResponse) updates) => super.copyWith((message) => updates(message as CovertResponse)) as CovertResponse; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CovertResponse create() => CovertResponse._(); - CovertResponse createEmptyInstance() => create(); - static $pb.PbList<CovertResponse> createRepeated() => $pb.PbList<CovertResponse>(); - @$core.pragma('dart2js:noInline') - static CovertResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertResponse>(create); - static CovertResponse? _defaultInstance; - - CovertResponse_Msg whichMsg() => _CovertResponse_MsgByTag[$_whichOneof(0)]!; - void clearMsg() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - OK get ok => $_getN(0); - @$pb.TagNumber(1) - set ok(OK v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasOk() => $_has(0); - @$pb.TagNumber(1) - void clearOk() => clearField(1); - @$pb.TagNumber(1) - OK ensureOk() => $_ensure(0); - - @$pb.TagNumber(15) - Error get error => $_getN(1); - @$pb.TagNumber(15) - set error(Error v) { setField(15, v); } - @$pb.TagNumber(15) - $core.bool hasError() => $_has(1); - @$pb.TagNumber(15) - void clearError() => clearField(15); - @$pb.TagNumber(15) - Error ensureError() => $_ensure(1); -} - diff --git a/lib/services/cashfusion/pedersen.dart b/lib/services/cashfusion/pedersen.dart deleted file mode 100644 index d15ff7800..000000000 --- a/lib/services/cashfusion/pedersen.dart +++ /dev/null @@ -1,195 +0,0 @@ -import 'dart:typed_data'; - -import 'package:pointycastle/ecc/api.dart'; -import 'package:stackwallet/services/cashfusion/util.dart'; - -ECDomainParameters getDefaultParams() { - return ECDomainParameters("secp256k1"); -} - -class NullPointError implements Exception { - String errMsg() => 'NullPointError: Either Hpoint or HGpoint is null.'; -} - -class NonceRangeError implements Exception { - final String message; - NonceRangeError( - [this.message = "Nonce value must be in the range 0 < nonce < order"]); - String toString() => "NonceRangeError: $message"; -} - -class ResultAtInfinity implements Exception { - final String message; - ResultAtInfinity([this.message = "Result is at infinity"]); - String toString() => "ResultAtInfinity: $message"; -} - -class InsecureHPoint implements Exception { - final String message; - InsecureHPoint( - [this.message = - "The H point has a known discrete logarithm, which means the commitment setup is broken"]); - String toString() => "InsecureHPoint: $message"; -} - -class PedersenSetup { - late ECPoint _H; - late ECPoint _HG; - late ECDomainParameters _params; - ECDomainParameters get params => _params; - - PedersenSetup(this._H) { - _params = new ECDomainParameters("secp256k1"); - // validate H point - if (!Util.isPointOnCurve(_H, _params.curve)) { - throw Exception('H is not a valid point on the curve'); - } - _HG = Util.combinePubKeys([_H, _params.G]); - } - - Uint8List get H => _H.getEncoded(false); - Uint8List get HG => _HG.getEncoded(false); - - Commitment commit(BigInt amount, {BigInt? nonce, Uint8List? PUncompressed}) { - return Commitment(this, amount, nonce: nonce, PUncompressed: PUncompressed); - } -} - -class Commitment { - late PedersenSetup setup; // Added setup property to Commitment class - late BigInt amountMod; - late BigInt nonce; - late Uint8List PUncompressed; - - Commitment(this.setup, BigInt amount, - {BigInt? nonce, Uint8List? PUncompressed}) { - this.nonce = nonce ?? Util.secureRandomBigInt(setup.params.n.bitLength); - amountMod = amount % setup.params.n; - - if (this.nonce <= BigInt.zero || this.nonce >= setup.params.n) { - throw NonceRangeError(); - } - - ECPoint? Hpoint = setup._H; - ECPoint? HGpoint = setup._HG; - - if (Hpoint == null || HGpoint == null) { - throw NullPointError(); - } - - BigInt multiplier1 = (amountMod - this.nonce) % setup.params.n; - BigInt multiplier2 = this.nonce; - - ECPoint? HpointMultiplied = Hpoint * multiplier1; - ECPoint? HGpointMultiplied = HGpoint * multiplier2; - - ECPoint? Ppoint = HpointMultiplied != null && HGpointMultiplied != null - ? HpointMultiplied + HGpointMultiplied - : null; - - if (Ppoint == setup.params.curve.infinity) { - throw ResultAtInfinity(); - } - - this.PUncompressed = - PUncompressed ?? Ppoint?.getEncoded(false) ?? Uint8List(0); - } - - void calcInitial(PedersenSetup setup, BigInt amount) { - amountMod = amount % setup.params.n; - nonce = Util.secureRandomBigInt(setup.params.n.bitLength); - - ECPoint? Hpoint = setup._H; - ECPoint? HGpoint = setup._HG; - - if (nonce <= BigInt.zero || nonce >= setup.params.n) { - throw NonceRangeError(); - } - - if (Hpoint == null || HGpoint == null) { - throw NullPointError(); - } - - BigInt multiplier1 = amountMod; - BigInt multiplier2 = nonce; - - ECPoint? HpointMultiplied = Hpoint * multiplier1; - ECPoint? HGpointMultiplied = HGpoint * multiplier2; - - ECPoint? Ppoint = HpointMultiplied != null && HGpointMultiplied != null - ? HpointMultiplied + HGpointMultiplied - : null; - - if (Ppoint == setup.params.curve.infinity) { - throw ResultAtInfinity(); - } - - PUncompressed = Ppoint?.getEncoded(false) ?? Uint8List(0); - } - - static Uint8List add_points(Iterable<Uint8List> pointsIterable) { - ECDomainParameters params = - getDefaultParams(); // Using helper function here - var pointList = - pointsIterable.map((pser) => Util.ser_to_point(pser, params)).toList(); - - if (pointList.isEmpty) { - throw ArgumentError('Empty list'); - } - - ECPoint pSum = - pointList.first; // Initialize pSum with the first point in the list - - for (var i = 1; i < pointList.length; i++) { - pSum = (pSum + pointList[i])!; - } - - if (pSum == params.curve.infinity) { - throw Exception('Result is at infinity'); - } - - return Util.point_to_ser(pSum, false); - } - - Commitment addCommitments(Iterable<Commitment> commitmentIterable) { - BigInt ktotal = BigInt.zero; // Changed to BigInt from int - BigInt atotal = BigInt.zero; // Changed to BigInt from int - List<Uint8List> points = []; - List<PedersenSetup> setups = []; // Changed Setup to PedersenSetup - for (Commitment c in commitmentIterable) { - ktotal += c.nonce; - atotal += c.amountMod; // Changed from amount to amountMod - points.add(c.PUncompressed); - setups.add(c.setup); - } - - if (points.isEmpty) { - throw ArgumentError('Empty list'); - } - - PedersenSetup setup = setups[0]; // Changed Setup to PedersenSetup - if (!setups.every((s) => s == setup)) { - throw ArgumentError('Mismatched setups'); - } - - ktotal = ktotal % setup.params.n; // Changed order to setup.params.n - - if (ktotal == BigInt.zero) { - // Changed comparison from 0 to BigInt.zero - throw Exception('Nonce range error'); - } - - Uint8List? PUncompressed; - if (points.length < 512) { - try { - PUncompressed = add_points(points); - } on Exception { - PUncompressed = null; - } - } else { - PUncompressed = null; - } - return Commitment(setup, atotal, - nonce: ktotal, PUncompressed: PUncompressed); - } -} diff --git a/lib/services/cashfusion/protobuf/build-proto-fusion.sh b/lib/services/cashfusion/protobuf/build-proto-fusion.sh deleted file mode 100644 index 75be9ab37..000000000 --- a/lib/services/cashfusion/protobuf/build-proto-fusion.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -# This script will build the dart files based on fusion.proto. Navigate to the protobuf directory where the fusion.proto is and run this, then copy the needed files to lib. - -# The path to your .proto file. Adjust this if necessary. -PROTO_FILE="fusion.proto" - -# Run the protoc command. -protoc --dart_out=grpc:. $PROTO_FILE - -# After this, You should manually copy any needed dart files that were generated to the lib folder. diff --git a/lib/services/cashfusion/protobuf/fusion.pb.dart b/lib/services/cashfusion/protobuf/fusion.pb.dart deleted file mode 100644 index dac659f95..000000000 --- a/lib/services/cashfusion/protobuf/fusion.pb.dart +++ /dev/null @@ -1,2501 +0,0 @@ -/// -// Generated code. Do not modify. -// source: fusion.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name - -import 'dart:core' as $core; - -import 'package:fixnum/fixnum.dart' as $fixnum; -import 'package:protobuf/protobuf.dart' as $pb; - -class InputComponent extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'InputComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'prevTxid', $pb.PbFieldType.QY) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'prevIndex', $pb.PbFieldType.QU3) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pubkey', $pb.PbFieldType.QY) - ..a<$fixnum.Int64>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amount', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ; - - InputComponent._() : super(); - factory InputComponent({ - $core.List<$core.int>? prevTxid, - $core.int? prevIndex, - $core.List<$core.int>? pubkey, - $fixnum.Int64? amount, - }) { - final _result = create(); - if (prevTxid != null) { - _result.prevTxid = prevTxid; - } - if (prevIndex != null) { - _result.prevIndex = prevIndex; - } - if (pubkey != null) { - _result.pubkey = pubkey; - } - if (amount != null) { - _result.amount = amount; - } - return _result; - } - factory InputComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory InputComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - InputComponent clone() => InputComponent()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - InputComponent copyWith(void Function(InputComponent) updates) => super.copyWith((message) => updates(message as InputComponent)) as InputComponent; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static InputComponent create() => InputComponent._(); - InputComponent createEmptyInstance() => create(); - static $pb.PbList<InputComponent> createRepeated() => $pb.PbList<InputComponent>(); - @$core.pragma('dart2js:noInline') - static InputComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<InputComponent>(create); - static InputComponent? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get prevTxid => $_getN(0); - @$pb.TagNumber(1) - set prevTxid($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasPrevTxid() => $_has(0); - @$pb.TagNumber(1) - void clearPrevTxid() => clearField(1); - - @$pb.TagNumber(2) - $core.int get prevIndex => $_getIZ(1); - @$pb.TagNumber(2) - set prevIndex($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasPrevIndex() => $_has(1); - @$pb.TagNumber(2) - void clearPrevIndex() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get pubkey => $_getN(2); - @$pb.TagNumber(3) - set pubkey($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasPubkey() => $_has(2); - @$pb.TagNumber(3) - void clearPubkey() => clearField(3); - - @$pb.TagNumber(4) - $fixnum.Int64 get amount => $_getI64(3); - @$pb.TagNumber(4) - set amount($fixnum.Int64 v) { $_setInt64(3, v); } - @$pb.TagNumber(4) - $core.bool hasAmount() => $_has(3); - @$pb.TagNumber(4) - void clearAmount() => clearField(4); -} - -class OutputComponent extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'OutputComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scriptpubkey', $pb.PbFieldType.QY) - ..a<$fixnum.Int64>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amount', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ; - - OutputComponent._() : super(); - factory OutputComponent({ - $core.List<$core.int>? scriptpubkey, - $fixnum.Int64? amount, - }) { - final _result = create(); - if (scriptpubkey != null) { - _result.scriptpubkey = scriptpubkey; - } - if (amount != null) { - _result.amount = amount; - } - return _result; - } - factory OutputComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory OutputComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - OutputComponent clone() => OutputComponent()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - OutputComponent copyWith(void Function(OutputComponent) updates) => super.copyWith((message) => updates(message as OutputComponent)) as OutputComponent; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static OutputComponent create() => OutputComponent._(); - OutputComponent createEmptyInstance() => create(); - static $pb.PbList<OutputComponent> createRepeated() => $pb.PbList<OutputComponent>(); - @$core.pragma('dart2js:noInline') - static OutputComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OutputComponent>(create); - static OutputComponent? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get scriptpubkey => $_getN(0); - @$pb.TagNumber(1) - set scriptpubkey($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasScriptpubkey() => $_has(0); - @$pb.TagNumber(1) - void clearScriptpubkey() => clearField(1); - - @$pb.TagNumber(2) - $fixnum.Int64 get amount => $_getI64(1); - @$pb.TagNumber(2) - set amount($fixnum.Int64 v) { $_setInt64(1, v); } - @$pb.TagNumber(2) - $core.bool hasAmount() => $_has(1); - @$pb.TagNumber(2) - void clearAmount() => clearField(2); -} - -class BlankComponent extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlankComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..hasRequiredFields = false - ; - - BlankComponent._() : super(); - factory BlankComponent() => create(); - factory BlankComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory BlankComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - BlankComponent clone() => BlankComponent()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - BlankComponent copyWith(void Function(BlankComponent) updates) => super.copyWith((message) => updates(message as BlankComponent)) as BlankComponent; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static BlankComponent create() => BlankComponent._(); - BlankComponent createEmptyInstance() => create(); - static $pb.PbList<BlankComponent> createRepeated() => $pb.PbList<BlankComponent>(); - @$core.pragma('dart2js:noInline') - static BlankComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BlankComponent>(create); - static BlankComponent? _defaultInstance; -} - -enum Component_Component { - input, - output, - blank, - notSet -} - -class Component extends $pb.GeneratedMessage { - static const $core.Map<$core.int, Component_Component> _Component_ComponentByTag = { - 2 : Component_Component.input, - 3 : Component_Component.output, - 4 : Component_Component.blank, - 0 : Component_Component.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Component', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [2, 3, 4]) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'saltCommitment', $pb.PbFieldType.QY) - ..aOM<InputComponent>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'input', subBuilder: InputComponent.create) - ..aOM<OutputComponent>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'output', subBuilder: OutputComponent.create) - ..aOM<BlankComponent>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blank', subBuilder: BlankComponent.create) - ; - - Component._() : super(); - factory Component({ - $core.List<$core.int>? saltCommitment, - InputComponent? input, - OutputComponent? output, - BlankComponent? blank, - }) { - final _result = create(); - if (saltCommitment != null) { - _result.saltCommitment = saltCommitment; - } - if (input != null) { - _result.input = input; - } - if (output != null) { - _result.output = output; - } - if (blank != null) { - _result.blank = blank; - } - return _result; - } - factory Component.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Component.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Component clone() => Component()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Component copyWith(void Function(Component) updates) => super.copyWith((message) => updates(message as Component)) as Component; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Component create() => Component._(); - Component createEmptyInstance() => create(); - static $pb.PbList<Component> createRepeated() => $pb.PbList<Component>(); - @$core.pragma('dart2js:noInline') - static Component getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Component>(create); - static Component? _defaultInstance; - - Component_Component whichComponent() => _Component_ComponentByTag[$_whichOneof(0)]!; - void clearComponent() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - $core.List<$core.int> get saltCommitment => $_getN(0); - @$pb.TagNumber(1) - set saltCommitment($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasSaltCommitment() => $_has(0); - @$pb.TagNumber(1) - void clearSaltCommitment() => clearField(1); - - @$pb.TagNumber(2) - InputComponent get input => $_getN(1); - @$pb.TagNumber(2) - set input(InputComponent v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasInput() => $_has(1); - @$pb.TagNumber(2) - void clearInput() => clearField(2); - @$pb.TagNumber(2) - InputComponent ensureInput() => $_ensure(1); - - @$pb.TagNumber(3) - OutputComponent get output => $_getN(2); - @$pb.TagNumber(3) - set output(OutputComponent v) { setField(3, v); } - @$pb.TagNumber(3) - $core.bool hasOutput() => $_has(2); - @$pb.TagNumber(3) - void clearOutput() => clearField(3); - @$pb.TagNumber(3) - OutputComponent ensureOutput() => $_ensure(2); - - @$pb.TagNumber(4) - BlankComponent get blank => $_getN(3); - @$pb.TagNumber(4) - set blank(BlankComponent v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasBlank() => $_has(3); - @$pb.TagNumber(4) - void clearBlank() => clearField(4); - @$pb.TagNumber(4) - BlankComponent ensureBlank() => $_ensure(3); -} - -class InitialCommitment extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'InitialCommitment', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'saltedComponentHash', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'amountCommitment', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'communicationKey', $pb.PbFieldType.QY) - ; - - InitialCommitment._() : super(); - factory InitialCommitment({ - $core.List<$core.int>? saltedComponentHash, - $core.List<$core.int>? amountCommitment, - $core.List<$core.int>? communicationKey, - }) { - final _result = create(); - if (saltedComponentHash != null) { - _result.saltedComponentHash = saltedComponentHash; - } - if (amountCommitment != null) { - _result.amountCommitment = amountCommitment; - } - if (communicationKey != null) { - _result.communicationKey = communicationKey; - } - return _result; - } - factory InitialCommitment.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory InitialCommitment.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - InitialCommitment clone() => InitialCommitment()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - InitialCommitment copyWith(void Function(InitialCommitment) updates) => super.copyWith((message) => updates(message as InitialCommitment)) as InitialCommitment; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static InitialCommitment create() => InitialCommitment._(); - InitialCommitment createEmptyInstance() => create(); - static $pb.PbList<InitialCommitment> createRepeated() => $pb.PbList<InitialCommitment>(); - @$core.pragma('dart2js:noInline') - static InitialCommitment getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<InitialCommitment>(create); - static InitialCommitment? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get saltedComponentHash => $_getN(0); - @$pb.TagNumber(1) - set saltedComponentHash($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasSaltedComponentHash() => $_has(0); - @$pb.TagNumber(1) - void clearSaltedComponentHash() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get amountCommitment => $_getN(1); - @$pb.TagNumber(2) - set amountCommitment($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasAmountCommitment() => $_has(1); - @$pb.TagNumber(2) - void clearAmountCommitment() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get communicationKey => $_getN(2); - @$pb.TagNumber(3) - set communicationKey($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasCommunicationKey() => $_has(2); - @$pb.TagNumber(3) - void clearCommunicationKey() => clearField(3); -} - -class Proof extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Proof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'componentIdx', $pb.PbFieldType.QF3) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'salt', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pedersenNonce', $pb.PbFieldType.QY) - ; - - Proof._() : super(); - factory Proof({ - $core.int? componentIdx, - $core.List<$core.int>? salt, - $core.List<$core.int>? pedersenNonce, - }) { - final _result = create(); - if (componentIdx != null) { - _result.componentIdx = componentIdx; - } - if (salt != null) { - _result.salt = salt; - } - if (pedersenNonce != null) { - _result.pedersenNonce = pedersenNonce; - } - return _result; - } - factory Proof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Proof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Proof clone() => Proof()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Proof copyWith(void Function(Proof) updates) => super.copyWith((message) => updates(message as Proof)) as Proof; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Proof create() => Proof._(); - Proof createEmptyInstance() => create(); - static $pb.PbList<Proof> createRepeated() => $pb.PbList<Proof>(); - @$core.pragma('dart2js:noInline') - static Proof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Proof>(create); - static Proof? _defaultInstance; - - @$pb.TagNumber(1) - $core.int get componentIdx => $_getIZ(0); - @$pb.TagNumber(1) - set componentIdx($core.int v) { $_setUnsignedInt32(0, v); } - @$pb.TagNumber(1) - $core.bool hasComponentIdx() => $_has(0); - @$pb.TagNumber(1) - void clearComponentIdx() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get salt => $_getN(1); - @$pb.TagNumber(2) - set salt($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasSalt() => $_has(1); - @$pb.TagNumber(2) - void clearSalt() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get pedersenNonce => $_getN(2); - @$pb.TagNumber(3) - set pedersenNonce($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasPedersenNonce() => $_has(2); - @$pb.TagNumber(3) - void clearPedersenNonce() => clearField(3); -} - -class ClientHello extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ClientHello', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'version', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'genesisHash', $pb.PbFieldType.OY) - ; - - ClientHello._() : super(); - factory ClientHello({ - $core.List<$core.int>? version, - $core.List<$core.int>? genesisHash, - }) { - final _result = create(); - if (version != null) { - _result.version = version; - } - if (genesisHash != null) { - _result.genesisHash = genesisHash; - } - return _result; - } - factory ClientHello.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ClientHello.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - ClientHello clone() => ClientHello()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - ClientHello copyWith(void Function(ClientHello) updates) => super.copyWith((message) => updates(message as ClientHello)) as ClientHello; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static ClientHello create() => ClientHello._(); - ClientHello createEmptyInstance() => create(); - static $pb.PbList<ClientHello> createRepeated() => $pb.PbList<ClientHello>(); - @$core.pragma('dart2js:noInline') - static ClientHello getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ClientHello>(create); - static ClientHello? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get version => $_getN(0); - @$pb.TagNumber(1) - set version($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasVersion() => $_has(0); - @$pb.TagNumber(1) - void clearVersion() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get genesisHash => $_getN(1); - @$pb.TagNumber(2) - set genesisHash($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasGenesisHash() => $_has(1); - @$pb.TagNumber(2) - void clearGenesisHash() => clearField(2); -} - -class ServerHello extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ServerHello', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tiers', $pb.PbFieldType.PU6) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'numComponents', $pb.PbFieldType.QU3) - ..a<$fixnum.Int64>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'componentFeerate', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'minExcessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ..a<$fixnum.Int64>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'maxExcessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ..aOS(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'donationAddress') - ; - - ServerHello._() : super(); - factory ServerHello({ - $core.Iterable<$fixnum.Int64>? tiers, - $core.int? numComponents, - $fixnum.Int64? componentFeerate, - $fixnum.Int64? minExcessFee, - $fixnum.Int64? maxExcessFee, - $core.String? donationAddress, - }) { - final _result = create(); - if (tiers != null) { - _result.tiers.addAll(tiers); - } - if (numComponents != null) { - _result.numComponents = numComponents; - } - if (componentFeerate != null) { - _result.componentFeerate = componentFeerate; - } - if (minExcessFee != null) { - _result.minExcessFee = minExcessFee; - } - if (maxExcessFee != null) { - _result.maxExcessFee = maxExcessFee; - } - if (donationAddress != null) { - _result.donationAddress = donationAddress; - } - return _result; - } - factory ServerHello.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ServerHello.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - ServerHello clone() => ServerHello()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - ServerHello copyWith(void Function(ServerHello) updates) => super.copyWith((message) => updates(message as ServerHello)) as ServerHello; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static ServerHello create() => ServerHello._(); - ServerHello createEmptyInstance() => create(); - static $pb.PbList<ServerHello> createRepeated() => $pb.PbList<ServerHello>(); - @$core.pragma('dart2js:noInline') - static ServerHello getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ServerHello>(create); - static ServerHello? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$fixnum.Int64> get tiers => $_getList(0); - - @$pb.TagNumber(2) - $core.int get numComponents => $_getIZ(1); - @$pb.TagNumber(2) - set numComponents($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasNumComponents() => $_has(1); - @$pb.TagNumber(2) - void clearNumComponents() => clearField(2); - - @$pb.TagNumber(4) - $fixnum.Int64 get componentFeerate => $_getI64(2); - @$pb.TagNumber(4) - set componentFeerate($fixnum.Int64 v) { $_setInt64(2, v); } - @$pb.TagNumber(4) - $core.bool hasComponentFeerate() => $_has(2); - @$pb.TagNumber(4) - void clearComponentFeerate() => clearField(4); - - @$pb.TagNumber(5) - $fixnum.Int64 get minExcessFee => $_getI64(3); - @$pb.TagNumber(5) - set minExcessFee($fixnum.Int64 v) { $_setInt64(3, v); } - @$pb.TagNumber(5) - $core.bool hasMinExcessFee() => $_has(3); - @$pb.TagNumber(5) - void clearMinExcessFee() => clearField(5); - - @$pb.TagNumber(6) - $fixnum.Int64 get maxExcessFee => $_getI64(4); - @$pb.TagNumber(6) - set maxExcessFee($fixnum.Int64 v) { $_setInt64(4, v); } - @$pb.TagNumber(6) - $core.bool hasMaxExcessFee() => $_has(4); - @$pb.TagNumber(6) - void clearMaxExcessFee() => clearField(6); - - @$pb.TagNumber(15) - $core.String get donationAddress => $_getSZ(5); - @$pb.TagNumber(15) - set donationAddress($core.String v) { $_setString(5, v); } - @$pb.TagNumber(15) - $core.bool hasDonationAddress() => $_has(5); - @$pb.TagNumber(15) - void clearDonationAddress() => clearField(15); -} - -class JoinPools_PoolTag extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'JoinPools.PoolTag', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'id', $pb.PbFieldType.QY) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'limit', $pb.PbFieldType.QU3) - ..aOB(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'noIp') - ; - - JoinPools_PoolTag._() : super(); - factory JoinPools_PoolTag({ - $core.List<$core.int>? id, - $core.int? limit, - $core.bool? noIp, - }) { - final _result = create(); - if (id != null) { - _result.id = id; - } - if (limit != null) { - _result.limit = limit; - } - if (noIp != null) { - _result.noIp = noIp; - } - return _result; - } - factory JoinPools_PoolTag.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory JoinPools_PoolTag.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - JoinPools_PoolTag clone() => JoinPools_PoolTag()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - JoinPools_PoolTag copyWith(void Function(JoinPools_PoolTag) updates) => super.copyWith((message) => updates(message as JoinPools_PoolTag)) as JoinPools_PoolTag; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static JoinPools_PoolTag create() => JoinPools_PoolTag._(); - JoinPools_PoolTag createEmptyInstance() => create(); - static $pb.PbList<JoinPools_PoolTag> createRepeated() => $pb.PbList<JoinPools_PoolTag>(); - @$core.pragma('dart2js:noInline') - static JoinPools_PoolTag getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<JoinPools_PoolTag>(create); - static JoinPools_PoolTag? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get id => $_getN(0); - @$pb.TagNumber(1) - set id($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasId() => $_has(0); - @$pb.TagNumber(1) - void clearId() => clearField(1); - - @$pb.TagNumber(2) - $core.int get limit => $_getIZ(1); - @$pb.TagNumber(2) - set limit($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasLimit() => $_has(1); - @$pb.TagNumber(2) - void clearLimit() => clearField(2); - - @$pb.TagNumber(3) - $core.bool get noIp => $_getBF(2); - @$pb.TagNumber(3) - set noIp($core.bool v) { $_setBool(2, v); } - @$pb.TagNumber(3) - $core.bool hasNoIp() => $_has(2); - @$pb.TagNumber(3) - void clearNoIp() => clearField(3); -} - -class JoinPools extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'JoinPools', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tiers', $pb.PbFieldType.PU6) - ..pc<JoinPools_PoolTag>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tags', $pb.PbFieldType.PM, subBuilder: JoinPools_PoolTag.create) - ; - - JoinPools._() : super(); - factory JoinPools({ - $core.Iterable<$fixnum.Int64>? tiers, - $core.Iterable<JoinPools_PoolTag>? tags, - }) { - final _result = create(); - if (tiers != null) { - _result.tiers.addAll(tiers); - } - if (tags != null) { - _result.tags.addAll(tags); - } - return _result; - } - factory JoinPools.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory JoinPools.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - JoinPools clone() => JoinPools()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - JoinPools copyWith(void Function(JoinPools) updates) => super.copyWith((message) => updates(message as JoinPools)) as JoinPools; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static JoinPools create() => JoinPools._(); - JoinPools createEmptyInstance() => create(); - static $pb.PbList<JoinPools> createRepeated() => $pb.PbList<JoinPools>(); - @$core.pragma('dart2js:noInline') - static JoinPools getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<JoinPools>(create); - static JoinPools? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$fixnum.Int64> get tiers => $_getList(0); - - @$pb.TagNumber(2) - $core.List<JoinPools_PoolTag> get tags => $_getList(1); -} - -class TierStatusUpdate_TierStatus extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TierStatusUpdate.TierStatus', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'players', $pb.PbFieldType.OU3) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'minPlayers', $pb.PbFieldType.OU3) - ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'maxPlayers', $pb.PbFieldType.OU3) - ..a<$core.int>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'timeRemaining', $pb.PbFieldType.OU3) - ..hasRequiredFields = false - ; - - TierStatusUpdate_TierStatus._() : super(); - factory TierStatusUpdate_TierStatus({ - $core.int? players, - $core.int? minPlayers, - $core.int? maxPlayers, - $core.int? timeRemaining, - }) { - final _result = create(); - if (players != null) { - _result.players = players; - } - if (minPlayers != null) { - _result.minPlayers = minPlayers; - } - if (maxPlayers != null) { - _result.maxPlayers = maxPlayers; - } - if (timeRemaining != null) { - _result.timeRemaining = timeRemaining; - } - return _result; - } - factory TierStatusUpdate_TierStatus.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory TierStatusUpdate_TierStatus.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - TierStatusUpdate_TierStatus clone() => TierStatusUpdate_TierStatus()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - TierStatusUpdate_TierStatus copyWith(void Function(TierStatusUpdate_TierStatus) updates) => super.copyWith((message) => updates(message as TierStatusUpdate_TierStatus)) as TierStatusUpdate_TierStatus; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static TierStatusUpdate_TierStatus create() => TierStatusUpdate_TierStatus._(); - TierStatusUpdate_TierStatus createEmptyInstance() => create(); - static $pb.PbList<TierStatusUpdate_TierStatus> createRepeated() => $pb.PbList<TierStatusUpdate_TierStatus>(); - @$core.pragma('dart2js:noInline') - static TierStatusUpdate_TierStatus getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TierStatusUpdate_TierStatus>(create); - static TierStatusUpdate_TierStatus? _defaultInstance; - - @$pb.TagNumber(1) - $core.int get players => $_getIZ(0); - @$pb.TagNumber(1) - set players($core.int v) { $_setUnsignedInt32(0, v); } - @$pb.TagNumber(1) - $core.bool hasPlayers() => $_has(0); - @$pb.TagNumber(1) - void clearPlayers() => clearField(1); - - @$pb.TagNumber(2) - $core.int get minPlayers => $_getIZ(1); - @$pb.TagNumber(2) - set minPlayers($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasMinPlayers() => $_has(1); - @$pb.TagNumber(2) - void clearMinPlayers() => clearField(2); - - @$pb.TagNumber(3) - $core.int get maxPlayers => $_getIZ(2); - @$pb.TagNumber(3) - set maxPlayers($core.int v) { $_setUnsignedInt32(2, v); } - @$pb.TagNumber(3) - $core.bool hasMaxPlayers() => $_has(2); - @$pb.TagNumber(3) - void clearMaxPlayers() => clearField(3); - - @$pb.TagNumber(4) - $core.int get timeRemaining => $_getIZ(3); - @$pb.TagNumber(4) - set timeRemaining($core.int v) { $_setUnsignedInt32(3, v); } - @$pb.TagNumber(4) - $core.bool hasTimeRemaining() => $_has(3); - @$pb.TagNumber(4) - void clearTimeRemaining() => clearField(4); -} - -class TierStatusUpdate extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TierStatusUpdate', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..m<$fixnum.Int64, TierStatusUpdate_TierStatus>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'statuses', entryClassName: 'TierStatusUpdate.StatusesEntry', keyFieldType: $pb.PbFieldType.OU6, valueFieldType: $pb.PbFieldType.OM, valueCreator: TierStatusUpdate_TierStatus.create, packageName: const $pb.PackageName('fusion')) - ..hasRequiredFields = false - ; - - TierStatusUpdate._() : super(); - factory TierStatusUpdate({ - $core.Map<$fixnum.Int64, TierStatusUpdate_TierStatus>? statuses, - }) { - final _result = create(); - if (statuses != null) { - _result.statuses.addAll(statuses); - } - return _result; - } - factory TierStatusUpdate.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory TierStatusUpdate.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - TierStatusUpdate clone() => TierStatusUpdate()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - TierStatusUpdate copyWith(void Function(TierStatusUpdate) updates) => super.copyWith((message) => updates(message as TierStatusUpdate)) as TierStatusUpdate; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static TierStatusUpdate create() => TierStatusUpdate._(); - TierStatusUpdate createEmptyInstance() => create(); - static $pb.PbList<TierStatusUpdate> createRepeated() => $pb.PbList<TierStatusUpdate>(); - @$core.pragma('dart2js:noInline') - static TierStatusUpdate getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TierStatusUpdate>(create); - static TierStatusUpdate? _defaultInstance; - - @$pb.TagNumber(1) - $core.Map<$fixnum.Int64, TierStatusUpdate_TierStatus> get statuses => $_getMap(0); -} - -class FusionBegin extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FusionBegin', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$fixnum.Int64>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tier', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertDomain', $pb.PbFieldType.QY) - ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertPort', $pb.PbFieldType.QU3) - ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'covertSsl') - ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverTime', $pb.PbFieldType.QF6, defaultOrMaker: $fixnum.Int64.ZERO) - ; - - FusionBegin._() : super(); - factory FusionBegin({ - $fixnum.Int64? tier, - $core.List<$core.int>? covertDomain, - $core.int? covertPort, - $core.bool? covertSsl, - $fixnum.Int64? serverTime, - }) { - final _result = create(); - if (tier != null) { - _result.tier = tier; - } - if (covertDomain != null) { - _result.covertDomain = covertDomain; - } - if (covertPort != null) { - _result.covertPort = covertPort; - } - if (covertSsl != null) { - _result.covertSsl = covertSsl; - } - if (serverTime != null) { - _result.serverTime = serverTime; - } - return _result; - } - factory FusionBegin.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory FusionBegin.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - FusionBegin clone() => FusionBegin()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - FusionBegin copyWith(void Function(FusionBegin) updates) => super.copyWith((message) => updates(message as FusionBegin)) as FusionBegin; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static FusionBegin create() => FusionBegin._(); - FusionBegin createEmptyInstance() => create(); - static $pb.PbList<FusionBegin> createRepeated() => $pb.PbList<FusionBegin>(); - @$core.pragma('dart2js:noInline') - static FusionBegin getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FusionBegin>(create); - static FusionBegin? _defaultInstance; - - @$pb.TagNumber(1) - $fixnum.Int64 get tier => $_getI64(0); - @$pb.TagNumber(1) - set tier($fixnum.Int64 v) { $_setInt64(0, v); } - @$pb.TagNumber(1) - $core.bool hasTier() => $_has(0); - @$pb.TagNumber(1) - void clearTier() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get covertDomain => $_getN(1); - @$pb.TagNumber(2) - set covertDomain($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasCovertDomain() => $_has(1); - @$pb.TagNumber(2) - void clearCovertDomain() => clearField(2); - - @$pb.TagNumber(3) - $core.int get covertPort => $_getIZ(2); - @$pb.TagNumber(3) - set covertPort($core.int v) { $_setUnsignedInt32(2, v); } - @$pb.TagNumber(3) - $core.bool hasCovertPort() => $_has(2); - @$pb.TagNumber(3) - void clearCovertPort() => clearField(3); - - @$pb.TagNumber(4) - $core.bool get covertSsl => $_getBF(3); - @$pb.TagNumber(4) - set covertSsl($core.bool v) { $_setBool(3, v); } - @$pb.TagNumber(4) - $core.bool hasCovertSsl() => $_has(3); - @$pb.TagNumber(4) - void clearCovertSsl() => clearField(4); - - @$pb.TagNumber(5) - $fixnum.Int64 get serverTime => $_getI64(4); - @$pb.TagNumber(5) - set serverTime($fixnum.Int64 v) { $_setInt64(4, v); } - @$pb.TagNumber(5) - $core.bool hasServerTime() => $_has(4); - @$pb.TagNumber(5) - void clearServerTime() => clearField(5); -} - -class StartRound extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'StartRound', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.QY) - ..p<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindNoncePoints', $pb.PbFieldType.PY) - ..a<$fixnum.Int64>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverTime', $pb.PbFieldType.QF6, defaultOrMaker: $fixnum.Int64.ZERO) - ; - - StartRound._() : super(); - factory StartRound({ - $core.List<$core.int>? roundPubkey, - $core.Iterable<$core.List<$core.int>>? blindNoncePoints, - $fixnum.Int64? serverTime, - }) { - final _result = create(); - if (roundPubkey != null) { - _result.roundPubkey = roundPubkey; - } - if (blindNoncePoints != null) { - _result.blindNoncePoints.addAll(blindNoncePoints); - } - if (serverTime != null) { - _result.serverTime = serverTime; - } - return _result; - } - factory StartRound.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory StartRound.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - StartRound clone() => StartRound()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - StartRound copyWith(void Function(StartRound) updates) => super.copyWith((message) => updates(message as StartRound)) as StartRound; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static StartRound create() => StartRound._(); - StartRound createEmptyInstance() => create(); - static $pb.PbList<StartRound> createRepeated() => $pb.PbList<StartRound>(); - @$core.pragma('dart2js:noInline') - static StartRound getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<StartRound>(create); - static StartRound? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get roundPubkey => $_getN(0); - @$pb.TagNumber(1) - set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasRoundPubkey() => $_has(0); - @$pb.TagNumber(1) - void clearRoundPubkey() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.List<$core.int>> get blindNoncePoints => $_getList(1); - - @$pb.TagNumber(5) - $fixnum.Int64 get serverTime => $_getI64(2); - @$pb.TagNumber(5) - set serverTime($fixnum.Int64 v) { $_setInt64(2, v); } - @$pb.TagNumber(5) - $core.bool hasServerTime() => $_has(2); - @$pb.TagNumber(5) - void clearServerTime() => clearField(5); -} - -class PlayerCommit extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'PlayerCommit', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'initialCommitments', $pb.PbFieldType.PY) - ..a<$fixnum.Int64>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'excessFee', $pb.PbFieldType.QU6, defaultOrMaker: $fixnum.Int64.ZERO) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'pedersenTotalNonce', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'randomNumberCommitment', $pb.PbFieldType.QY) - ..p<$core.List<$core.int>>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindSigRequests', $pb.PbFieldType.PY) - ; - - PlayerCommit._() : super(); - factory PlayerCommit({ - $core.Iterable<$core.List<$core.int>>? initialCommitments, - $fixnum.Int64? excessFee, - $core.List<$core.int>? pedersenTotalNonce, - $core.List<$core.int>? randomNumberCommitment, - $core.Iterable<$core.List<$core.int>>? blindSigRequests, - }) { - final _result = create(); - if (initialCommitments != null) { - _result.initialCommitments.addAll(initialCommitments); - } - if (excessFee != null) { - _result.excessFee = excessFee; - } - if (pedersenTotalNonce != null) { - _result.pedersenTotalNonce = pedersenTotalNonce; - } - if (randomNumberCommitment != null) { - _result.randomNumberCommitment = randomNumberCommitment; - } - if (blindSigRequests != null) { - _result.blindSigRequests.addAll(blindSigRequests); - } - return _result; - } - factory PlayerCommit.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory PlayerCommit.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - PlayerCommit clone() => PlayerCommit()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - PlayerCommit copyWith(void Function(PlayerCommit) updates) => super.copyWith((message) => updates(message as PlayerCommit)) as PlayerCommit; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static PlayerCommit create() => PlayerCommit._(); - PlayerCommit createEmptyInstance() => create(); - static $pb.PbList<PlayerCommit> createRepeated() => $pb.PbList<PlayerCommit>(); - @$core.pragma('dart2js:noInline') - static PlayerCommit getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<PlayerCommit>(create); - static PlayerCommit? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.List<$core.int>> get initialCommitments => $_getList(0); - - @$pb.TagNumber(2) - $fixnum.Int64 get excessFee => $_getI64(1); - @$pb.TagNumber(2) - set excessFee($fixnum.Int64 v) { $_setInt64(1, v); } - @$pb.TagNumber(2) - $core.bool hasExcessFee() => $_has(1); - @$pb.TagNumber(2) - void clearExcessFee() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get pedersenTotalNonce => $_getN(2); - @$pb.TagNumber(3) - set pedersenTotalNonce($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasPedersenTotalNonce() => $_has(2); - @$pb.TagNumber(3) - void clearPedersenTotalNonce() => clearField(3); - - @$pb.TagNumber(4) - $core.List<$core.int> get randomNumberCommitment => $_getN(3); - @$pb.TagNumber(4) - set randomNumberCommitment($core.List<$core.int> v) { $_setBytes(3, v); } - @$pb.TagNumber(4) - $core.bool hasRandomNumberCommitment() => $_has(3); - @$pb.TagNumber(4) - void clearRandomNumberCommitment() => clearField(4); - - @$pb.TagNumber(5) - $core.List<$core.List<$core.int>> get blindSigRequests => $_getList(4); -} - -class BlindSigResponses extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'BlindSigResponses', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scalars', $pb.PbFieldType.PY) - ..hasRequiredFields = false - ; - - BlindSigResponses._() : super(); - factory BlindSigResponses({ - $core.Iterable<$core.List<$core.int>>? scalars, - }) { - final _result = create(); - if (scalars != null) { - _result.scalars.addAll(scalars); - } - return _result; - } - factory BlindSigResponses.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory BlindSigResponses.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - BlindSigResponses clone() => BlindSigResponses()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - BlindSigResponses copyWith(void Function(BlindSigResponses) updates) => super.copyWith((message) => updates(message as BlindSigResponses)) as BlindSigResponses; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static BlindSigResponses create() => BlindSigResponses._(); - BlindSigResponses createEmptyInstance() => create(); - static $pb.PbList<BlindSigResponses> createRepeated() => $pb.PbList<BlindSigResponses>(); - @$core.pragma('dart2js:noInline') - static BlindSigResponses getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<BlindSigResponses>(create); - static BlindSigResponses? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.List<$core.int>> get scalars => $_getList(0); -} - -class AllCommitments extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AllCommitments', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'initialCommitments', $pb.PbFieldType.PY) - ..hasRequiredFields = false - ; - - AllCommitments._() : super(); - factory AllCommitments({ - $core.Iterable<$core.List<$core.int>>? initialCommitments, - }) { - final _result = create(); - if (initialCommitments != null) { - _result.initialCommitments.addAll(initialCommitments); - } - return _result; - } - factory AllCommitments.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory AllCommitments.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - AllCommitments clone() => AllCommitments()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - AllCommitments copyWith(void Function(AllCommitments) updates) => super.copyWith((message) => updates(message as AllCommitments)) as AllCommitments; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static AllCommitments create() => AllCommitments._(); - AllCommitments createEmptyInstance() => create(); - static $pb.PbList<AllCommitments> createRepeated() => $pb.PbList<AllCommitments>(); - @$core.pragma('dart2js:noInline') - static AllCommitments getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AllCommitments>(create); - static AllCommitments? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.List<$core.int>> get initialCommitments => $_getList(0); -} - -class CovertComponent extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertComponent', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.OY) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signature', $pb.PbFieldType.QY) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'component', $pb.PbFieldType.QY) - ; - - CovertComponent._() : super(); - factory CovertComponent({ - $core.List<$core.int>? roundPubkey, - $core.List<$core.int>? signature, - $core.List<$core.int>? component, - }) { - final _result = create(); - if (roundPubkey != null) { - _result.roundPubkey = roundPubkey; - } - if (signature != null) { - _result.signature = signature; - } - if (component != null) { - _result.component = component; - } - return _result; - } - factory CovertComponent.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CovertComponent.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CovertComponent clone() => CovertComponent()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CovertComponent copyWith(void Function(CovertComponent) updates) => super.copyWith((message) => updates(message as CovertComponent)) as CovertComponent; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CovertComponent create() => CovertComponent._(); - CovertComponent createEmptyInstance() => create(); - static $pb.PbList<CovertComponent> createRepeated() => $pb.PbList<CovertComponent>(); - @$core.pragma('dart2js:noInline') - static CovertComponent getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertComponent>(create); - static CovertComponent? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get roundPubkey => $_getN(0); - @$pb.TagNumber(1) - set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasRoundPubkey() => $_has(0); - @$pb.TagNumber(1) - void clearRoundPubkey() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get signature => $_getN(1); - @$pb.TagNumber(2) - set signature($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasSignature() => $_has(1); - @$pb.TagNumber(2) - void clearSignature() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get component => $_getN(2); - @$pb.TagNumber(3) - set component($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasComponent() => $_has(2); - @$pb.TagNumber(3) - void clearComponent() => clearField(3); -} - -class ShareCovertComponents extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ShareCovertComponents', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$core.List<$core.int>>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'components', $pb.PbFieldType.PY) - ..aOB(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'skipSignatures') - ..a<$core.List<$core.int>>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sessionHash', $pb.PbFieldType.OY) - ..hasRequiredFields = false - ; - - ShareCovertComponents._() : super(); - factory ShareCovertComponents({ - $core.Iterable<$core.List<$core.int>>? components, - $core.bool? skipSignatures, - $core.List<$core.int>? sessionHash, - }) { - final _result = create(); - if (components != null) { - _result.components.addAll(components); - } - if (skipSignatures != null) { - _result.skipSignatures = skipSignatures; - } - if (sessionHash != null) { - _result.sessionHash = sessionHash; - } - return _result; - } - factory ShareCovertComponents.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ShareCovertComponents.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - ShareCovertComponents clone() => ShareCovertComponents()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - ShareCovertComponents copyWith(void Function(ShareCovertComponents) updates) => super.copyWith((message) => updates(message as ShareCovertComponents)) as ShareCovertComponents; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static ShareCovertComponents create() => ShareCovertComponents._(); - ShareCovertComponents createEmptyInstance() => create(); - static $pb.PbList<ShareCovertComponents> createRepeated() => $pb.PbList<ShareCovertComponents>(); - @$core.pragma('dart2js:noInline') - static ShareCovertComponents getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ShareCovertComponents>(create); - static ShareCovertComponents? _defaultInstance; - - @$pb.TagNumber(4) - $core.List<$core.List<$core.int>> get components => $_getList(0); - - @$pb.TagNumber(5) - $core.bool get skipSignatures => $_getBF(1); - @$pb.TagNumber(5) - set skipSignatures($core.bool v) { $_setBool(1, v); } - @$pb.TagNumber(5) - $core.bool hasSkipSignatures() => $_has(1); - @$pb.TagNumber(5) - void clearSkipSignatures() => clearField(5); - - @$pb.TagNumber(6) - $core.List<$core.int> get sessionHash => $_getN(2); - @$pb.TagNumber(6) - set sessionHash($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(6) - $core.bool hasSessionHash() => $_has(2); - @$pb.TagNumber(6) - void clearSessionHash() => clearField(6); -} - -class CovertTransactionSignature extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertTransactionSignature', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'roundPubkey', $pb.PbFieldType.OY) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'whichInput', $pb.PbFieldType.QU3) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'txsignature', $pb.PbFieldType.QY) - ; - - CovertTransactionSignature._() : super(); - factory CovertTransactionSignature({ - $core.List<$core.int>? roundPubkey, - $core.int? whichInput, - $core.List<$core.int>? txsignature, - }) { - final _result = create(); - if (roundPubkey != null) { - _result.roundPubkey = roundPubkey; - } - if (whichInput != null) { - _result.whichInput = whichInput; - } - if (txsignature != null) { - _result.txsignature = txsignature; - } - return _result; - } - factory CovertTransactionSignature.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CovertTransactionSignature.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CovertTransactionSignature clone() => CovertTransactionSignature()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CovertTransactionSignature copyWith(void Function(CovertTransactionSignature) updates) => super.copyWith((message) => updates(message as CovertTransactionSignature)) as CovertTransactionSignature; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CovertTransactionSignature create() => CovertTransactionSignature._(); - CovertTransactionSignature createEmptyInstance() => create(); - static $pb.PbList<CovertTransactionSignature> createRepeated() => $pb.PbList<CovertTransactionSignature>(); - @$core.pragma('dart2js:noInline') - static CovertTransactionSignature getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertTransactionSignature>(create); - static CovertTransactionSignature? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get roundPubkey => $_getN(0); - @$pb.TagNumber(1) - set roundPubkey($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasRoundPubkey() => $_has(0); - @$pb.TagNumber(1) - void clearRoundPubkey() => clearField(1); - - @$pb.TagNumber(2) - $core.int get whichInput => $_getIZ(1); - @$pb.TagNumber(2) - set whichInput($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasWhichInput() => $_has(1); - @$pb.TagNumber(2) - void clearWhichInput() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get txsignature => $_getN(2); - @$pb.TagNumber(3) - set txsignature($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasTxsignature() => $_has(2); - @$pb.TagNumber(3) - void clearTxsignature() => clearField(3); -} - -class FusionResult extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'FusionResult', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.bool>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ok', $pb.PbFieldType.QB) - ..p<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'txsignatures', $pb.PbFieldType.PY) - ..p<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'badComponents', $pb.PbFieldType.PU3) - ; - - FusionResult._() : super(); - factory FusionResult({ - $core.bool? ok, - $core.Iterable<$core.List<$core.int>>? txsignatures, - $core.Iterable<$core.int>? badComponents, - }) { - final _result = create(); - if (ok != null) { - _result.ok = ok; - } - if (txsignatures != null) { - _result.txsignatures.addAll(txsignatures); - } - if (badComponents != null) { - _result.badComponents.addAll(badComponents); - } - return _result; - } - factory FusionResult.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory FusionResult.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - FusionResult clone() => FusionResult()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - FusionResult copyWith(void Function(FusionResult) updates) => super.copyWith((message) => updates(message as FusionResult)) as FusionResult; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static FusionResult create() => FusionResult._(); - FusionResult createEmptyInstance() => create(); - static $pb.PbList<FusionResult> createRepeated() => $pb.PbList<FusionResult>(); - @$core.pragma('dart2js:noInline') - static FusionResult getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<FusionResult>(create); - static FusionResult? _defaultInstance; - - @$pb.TagNumber(1) - $core.bool get ok => $_getBF(0); - @$pb.TagNumber(1) - set ok($core.bool v) { $_setBool(0, v); } - @$pb.TagNumber(1) - $core.bool hasOk() => $_has(0); - @$pb.TagNumber(1) - void clearOk() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.List<$core.int>> get txsignatures => $_getList(1); - - @$pb.TagNumber(3) - $core.List<$core.int> get badComponents => $_getList(2); -} - -class MyProofsList extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'MyProofsList', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..p<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'encryptedProofs', $pb.PbFieldType.PY) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'randomNumber', $pb.PbFieldType.QY) - ; - - MyProofsList._() : super(); - factory MyProofsList({ - $core.Iterable<$core.List<$core.int>>? encryptedProofs, - $core.List<$core.int>? randomNumber, - }) { - final _result = create(); - if (encryptedProofs != null) { - _result.encryptedProofs.addAll(encryptedProofs); - } - if (randomNumber != null) { - _result.randomNumber = randomNumber; - } - return _result; - } - factory MyProofsList.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory MyProofsList.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - MyProofsList clone() => MyProofsList()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - MyProofsList copyWith(void Function(MyProofsList) updates) => super.copyWith((message) => updates(message as MyProofsList)) as MyProofsList; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static MyProofsList create() => MyProofsList._(); - MyProofsList createEmptyInstance() => create(); - static $pb.PbList<MyProofsList> createRepeated() => $pb.PbList<MyProofsList>(); - @$core.pragma('dart2js:noInline') - static MyProofsList getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<MyProofsList>(create); - static MyProofsList? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.List<$core.int>> get encryptedProofs => $_getList(0); - - @$pb.TagNumber(2) - $core.List<$core.int> get randomNumber => $_getN(1); - @$pb.TagNumber(2) - set randomNumber($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasRandomNumber() => $_has(1); - @$pb.TagNumber(2) - void clearRandomNumber() => clearField(2); -} - -class TheirProofsList_RelayedProof extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TheirProofsList.RelayedProof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'encryptedProof', $pb.PbFieldType.QY) - ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'srcCommitmentIdx', $pb.PbFieldType.QU3) - ..a<$core.int>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'dstKeyIdx', $pb.PbFieldType.QU3) - ; - - TheirProofsList_RelayedProof._() : super(); - factory TheirProofsList_RelayedProof({ - $core.List<$core.int>? encryptedProof, - $core.int? srcCommitmentIdx, - $core.int? dstKeyIdx, - }) { - final _result = create(); - if (encryptedProof != null) { - _result.encryptedProof = encryptedProof; - } - if (srcCommitmentIdx != null) { - _result.srcCommitmentIdx = srcCommitmentIdx; - } - if (dstKeyIdx != null) { - _result.dstKeyIdx = dstKeyIdx; - } - return _result; - } - factory TheirProofsList_RelayedProof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory TheirProofsList_RelayedProof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - TheirProofsList_RelayedProof clone() => TheirProofsList_RelayedProof()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - TheirProofsList_RelayedProof copyWith(void Function(TheirProofsList_RelayedProof) updates) => super.copyWith((message) => updates(message as TheirProofsList_RelayedProof)) as TheirProofsList_RelayedProof; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static TheirProofsList_RelayedProof create() => TheirProofsList_RelayedProof._(); - TheirProofsList_RelayedProof createEmptyInstance() => create(); - static $pb.PbList<TheirProofsList_RelayedProof> createRepeated() => $pb.PbList<TheirProofsList_RelayedProof>(); - @$core.pragma('dart2js:noInline') - static TheirProofsList_RelayedProof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TheirProofsList_RelayedProof>(create); - static TheirProofsList_RelayedProof? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<$core.int> get encryptedProof => $_getN(0); - @$pb.TagNumber(1) - set encryptedProof($core.List<$core.int> v) { $_setBytes(0, v); } - @$pb.TagNumber(1) - $core.bool hasEncryptedProof() => $_has(0); - @$pb.TagNumber(1) - void clearEncryptedProof() => clearField(1); - - @$pb.TagNumber(2) - $core.int get srcCommitmentIdx => $_getIZ(1); - @$pb.TagNumber(2) - set srcCommitmentIdx($core.int v) { $_setUnsignedInt32(1, v); } - @$pb.TagNumber(2) - $core.bool hasSrcCommitmentIdx() => $_has(1); - @$pb.TagNumber(2) - void clearSrcCommitmentIdx() => clearField(2); - - @$pb.TagNumber(3) - $core.int get dstKeyIdx => $_getIZ(2); - @$pb.TagNumber(3) - set dstKeyIdx($core.int v) { $_setUnsignedInt32(2, v); } - @$pb.TagNumber(3) - $core.bool hasDstKeyIdx() => $_has(2); - @$pb.TagNumber(3) - void clearDstKeyIdx() => clearField(3); -} - -class TheirProofsList extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TheirProofsList', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..pc<TheirProofsList_RelayedProof>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'proofs', $pb.PbFieldType.PM, subBuilder: TheirProofsList_RelayedProof.create) - ; - - TheirProofsList._() : super(); - factory TheirProofsList({ - $core.Iterable<TheirProofsList_RelayedProof>? proofs, - }) { - final _result = create(); - if (proofs != null) { - _result.proofs.addAll(proofs); - } - return _result; - } - factory TheirProofsList.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory TheirProofsList.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - TheirProofsList clone() => TheirProofsList()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - TheirProofsList copyWith(void Function(TheirProofsList) updates) => super.copyWith((message) => updates(message as TheirProofsList)) as TheirProofsList; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static TheirProofsList create() => TheirProofsList._(); - TheirProofsList createEmptyInstance() => create(); - static $pb.PbList<TheirProofsList> createRepeated() => $pb.PbList<TheirProofsList>(); - @$core.pragma('dart2js:noInline') - static TheirProofsList getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<TheirProofsList>(create); - static TheirProofsList? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<TheirProofsList_RelayedProof> get proofs => $_getList(0); -} - -enum Blames_BlameProof_Decrypter { - sessionKey, - privkey, - notSet -} - -class Blames_BlameProof extends $pb.GeneratedMessage { - static const $core.Map<$core.int, Blames_BlameProof_Decrypter> _Blames_BlameProof_DecrypterByTag = { - 2 : Blames_BlameProof_Decrypter.sessionKey, - 3 : Blames_BlameProof_Decrypter.privkey, - 0 : Blames_BlameProof_Decrypter.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Blames.BlameProof', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [2, 3]) - ..a<$core.int>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'whichProof', $pb.PbFieldType.QU3) - ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sessionKey', $pb.PbFieldType.OY) - ..a<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'privkey', $pb.PbFieldType.OY) - ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'needLookupBlockchain') - ..aOS(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blameReason') - ; - - Blames_BlameProof._() : super(); - factory Blames_BlameProof({ - $core.int? whichProof, - $core.List<$core.int>? sessionKey, - $core.List<$core.int>? privkey, - $core.bool? needLookupBlockchain, - $core.String? blameReason, - }) { - final _result = create(); - if (whichProof != null) { - _result.whichProof = whichProof; - } - if (sessionKey != null) { - _result.sessionKey = sessionKey; - } - if (privkey != null) { - _result.privkey = privkey; - } - if (needLookupBlockchain != null) { - _result.needLookupBlockchain = needLookupBlockchain; - } - if (blameReason != null) { - _result.blameReason = blameReason; - } - return _result; - } - factory Blames_BlameProof.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Blames_BlameProof.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Blames_BlameProof clone() => Blames_BlameProof()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Blames_BlameProof copyWith(void Function(Blames_BlameProof) updates) => super.copyWith((message) => updates(message as Blames_BlameProof)) as Blames_BlameProof; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Blames_BlameProof create() => Blames_BlameProof._(); - Blames_BlameProof createEmptyInstance() => create(); - static $pb.PbList<Blames_BlameProof> createRepeated() => $pb.PbList<Blames_BlameProof>(); - @$core.pragma('dart2js:noInline') - static Blames_BlameProof getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Blames_BlameProof>(create); - static Blames_BlameProof? _defaultInstance; - - Blames_BlameProof_Decrypter whichDecrypter() => _Blames_BlameProof_DecrypterByTag[$_whichOneof(0)]!; - void clearDecrypter() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - $core.int get whichProof => $_getIZ(0); - @$pb.TagNumber(1) - set whichProof($core.int v) { $_setUnsignedInt32(0, v); } - @$pb.TagNumber(1) - $core.bool hasWhichProof() => $_has(0); - @$pb.TagNumber(1) - void clearWhichProof() => clearField(1); - - @$pb.TagNumber(2) - $core.List<$core.int> get sessionKey => $_getN(1); - @$pb.TagNumber(2) - set sessionKey($core.List<$core.int> v) { $_setBytes(1, v); } - @$pb.TagNumber(2) - $core.bool hasSessionKey() => $_has(1); - @$pb.TagNumber(2) - void clearSessionKey() => clearField(2); - - @$pb.TagNumber(3) - $core.List<$core.int> get privkey => $_getN(2); - @$pb.TagNumber(3) - set privkey($core.List<$core.int> v) { $_setBytes(2, v); } - @$pb.TagNumber(3) - $core.bool hasPrivkey() => $_has(2); - @$pb.TagNumber(3) - void clearPrivkey() => clearField(3); - - @$pb.TagNumber(4) - $core.bool get needLookupBlockchain => $_getBF(3); - @$pb.TagNumber(4) - set needLookupBlockchain($core.bool v) { $_setBool(3, v); } - @$pb.TagNumber(4) - $core.bool hasNeedLookupBlockchain() => $_has(3); - @$pb.TagNumber(4) - void clearNeedLookupBlockchain() => clearField(4); - - @$pb.TagNumber(5) - $core.String get blameReason => $_getSZ(4); - @$pb.TagNumber(5) - set blameReason($core.String v) { $_setString(4, v); } - @$pb.TagNumber(5) - $core.bool hasBlameReason() => $_has(4); - @$pb.TagNumber(5) - void clearBlameReason() => clearField(5); -} - -class Blames extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Blames', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..pc<Blames_BlameProof>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blames', $pb.PbFieldType.PM, subBuilder: Blames_BlameProof.create) - ; - - Blames._() : super(); - factory Blames({ - $core.Iterable<Blames_BlameProof>? blames, - }) { - final _result = create(); - if (blames != null) { - _result.blames.addAll(blames); - } - return _result; - } - factory Blames.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Blames.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Blames clone() => Blames()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Blames copyWith(void Function(Blames) updates) => super.copyWith((message) => updates(message as Blames)) as Blames; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Blames create() => Blames._(); - Blames createEmptyInstance() => create(); - static $pb.PbList<Blames> createRepeated() => $pb.PbList<Blames>(); - @$core.pragma('dart2js:noInline') - static Blames getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Blames>(create); - static Blames? _defaultInstance; - - @$pb.TagNumber(1) - $core.List<Blames_BlameProof> get blames => $_getList(0); -} - -class RestartRound extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'RestartRound', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..hasRequiredFields = false - ; - - RestartRound._() : super(); - factory RestartRound() => create(); - factory RestartRound.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory RestartRound.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - RestartRound clone() => RestartRound()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - RestartRound copyWith(void Function(RestartRound) updates) => super.copyWith((message) => updates(message as RestartRound)) as RestartRound; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static RestartRound create() => RestartRound._(); - RestartRound createEmptyInstance() => create(); - static $pb.PbList<RestartRound> createRepeated() => $pb.PbList<RestartRound>(); - @$core.pragma('dart2js:noInline') - static RestartRound getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<RestartRound>(create); - static RestartRound? _defaultInstance; -} - -class Error extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Error', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'message') - ..hasRequiredFields = false - ; - - Error._() : super(); - factory Error({ - $core.String? message, - }) { - final _result = create(); - if (message != null) { - _result.message = message; - } - return _result; - } - factory Error.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Error.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Error clone() => Error()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Error copyWith(void Function(Error) updates) => super.copyWith((message) => updates(message as Error)) as Error; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Error create() => Error._(); - Error createEmptyInstance() => create(); - static $pb.PbList<Error> createRepeated() => $pb.PbList<Error>(); - @$core.pragma('dart2js:noInline') - static Error getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Error>(create); - static Error? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get message => $_getSZ(0); - @$pb.TagNumber(1) - set message($core.String v) { $_setString(0, v); } - @$pb.TagNumber(1) - $core.bool hasMessage() => $_has(0); - @$pb.TagNumber(1) - void clearMessage() => clearField(1); -} - -class Ping extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'Ping', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..hasRequiredFields = false - ; - - Ping._() : super(); - factory Ping() => create(); - factory Ping.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory Ping.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Ping clone() => Ping()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Ping copyWith(void Function(Ping) updates) => super.copyWith((message) => updates(message as Ping)) as Ping; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static Ping create() => Ping._(); - Ping createEmptyInstance() => create(); - static $pb.PbList<Ping> createRepeated() => $pb.PbList<Ping>(); - @$core.pragma('dart2js:noInline') - static Ping getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<Ping>(create); - static Ping? _defaultInstance; -} - -class OK extends $pb.GeneratedMessage { - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'OK', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..hasRequiredFields = false - ; - - OK._() : super(); - factory OK() => create(); - factory OK.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory OK.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - OK clone() => OK()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - OK copyWith(void Function(OK) updates) => super.copyWith((message) => updates(message as OK)) as OK; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static OK create() => OK._(); - OK createEmptyInstance() => create(); - static $pb.PbList<OK> createRepeated() => $pb.PbList<OK>(); - @$core.pragma('dart2js:noInline') - static OK getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OK>(create); - static OK? _defaultInstance; -} - -enum ClientMessage_Msg { - clienthello, - joinpools, - playercommit, - myproofslist, - blames, - notSet -} - -class ClientMessage extends $pb.GeneratedMessage { - static const $core.Map<$core.int, ClientMessage_Msg> _ClientMessage_MsgByTag = { - 1 : ClientMessage_Msg.clienthello, - 2 : ClientMessage_Msg.joinpools, - 3 : ClientMessage_Msg.playercommit, - 5 : ClientMessage_Msg.myproofslist, - 6 : ClientMessage_Msg.blames, - 0 : ClientMessage_Msg.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ClientMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [1, 2, 3, 5, 6]) - ..aOM<ClientHello>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'clienthello', subBuilder: ClientHello.create) - ..aOM<JoinPools>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'joinpools', subBuilder: JoinPools.create) - ..aOM<PlayerCommit>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'playercommit', subBuilder: PlayerCommit.create) - ..aOM<MyProofsList>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'myproofslist', subBuilder: MyProofsList.create) - ..aOM<Blames>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blames', subBuilder: Blames.create) - ; - - ClientMessage._() : super(); - factory ClientMessage({ - ClientHello? clienthello, - JoinPools? joinpools, - PlayerCommit? playercommit, - MyProofsList? myproofslist, - Blames? blames, - }) { - final _result = create(); - if (clienthello != null) { - _result.clienthello = clienthello; - } - if (joinpools != null) { - _result.joinpools = joinpools; - } - if (playercommit != null) { - _result.playercommit = playercommit; - } - if (myproofslist != null) { - _result.myproofslist = myproofslist; - } - if (blames != null) { - _result.blames = blames; - } - return _result; - } - factory ClientMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ClientMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - ClientMessage clone() => ClientMessage()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - ClientMessage copyWith(void Function(ClientMessage) updates) => super.copyWith((message) => updates(message as ClientMessage)) as ClientMessage; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static ClientMessage create() => ClientMessage._(); - ClientMessage createEmptyInstance() => create(); - static $pb.PbList<ClientMessage> createRepeated() => $pb.PbList<ClientMessage>(); - @$core.pragma('dart2js:noInline') - static ClientMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ClientMessage>(create); - static ClientMessage? _defaultInstance; - - ClientMessage_Msg whichMsg() => _ClientMessage_MsgByTag[$_whichOneof(0)]!; - void clearMsg() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - ClientHello get clienthello => $_getN(0); - @$pb.TagNumber(1) - set clienthello(ClientHello v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasClienthello() => $_has(0); - @$pb.TagNumber(1) - void clearClienthello() => clearField(1); - @$pb.TagNumber(1) - ClientHello ensureClienthello() => $_ensure(0); - - @$pb.TagNumber(2) - JoinPools get joinpools => $_getN(1); - @$pb.TagNumber(2) - set joinpools(JoinPools v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasJoinpools() => $_has(1); - @$pb.TagNumber(2) - void clearJoinpools() => clearField(2); - @$pb.TagNumber(2) - JoinPools ensureJoinpools() => $_ensure(1); - - @$pb.TagNumber(3) - PlayerCommit get playercommit => $_getN(2); - @$pb.TagNumber(3) - set playercommit(PlayerCommit v) { setField(3, v); } - @$pb.TagNumber(3) - $core.bool hasPlayercommit() => $_has(2); - @$pb.TagNumber(3) - void clearPlayercommit() => clearField(3); - @$pb.TagNumber(3) - PlayerCommit ensurePlayercommit() => $_ensure(2); - - @$pb.TagNumber(5) - MyProofsList get myproofslist => $_getN(3); - @$pb.TagNumber(5) - set myproofslist(MyProofsList v) { setField(5, v); } - @$pb.TagNumber(5) - $core.bool hasMyproofslist() => $_has(3); - @$pb.TagNumber(5) - void clearMyproofslist() => clearField(5); - @$pb.TagNumber(5) - MyProofsList ensureMyproofslist() => $_ensure(3); - - @$pb.TagNumber(6) - Blames get blames => $_getN(4); - @$pb.TagNumber(6) - set blames(Blames v) { setField(6, v); } - @$pb.TagNumber(6) - $core.bool hasBlames() => $_has(4); - @$pb.TagNumber(6) - void clearBlames() => clearField(6); - @$pb.TagNumber(6) - Blames ensureBlames() => $_ensure(4); -} - -enum ServerMessage_Msg { - serverhello, - tierstatusupdate, - fusionbegin, - startround, - blindsigresponses, - allcommitments, - sharecovertcomponents, - fusionresult, - theirproofslist, - restartround, - error, - notSet -} - -class ServerMessage extends $pb.GeneratedMessage { - static const $core.Map<$core.int, ServerMessage_Msg> _ServerMessage_MsgByTag = { - 1 : ServerMessage_Msg.serverhello, - 2 : ServerMessage_Msg.tierstatusupdate, - 3 : ServerMessage_Msg.fusionbegin, - 4 : ServerMessage_Msg.startround, - 5 : ServerMessage_Msg.blindsigresponses, - 6 : ServerMessage_Msg.allcommitments, - 7 : ServerMessage_Msg.sharecovertcomponents, - 8 : ServerMessage_Msg.fusionresult, - 9 : ServerMessage_Msg.theirproofslist, - 14 : ServerMessage_Msg.restartround, - 15 : ServerMessage_Msg.error, - 0 : ServerMessage_Msg.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'ServerMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 14, 15]) - ..aOM<ServerHello>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'serverhello', subBuilder: ServerHello.create) - ..aOM<TierStatusUpdate>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'tierstatusupdate', subBuilder: TierStatusUpdate.create) - ..aOM<FusionBegin>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fusionbegin', subBuilder: FusionBegin.create) - ..aOM<StartRound>(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'startround', subBuilder: StartRound.create) - ..aOM<BlindSigResponses>(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'blindsigresponses', subBuilder: BlindSigResponses.create) - ..aOM<AllCommitments>(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'allcommitments', subBuilder: AllCommitments.create) - ..aOM<ShareCovertComponents>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sharecovertcomponents', subBuilder: ShareCovertComponents.create) - ..aOM<FusionResult>(8, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'fusionresult', subBuilder: FusionResult.create) - ..aOM<TheirProofsList>(9, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'theirproofslist', subBuilder: TheirProofsList.create) - ..aOM<RestartRound>(14, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'restartround', subBuilder: RestartRound.create) - ..aOM<Error>(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'error', subBuilder: Error.create) - ; - - ServerMessage._() : super(); - factory ServerMessage({ - ServerHello? serverhello, - TierStatusUpdate? tierstatusupdate, - FusionBegin? fusionbegin, - StartRound? startround, - BlindSigResponses? blindsigresponses, - AllCommitments? allcommitments, - ShareCovertComponents? sharecovertcomponents, - FusionResult? fusionresult, - TheirProofsList? theirproofslist, - RestartRound? restartround, - Error? error, - }) { - final _result = create(); - if (serverhello != null) { - _result.serverhello = serverhello; - } - if (tierstatusupdate != null) { - _result.tierstatusupdate = tierstatusupdate; - } - if (fusionbegin != null) { - _result.fusionbegin = fusionbegin; - } - if (startround != null) { - _result.startround = startround; - } - if (blindsigresponses != null) { - _result.blindsigresponses = blindsigresponses; - } - if (allcommitments != null) { - _result.allcommitments = allcommitments; - } - if (sharecovertcomponents != null) { - _result.sharecovertcomponents = sharecovertcomponents; - } - if (fusionresult != null) { - _result.fusionresult = fusionresult; - } - if (theirproofslist != null) { - _result.theirproofslist = theirproofslist; - } - if (restartround != null) { - _result.restartround = restartround; - } - if (error != null) { - _result.error = error; - } - return _result; - } - factory ServerMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory ServerMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - ServerMessage clone() => ServerMessage()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - ServerMessage copyWith(void Function(ServerMessage) updates) => super.copyWith((message) => updates(message as ServerMessage)) as ServerMessage; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static ServerMessage create() => ServerMessage._(); - ServerMessage createEmptyInstance() => create(); - static $pb.PbList<ServerMessage> createRepeated() => $pb.PbList<ServerMessage>(); - @$core.pragma('dart2js:noInline') - static ServerMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<ServerMessage>(create); - static ServerMessage? _defaultInstance; - - ServerMessage_Msg whichMsg() => _ServerMessage_MsgByTag[$_whichOneof(0)]!; - void clearMsg() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - ServerHello get serverhello => $_getN(0); - @$pb.TagNumber(1) - set serverhello(ServerHello v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasServerhello() => $_has(0); - @$pb.TagNumber(1) - void clearServerhello() => clearField(1); - @$pb.TagNumber(1) - ServerHello ensureServerhello() => $_ensure(0); - - @$pb.TagNumber(2) - TierStatusUpdate get tierstatusupdate => $_getN(1); - @$pb.TagNumber(2) - set tierstatusupdate(TierStatusUpdate v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasTierstatusupdate() => $_has(1); - @$pb.TagNumber(2) - void clearTierstatusupdate() => clearField(2); - @$pb.TagNumber(2) - TierStatusUpdate ensureTierstatusupdate() => $_ensure(1); - - @$pb.TagNumber(3) - FusionBegin get fusionbegin => $_getN(2); - @$pb.TagNumber(3) - set fusionbegin(FusionBegin v) { setField(3, v); } - @$pb.TagNumber(3) - $core.bool hasFusionbegin() => $_has(2); - @$pb.TagNumber(3) - void clearFusionbegin() => clearField(3); - @$pb.TagNumber(3) - FusionBegin ensureFusionbegin() => $_ensure(2); - - @$pb.TagNumber(4) - StartRound get startround => $_getN(3); - @$pb.TagNumber(4) - set startround(StartRound v) { setField(4, v); } - @$pb.TagNumber(4) - $core.bool hasStartround() => $_has(3); - @$pb.TagNumber(4) - void clearStartround() => clearField(4); - @$pb.TagNumber(4) - StartRound ensureStartround() => $_ensure(3); - - @$pb.TagNumber(5) - BlindSigResponses get blindsigresponses => $_getN(4); - @$pb.TagNumber(5) - set blindsigresponses(BlindSigResponses v) { setField(5, v); } - @$pb.TagNumber(5) - $core.bool hasBlindsigresponses() => $_has(4); - @$pb.TagNumber(5) - void clearBlindsigresponses() => clearField(5); - @$pb.TagNumber(5) - BlindSigResponses ensureBlindsigresponses() => $_ensure(4); - - @$pb.TagNumber(6) - AllCommitments get allcommitments => $_getN(5); - @$pb.TagNumber(6) - set allcommitments(AllCommitments v) { setField(6, v); } - @$pb.TagNumber(6) - $core.bool hasAllcommitments() => $_has(5); - @$pb.TagNumber(6) - void clearAllcommitments() => clearField(6); - @$pb.TagNumber(6) - AllCommitments ensureAllcommitments() => $_ensure(5); - - @$pb.TagNumber(7) - ShareCovertComponents get sharecovertcomponents => $_getN(6); - @$pb.TagNumber(7) - set sharecovertcomponents(ShareCovertComponents v) { setField(7, v); } - @$pb.TagNumber(7) - $core.bool hasSharecovertcomponents() => $_has(6); - @$pb.TagNumber(7) - void clearSharecovertcomponents() => clearField(7); - @$pb.TagNumber(7) - ShareCovertComponents ensureSharecovertcomponents() => $_ensure(6); - - @$pb.TagNumber(8) - FusionResult get fusionresult => $_getN(7); - @$pb.TagNumber(8) - set fusionresult(FusionResult v) { setField(8, v); } - @$pb.TagNumber(8) - $core.bool hasFusionresult() => $_has(7); - @$pb.TagNumber(8) - void clearFusionresult() => clearField(8); - @$pb.TagNumber(8) - FusionResult ensureFusionresult() => $_ensure(7); - - @$pb.TagNumber(9) - TheirProofsList get theirproofslist => $_getN(8); - @$pb.TagNumber(9) - set theirproofslist(TheirProofsList v) { setField(9, v); } - @$pb.TagNumber(9) - $core.bool hasTheirproofslist() => $_has(8); - @$pb.TagNumber(9) - void clearTheirproofslist() => clearField(9); - @$pb.TagNumber(9) - TheirProofsList ensureTheirproofslist() => $_ensure(8); - - @$pb.TagNumber(14) - RestartRound get restartround => $_getN(9); - @$pb.TagNumber(14) - set restartround(RestartRound v) { setField(14, v); } - @$pb.TagNumber(14) - $core.bool hasRestartround() => $_has(9); - @$pb.TagNumber(14) - void clearRestartround() => clearField(14); - @$pb.TagNumber(14) - RestartRound ensureRestartround() => $_ensure(9); - - @$pb.TagNumber(15) - Error get error => $_getN(10); - @$pb.TagNumber(15) - set error(Error v) { setField(15, v); } - @$pb.TagNumber(15) - $core.bool hasError() => $_has(10); - @$pb.TagNumber(15) - void clearError() => clearField(15); - @$pb.TagNumber(15) - Error ensureError() => $_ensure(10); -} - -enum CovertMessage_Msg { - component, - signature, - ping, - notSet -} - -class CovertMessage extends $pb.GeneratedMessage { - static const $core.Map<$core.int, CovertMessage_Msg> _CovertMessage_MsgByTag = { - 1 : CovertMessage_Msg.component, - 2 : CovertMessage_Msg.signature, - 3 : CovertMessage_Msg.ping, - 0 : CovertMessage_Msg.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [1, 2, 3]) - ..aOM<CovertComponent>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'component', subBuilder: CovertComponent.create) - ..aOM<CovertTransactionSignature>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signature', subBuilder: CovertTransactionSignature.create) - ..aOM<Ping>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ping', subBuilder: Ping.create) - ; - - CovertMessage._() : super(); - factory CovertMessage({ - CovertComponent? component, - CovertTransactionSignature? signature, - Ping? ping, - }) { - final _result = create(); - if (component != null) { - _result.component = component; - } - if (signature != null) { - _result.signature = signature; - } - if (ping != null) { - _result.ping = ping; - } - return _result; - } - factory CovertMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CovertMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CovertMessage clone() => CovertMessage()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CovertMessage copyWith(void Function(CovertMessage) updates) => super.copyWith((message) => updates(message as CovertMessage)) as CovertMessage; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CovertMessage create() => CovertMessage._(); - CovertMessage createEmptyInstance() => create(); - static $pb.PbList<CovertMessage> createRepeated() => $pb.PbList<CovertMessage>(); - @$core.pragma('dart2js:noInline') - static CovertMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertMessage>(create); - static CovertMessage? _defaultInstance; - - CovertMessage_Msg whichMsg() => _CovertMessage_MsgByTag[$_whichOneof(0)]!; - void clearMsg() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - CovertComponent get component => $_getN(0); - @$pb.TagNumber(1) - set component(CovertComponent v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasComponent() => $_has(0); - @$pb.TagNumber(1) - void clearComponent() => clearField(1); - @$pb.TagNumber(1) - CovertComponent ensureComponent() => $_ensure(0); - - @$pb.TagNumber(2) - CovertTransactionSignature get signature => $_getN(1); - @$pb.TagNumber(2) - set signature(CovertTransactionSignature v) { setField(2, v); } - @$pb.TagNumber(2) - $core.bool hasSignature() => $_has(1); - @$pb.TagNumber(2) - void clearSignature() => clearField(2); - @$pb.TagNumber(2) - CovertTransactionSignature ensureSignature() => $_ensure(1); - - @$pb.TagNumber(3) - Ping get ping => $_getN(2); - @$pb.TagNumber(3) - set ping(Ping v) { setField(3, v); } - @$pb.TagNumber(3) - $core.bool hasPing() => $_has(2); - @$pb.TagNumber(3) - void clearPing() => clearField(3); - @$pb.TagNumber(3) - Ping ensurePing() => $_ensure(2); -} - -enum CovertResponse_Msg { - ok, - error, - notSet -} - -class CovertResponse extends $pb.GeneratedMessage { - static const $core.Map<$core.int, CovertResponse_Msg> _CovertResponse_MsgByTag = { - 1 : CovertResponse_Msg.ok, - 15 : CovertResponse_Msg.error, - 0 : CovertResponse_Msg.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CovertResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'fusion'), createEmptyInstance: create) - ..oo(0, [1, 15]) - ..aOM<OK>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'ok', subBuilder: OK.create) - ..aOM<Error>(15, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'error', subBuilder: Error.create) - ..hasRequiredFields = false - ; - - CovertResponse._() : super(); - factory CovertResponse({ - OK? ok, - Error? error, - }) { - final _result = create(); - if (ok != null) { - _result.ok = ok; - } - if (error != null) { - _result.error = error; - } - return _result; - } - factory CovertResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); - factory CovertResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - CovertResponse clone() => CovertResponse()..mergeFromMessage(this); - @$core.Deprecated( - 'Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - CovertResponse copyWith(void Function(CovertResponse) updates) => super.copyWith((message) => updates(message as CovertResponse)) as CovertResponse; // ignore: deprecated_member_use - $pb.BuilderInfo get info_ => _i; - @$core.pragma('dart2js:noInline') - static CovertResponse create() => CovertResponse._(); - CovertResponse createEmptyInstance() => create(); - static $pb.PbList<CovertResponse> createRepeated() => $pb.PbList<CovertResponse>(); - @$core.pragma('dart2js:noInline') - static CovertResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<CovertResponse>(create); - static CovertResponse? _defaultInstance; - - CovertResponse_Msg whichMsg() => _CovertResponse_MsgByTag[$_whichOneof(0)]!; - void clearMsg() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - OK get ok => $_getN(0); - @$pb.TagNumber(1) - set ok(OK v) { setField(1, v); } - @$pb.TagNumber(1) - $core.bool hasOk() => $_has(0); - @$pb.TagNumber(1) - void clearOk() => clearField(1); - @$pb.TagNumber(1) - OK ensureOk() => $_ensure(0); - - @$pb.TagNumber(15) - Error get error => $_getN(1); - @$pb.TagNumber(15) - set error(Error v) { setField(15, v); } - @$pb.TagNumber(15) - $core.bool hasError() => $_has(1); - @$pb.TagNumber(15) - void clearError() => clearField(15); - @$pb.TagNumber(15) - Error ensureError() => $_ensure(1); -} - diff --git a/lib/services/cashfusion/protobuf/fusion.pbenum.dart b/lib/services/cashfusion/protobuf/fusion.pbenum.dart deleted file mode 100644 index fb5c0d734..000000000 --- a/lib/services/cashfusion/protobuf/fusion.pbenum.dart +++ /dev/null @@ -1,7 +0,0 @@ -/// -// Generated code. Do not modify. -// source: fusion.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name - diff --git a/lib/services/cashfusion/protobuf/fusion.pbjson.dart b/lib/services/cashfusion/protobuf/fusion.pbjson.dart deleted file mode 100644 index 7735f5acf..000000000 --- a/lib/services/cashfusion/protobuf/fusion.pbjson.dart +++ /dev/null @@ -1,427 +0,0 @@ -/// -// Generated code. Do not modify. -// source: fusion.proto -// -// @dart = 2.12 -// ignore_for_file: annotate_overrides,camel_case_types,constant_identifier_names,deprecated_member_use_from_same_package,directives_ordering,library_prefixes,non_constant_identifier_names,prefer_final_fields,return_of_invalid_type,unnecessary_const,unnecessary_import,unnecessary_this,unused_import,unused_shown_name - -import 'dart:core' as $core; -import 'dart:convert' as $convert; -import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use inputComponentDescriptor instead') -const InputComponent$json = const { - '1': 'InputComponent', - '2': const [ - const {'1': 'prev_txid', '3': 1, '4': 2, '5': 12, '10': 'prevTxid'}, - const {'1': 'prev_index', '3': 2, '4': 2, '5': 13, '10': 'prevIndex'}, - const {'1': 'pubkey', '3': 3, '4': 2, '5': 12, '10': 'pubkey'}, - const {'1': 'amount', '3': 4, '4': 2, '5': 4, '10': 'amount'}, - ], -}; - -/// Descriptor for `InputComponent`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List inputComponentDescriptor = $convert.base64Decode('Cg5JbnB1dENvbXBvbmVudBIbCglwcmV2X3R4aWQYASACKAxSCHByZXZUeGlkEh0KCnByZXZfaW5kZXgYAiACKA1SCXByZXZJbmRleBIWCgZwdWJrZXkYAyACKAxSBnB1YmtleRIWCgZhbW91bnQYBCACKARSBmFtb3VudA=='); -@$core.Deprecated('Use outputComponentDescriptor instead') -const OutputComponent$json = const { - '1': 'OutputComponent', - '2': const [ - const {'1': 'scriptpubkey', '3': 1, '4': 2, '5': 12, '10': 'scriptpubkey'}, - const {'1': 'amount', '3': 2, '4': 2, '5': 4, '10': 'amount'}, - ], -}; - -/// Descriptor for `OutputComponent`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List outputComponentDescriptor = $convert.base64Decode('Cg9PdXRwdXRDb21wb25lbnQSIgoMc2NyaXB0cHVia2V5GAEgAigMUgxzY3JpcHRwdWJrZXkSFgoGYW1vdW50GAIgAigEUgZhbW91bnQ='); -@$core.Deprecated('Use blankComponentDescriptor instead') -const BlankComponent$json = const { - '1': 'BlankComponent', -}; - -/// Descriptor for `BlankComponent`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blankComponentDescriptor = $convert.base64Decode('Cg5CbGFua0NvbXBvbmVudA=='); -@$core.Deprecated('Use componentDescriptor instead') -const Component$json = const { - '1': 'Component', - '2': const [ - const {'1': 'salt_commitment', '3': 1, '4': 2, '5': 12, '10': 'saltCommitment'}, - const {'1': 'input', '3': 2, '4': 1, '5': 11, '6': '.fusion.InputComponent', '9': 0, '10': 'input'}, - const {'1': 'output', '3': 3, '4': 1, '5': 11, '6': '.fusion.OutputComponent', '9': 0, '10': 'output'}, - const {'1': 'blank', '3': 4, '4': 1, '5': 11, '6': '.fusion.BlankComponent', '9': 0, '10': 'blank'}, - ], - '8': const [ - const {'1': 'component'}, - ], -}; - -/// Descriptor for `Component`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List componentDescriptor = $convert.base64Decode('CglDb21wb25lbnQSJwoPc2FsdF9jb21taXRtZW50GAEgAigMUg5zYWx0Q29tbWl0bWVudBIuCgVpbnB1dBgCIAEoCzIWLmZ1c2lvbi5JbnB1dENvbXBvbmVudEgAUgVpbnB1dBIxCgZvdXRwdXQYAyABKAsyFy5mdXNpb24uT3V0cHV0Q29tcG9uZW50SABSBm91dHB1dBIuCgVibGFuaxgEIAEoCzIWLmZ1c2lvbi5CbGFua0NvbXBvbmVudEgAUgVibGFua0ILCgljb21wb25lbnQ='); -@$core.Deprecated('Use initialCommitmentDescriptor instead') -const InitialCommitment$json = const { - '1': 'InitialCommitment', - '2': const [ - const {'1': 'salted_component_hash', '3': 1, '4': 2, '5': 12, '10': 'saltedComponentHash'}, - const {'1': 'amount_commitment', '3': 2, '4': 2, '5': 12, '10': 'amountCommitment'}, - const {'1': 'communication_key', '3': 3, '4': 2, '5': 12, '10': 'communicationKey'}, - ], -}; - -/// Descriptor for `InitialCommitment`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List initialCommitmentDescriptor = $convert.base64Decode('ChFJbml0aWFsQ29tbWl0bWVudBIyChVzYWx0ZWRfY29tcG9uZW50X2hhc2gYASACKAxSE3NhbHRlZENvbXBvbmVudEhhc2gSKwoRYW1vdW50X2NvbW1pdG1lbnQYAiACKAxSEGFtb3VudENvbW1pdG1lbnQSKwoRY29tbXVuaWNhdGlvbl9rZXkYAyACKAxSEGNvbW11bmljYXRpb25LZXk='); -@$core.Deprecated('Use proofDescriptor instead') -const Proof$json = const { - '1': 'Proof', - '2': const [ - const {'1': 'component_idx', '3': 1, '4': 2, '5': 7, '10': 'componentIdx'}, - const {'1': 'salt', '3': 2, '4': 2, '5': 12, '10': 'salt'}, - const {'1': 'pedersen_nonce', '3': 3, '4': 2, '5': 12, '10': 'pedersenNonce'}, - ], -}; - -/// Descriptor for `Proof`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List proofDescriptor = $convert.base64Decode('CgVQcm9vZhIjCg1jb21wb25lbnRfaWR4GAEgAigHUgxjb21wb25lbnRJZHgSEgoEc2FsdBgCIAIoDFIEc2FsdBIlCg5wZWRlcnNlbl9ub25jZRgDIAIoDFINcGVkZXJzZW5Ob25jZQ=='); -@$core.Deprecated('Use clientHelloDescriptor instead') -const ClientHello$json = const { - '1': 'ClientHello', - '2': const [ - const {'1': 'version', '3': 1, '4': 2, '5': 12, '10': 'version'}, - const {'1': 'genesis_hash', '3': 2, '4': 1, '5': 12, '10': 'genesisHash'}, - ], -}; - -/// Descriptor for `ClientHello`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List clientHelloDescriptor = $convert.base64Decode('CgtDbGllbnRIZWxsbxIYCgd2ZXJzaW9uGAEgAigMUgd2ZXJzaW9uEiEKDGdlbmVzaXNfaGFzaBgCIAEoDFILZ2VuZXNpc0hhc2g='); -@$core.Deprecated('Use serverHelloDescriptor instead') -const ServerHello$json = const { - '1': 'ServerHello', - '2': const [ - const {'1': 'tiers', '3': 1, '4': 3, '5': 4, '10': 'tiers'}, - const {'1': 'num_components', '3': 2, '4': 2, '5': 13, '10': 'numComponents'}, - const {'1': 'component_feerate', '3': 4, '4': 2, '5': 4, '10': 'componentFeerate'}, - const {'1': 'min_excess_fee', '3': 5, '4': 2, '5': 4, '10': 'minExcessFee'}, - const {'1': 'max_excess_fee', '3': 6, '4': 2, '5': 4, '10': 'maxExcessFee'}, - const {'1': 'donation_address', '3': 15, '4': 1, '5': 9, '10': 'donationAddress'}, - ], -}; - -/// Descriptor for `ServerHello`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List serverHelloDescriptor = $convert.base64Decode('CgtTZXJ2ZXJIZWxsbxIUCgV0aWVycxgBIAMoBFIFdGllcnMSJQoObnVtX2NvbXBvbmVudHMYAiACKA1SDW51bUNvbXBvbmVudHMSKwoRY29tcG9uZW50X2ZlZXJhdGUYBCACKARSEGNvbXBvbmVudEZlZXJhdGUSJAoObWluX2V4Y2Vzc19mZWUYBSACKARSDG1pbkV4Y2Vzc0ZlZRIkCg5tYXhfZXhjZXNzX2ZlZRgGIAIoBFIMbWF4RXhjZXNzRmVlEikKEGRvbmF0aW9uX2FkZHJlc3MYDyABKAlSD2RvbmF0aW9uQWRkcmVzcw=='); -@$core.Deprecated('Use joinPoolsDescriptor instead') -const JoinPools$json = const { - '1': 'JoinPools', - '2': const [ - const {'1': 'tiers', '3': 1, '4': 3, '5': 4, '10': 'tiers'}, - const {'1': 'tags', '3': 2, '4': 3, '5': 11, '6': '.fusion.JoinPools.PoolTag', '10': 'tags'}, - ], - '3': const [JoinPools_PoolTag$json], -}; - -@$core.Deprecated('Use joinPoolsDescriptor instead') -const JoinPools_PoolTag$json = const { - '1': 'PoolTag', - '2': const [ - const {'1': 'id', '3': 1, '4': 2, '5': 12, '10': 'id'}, - const {'1': 'limit', '3': 2, '4': 2, '5': 13, '10': 'limit'}, - const {'1': 'no_ip', '3': 3, '4': 1, '5': 8, '10': 'noIp'}, - ], -}; - -/// Descriptor for `JoinPools`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List joinPoolsDescriptor = $convert.base64Decode('CglKb2luUG9vbHMSFAoFdGllcnMYASADKARSBXRpZXJzEi0KBHRhZ3MYAiADKAsyGS5mdXNpb24uSm9pblBvb2xzLlBvb2xUYWdSBHRhZ3MaRAoHUG9vbFRhZxIOCgJpZBgBIAIoDFICaWQSFAoFbGltaXQYAiACKA1SBWxpbWl0EhMKBW5vX2lwGAMgASgIUgRub0lw'); -@$core.Deprecated('Use tierStatusUpdateDescriptor instead') -const TierStatusUpdate$json = const { - '1': 'TierStatusUpdate', - '2': const [ - const {'1': 'statuses', '3': 1, '4': 3, '5': 11, '6': '.fusion.TierStatusUpdate.StatusesEntry', '10': 'statuses'}, - ], - '3': const [TierStatusUpdate_TierStatus$json, TierStatusUpdate_StatusesEntry$json], -}; - -@$core.Deprecated('Use tierStatusUpdateDescriptor instead') -const TierStatusUpdate_TierStatus$json = const { - '1': 'TierStatus', - '2': const [ - const {'1': 'players', '3': 1, '4': 1, '5': 13, '10': 'players'}, - const {'1': 'min_players', '3': 2, '4': 1, '5': 13, '10': 'minPlayers'}, - const {'1': 'max_players', '3': 3, '4': 1, '5': 13, '10': 'maxPlayers'}, - const {'1': 'time_remaining', '3': 4, '4': 1, '5': 13, '10': 'timeRemaining'}, - ], -}; - -@$core.Deprecated('Use tierStatusUpdateDescriptor instead') -const TierStatusUpdate_StatusesEntry$json = const { - '1': 'StatusesEntry', - '2': const [ - const {'1': 'key', '3': 1, '4': 1, '5': 4, '10': 'key'}, - const {'1': 'value', '3': 2, '4': 1, '5': 11, '6': '.fusion.TierStatusUpdate.TierStatus', '10': 'value'}, - ], - '7': const {'7': true}, -}; - -/// Descriptor for `TierStatusUpdate`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List tierStatusUpdateDescriptor = $convert.base64Decode('ChBUaWVyU3RhdHVzVXBkYXRlEkIKCHN0YXR1c2VzGAEgAygLMiYuZnVzaW9uLlRpZXJTdGF0dXNVcGRhdGUuU3RhdHVzZXNFbnRyeVIIc3RhdHVzZXMajwEKClRpZXJTdGF0dXMSGAoHcGxheWVycxgBIAEoDVIHcGxheWVycxIfCgttaW5fcGxheWVycxgCIAEoDVIKbWluUGxheWVycxIfCgttYXhfcGxheWVycxgDIAEoDVIKbWF4UGxheWVycxIlCg50aW1lX3JlbWFpbmluZxgEIAEoDVINdGltZVJlbWFpbmluZxpgCg1TdGF0dXNlc0VudHJ5EhAKA2tleRgBIAEoBFIDa2V5EjkKBXZhbHVlGAIgASgLMiMuZnVzaW9uLlRpZXJTdGF0dXNVcGRhdGUuVGllclN0YXR1c1IFdmFsdWU6AjgB'); -@$core.Deprecated('Use fusionBeginDescriptor instead') -const FusionBegin$json = const { - '1': 'FusionBegin', - '2': const [ - const {'1': 'tier', '3': 1, '4': 2, '5': 4, '10': 'tier'}, - const {'1': 'covert_domain', '3': 2, '4': 2, '5': 12, '10': 'covertDomain'}, - const {'1': 'covert_port', '3': 3, '4': 2, '5': 13, '10': 'covertPort'}, - const {'1': 'covert_ssl', '3': 4, '4': 1, '5': 8, '10': 'covertSsl'}, - const {'1': 'server_time', '3': 5, '4': 2, '5': 6, '10': 'serverTime'}, - ], -}; - -/// Descriptor for `FusionBegin`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fusionBeginDescriptor = $convert.base64Decode('CgtGdXNpb25CZWdpbhISCgR0aWVyGAEgAigEUgR0aWVyEiMKDWNvdmVydF9kb21haW4YAiACKAxSDGNvdmVydERvbWFpbhIfCgtjb3ZlcnRfcG9ydBgDIAIoDVIKY292ZXJ0UG9ydBIdCgpjb3ZlcnRfc3NsGAQgASgIUgljb3ZlcnRTc2wSHwoLc2VydmVyX3RpbWUYBSACKAZSCnNlcnZlclRpbWU='); -@$core.Deprecated('Use startRoundDescriptor instead') -const StartRound$json = const { - '1': 'StartRound', - '2': const [ - const {'1': 'round_pubkey', '3': 1, '4': 2, '5': 12, '10': 'roundPubkey'}, - const {'1': 'blind_nonce_points', '3': 2, '4': 3, '5': 12, '10': 'blindNoncePoints'}, - const {'1': 'server_time', '3': 5, '4': 2, '5': 6, '10': 'serverTime'}, - ], -}; - -/// Descriptor for `StartRound`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List startRoundDescriptor = $convert.base64Decode('CgpTdGFydFJvdW5kEiEKDHJvdW5kX3B1YmtleRgBIAIoDFILcm91bmRQdWJrZXkSLAoSYmxpbmRfbm9uY2VfcG9pbnRzGAIgAygMUhBibGluZE5vbmNlUG9pbnRzEh8KC3NlcnZlcl90aW1lGAUgAigGUgpzZXJ2ZXJUaW1l'); -@$core.Deprecated('Use playerCommitDescriptor instead') -const PlayerCommit$json = const { - '1': 'PlayerCommit', - '2': const [ - const {'1': 'initial_commitments', '3': 1, '4': 3, '5': 12, '10': 'initialCommitments'}, - const {'1': 'excess_fee', '3': 2, '4': 2, '5': 4, '10': 'excessFee'}, - const {'1': 'pedersen_total_nonce', '3': 3, '4': 2, '5': 12, '10': 'pedersenTotalNonce'}, - const {'1': 'random_number_commitment', '3': 4, '4': 2, '5': 12, '10': 'randomNumberCommitment'}, - const {'1': 'blind_sig_requests', '3': 5, '4': 3, '5': 12, '10': 'blindSigRequests'}, - ], -}; - -/// Descriptor for `PlayerCommit`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List playerCommitDescriptor = $convert.base64Decode('CgxQbGF5ZXJDb21taXQSLwoTaW5pdGlhbF9jb21taXRtZW50cxgBIAMoDFISaW5pdGlhbENvbW1pdG1lbnRzEh0KCmV4Y2Vzc19mZWUYAiACKARSCWV4Y2Vzc0ZlZRIwChRwZWRlcnNlbl90b3RhbF9ub25jZRgDIAIoDFIScGVkZXJzZW5Ub3RhbE5vbmNlEjgKGHJhbmRvbV9udW1iZXJfY29tbWl0bWVudBgEIAIoDFIWcmFuZG9tTnVtYmVyQ29tbWl0bWVudBIsChJibGluZF9zaWdfcmVxdWVzdHMYBSADKAxSEGJsaW5kU2lnUmVxdWVzdHM='); -@$core.Deprecated('Use blindSigResponsesDescriptor instead') -const BlindSigResponses$json = const { - '1': 'BlindSigResponses', - '2': const [ - const {'1': 'scalars', '3': 1, '4': 3, '5': 12, '10': 'scalars'}, - ], -}; - -/// Descriptor for `BlindSigResponses`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blindSigResponsesDescriptor = $convert.base64Decode('ChFCbGluZFNpZ1Jlc3BvbnNlcxIYCgdzY2FsYXJzGAEgAygMUgdzY2FsYXJz'); -@$core.Deprecated('Use allCommitmentsDescriptor instead') -const AllCommitments$json = const { - '1': 'AllCommitments', - '2': const [ - const {'1': 'initial_commitments', '3': 1, '4': 3, '5': 12, '10': 'initialCommitments'}, - ], -}; - -/// Descriptor for `AllCommitments`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List allCommitmentsDescriptor = $convert.base64Decode('Cg5BbGxDb21taXRtZW50cxIvChNpbml0aWFsX2NvbW1pdG1lbnRzGAEgAygMUhJpbml0aWFsQ29tbWl0bWVudHM='); -@$core.Deprecated('Use covertComponentDescriptor instead') -const CovertComponent$json = const { - '1': 'CovertComponent', - '2': const [ - const {'1': 'round_pubkey', '3': 1, '4': 1, '5': 12, '10': 'roundPubkey'}, - const {'1': 'signature', '3': 2, '4': 2, '5': 12, '10': 'signature'}, - const {'1': 'component', '3': 3, '4': 2, '5': 12, '10': 'component'}, - ], -}; - -/// Descriptor for `CovertComponent`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List covertComponentDescriptor = $convert.base64Decode('Cg9Db3ZlcnRDb21wb25lbnQSIQoMcm91bmRfcHVia2V5GAEgASgMUgtyb3VuZFB1YmtleRIcCglzaWduYXR1cmUYAiACKAxSCXNpZ25hdHVyZRIcCgljb21wb25lbnQYAyACKAxSCWNvbXBvbmVudA=='); -@$core.Deprecated('Use shareCovertComponentsDescriptor instead') -const ShareCovertComponents$json = const { - '1': 'ShareCovertComponents', - '2': const [ - const {'1': 'components', '3': 4, '4': 3, '5': 12, '10': 'components'}, - const {'1': 'skip_signatures', '3': 5, '4': 1, '5': 8, '10': 'skipSignatures'}, - const {'1': 'session_hash', '3': 6, '4': 1, '5': 12, '10': 'sessionHash'}, - ], -}; - -/// Descriptor for `ShareCovertComponents`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List shareCovertComponentsDescriptor = $convert.base64Decode('ChVTaGFyZUNvdmVydENvbXBvbmVudHMSHgoKY29tcG9uZW50cxgEIAMoDFIKY29tcG9uZW50cxInCg9za2lwX3NpZ25hdHVyZXMYBSABKAhSDnNraXBTaWduYXR1cmVzEiEKDHNlc3Npb25faGFzaBgGIAEoDFILc2Vzc2lvbkhhc2g='); -@$core.Deprecated('Use covertTransactionSignatureDescriptor instead') -const CovertTransactionSignature$json = const { - '1': 'CovertTransactionSignature', - '2': const [ - const {'1': 'round_pubkey', '3': 1, '4': 1, '5': 12, '10': 'roundPubkey'}, - const {'1': 'which_input', '3': 2, '4': 2, '5': 13, '10': 'whichInput'}, - const {'1': 'txsignature', '3': 3, '4': 2, '5': 12, '10': 'txsignature'}, - ], -}; - -/// Descriptor for `CovertTransactionSignature`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List covertTransactionSignatureDescriptor = $convert.base64Decode('ChpDb3ZlcnRUcmFuc2FjdGlvblNpZ25hdHVyZRIhCgxyb3VuZF9wdWJrZXkYASABKAxSC3JvdW5kUHVia2V5Eh8KC3doaWNoX2lucHV0GAIgAigNUgp3aGljaElucHV0EiAKC3R4c2lnbmF0dXJlGAMgAigMUgt0eHNpZ25hdHVyZQ=='); -@$core.Deprecated('Use fusionResultDescriptor instead') -const FusionResult$json = const { - '1': 'FusionResult', - '2': const [ - const {'1': 'ok', '3': 1, '4': 2, '5': 8, '10': 'ok'}, - const {'1': 'txsignatures', '3': 2, '4': 3, '5': 12, '10': 'txsignatures'}, - const {'1': 'bad_components', '3': 3, '4': 3, '5': 13, '10': 'badComponents'}, - ], -}; - -/// Descriptor for `FusionResult`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List fusionResultDescriptor = $convert.base64Decode('CgxGdXNpb25SZXN1bHQSDgoCb2sYASACKAhSAm9rEiIKDHR4c2lnbmF0dXJlcxgCIAMoDFIMdHhzaWduYXR1cmVzEiUKDmJhZF9jb21wb25lbnRzGAMgAygNUg1iYWRDb21wb25lbnRz'); -@$core.Deprecated('Use myProofsListDescriptor instead') -const MyProofsList$json = const { - '1': 'MyProofsList', - '2': const [ - const {'1': 'encrypted_proofs', '3': 1, '4': 3, '5': 12, '10': 'encryptedProofs'}, - const {'1': 'random_number', '3': 2, '4': 2, '5': 12, '10': 'randomNumber'}, - ], -}; - -/// Descriptor for `MyProofsList`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List myProofsListDescriptor = $convert.base64Decode('CgxNeVByb29mc0xpc3QSKQoQZW5jcnlwdGVkX3Byb29mcxgBIAMoDFIPZW5jcnlwdGVkUHJvb2ZzEiMKDXJhbmRvbV9udW1iZXIYAiACKAxSDHJhbmRvbU51bWJlcg=='); -@$core.Deprecated('Use theirProofsListDescriptor instead') -const TheirProofsList$json = const { - '1': 'TheirProofsList', - '2': const [ - const {'1': 'proofs', '3': 1, '4': 3, '5': 11, '6': '.fusion.TheirProofsList.RelayedProof', '10': 'proofs'}, - ], - '3': const [TheirProofsList_RelayedProof$json], -}; - -@$core.Deprecated('Use theirProofsListDescriptor instead') -const TheirProofsList_RelayedProof$json = const { - '1': 'RelayedProof', - '2': const [ - const {'1': 'encrypted_proof', '3': 1, '4': 2, '5': 12, '10': 'encryptedProof'}, - const {'1': 'src_commitment_idx', '3': 2, '4': 2, '5': 13, '10': 'srcCommitmentIdx'}, - const {'1': 'dst_key_idx', '3': 3, '4': 2, '5': 13, '10': 'dstKeyIdx'}, - ], -}; - -/// Descriptor for `TheirProofsList`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List theirProofsListDescriptor = $convert.base64Decode('Cg9UaGVpclByb29mc0xpc3QSPAoGcHJvb2ZzGAEgAygLMiQuZnVzaW9uLlRoZWlyUHJvb2ZzTGlzdC5SZWxheWVkUHJvb2ZSBnByb29mcxqFAQoMUmVsYXllZFByb29mEicKD2VuY3J5cHRlZF9wcm9vZhgBIAIoDFIOZW5jcnlwdGVkUHJvb2YSLAoSc3JjX2NvbW1pdG1lbnRfaWR4GAIgAigNUhBzcmNDb21taXRtZW50SWR4Eh4KC2RzdF9rZXlfaWR4GAMgAigNUglkc3RLZXlJZHg='); -@$core.Deprecated('Use blamesDescriptor instead') -const Blames$json = const { - '1': 'Blames', - '2': const [ - const {'1': 'blames', '3': 1, '4': 3, '5': 11, '6': '.fusion.Blames.BlameProof', '10': 'blames'}, - ], - '3': const [Blames_BlameProof$json], -}; - -@$core.Deprecated('Use blamesDescriptor instead') -const Blames_BlameProof$json = const { - '1': 'BlameProof', - '2': const [ - const {'1': 'which_proof', '3': 1, '4': 2, '5': 13, '10': 'whichProof'}, - const {'1': 'session_key', '3': 2, '4': 1, '5': 12, '9': 0, '10': 'sessionKey'}, - const {'1': 'privkey', '3': 3, '4': 1, '5': 12, '9': 0, '10': 'privkey'}, - const {'1': 'need_lookup_blockchain', '3': 4, '4': 1, '5': 8, '10': 'needLookupBlockchain'}, - const {'1': 'blame_reason', '3': 5, '4': 1, '5': 9, '10': 'blameReason'}, - ], - '8': const [ - const {'1': 'decrypter'}, - ], -}; - -/// Descriptor for `Blames`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List blamesDescriptor = $convert.base64Decode('CgZCbGFtZXMSMQoGYmxhbWVzGAEgAygLMhkuZnVzaW9uLkJsYW1lcy5CbGFtZVByb29mUgZibGFtZXMa0gEKCkJsYW1lUHJvb2YSHwoLd2hpY2hfcHJvb2YYASACKA1SCndoaWNoUHJvb2YSIQoLc2Vzc2lvbl9rZXkYAiABKAxIAFIKc2Vzc2lvbktleRIaCgdwcml2a2V5GAMgASgMSABSB3ByaXZrZXkSNAoWbmVlZF9sb29rdXBfYmxvY2tjaGFpbhgEIAEoCFIUbmVlZExvb2t1cEJsb2NrY2hhaW4SIQoMYmxhbWVfcmVhc29uGAUgASgJUgtibGFtZVJlYXNvbkILCglkZWNyeXB0ZXI='); -@$core.Deprecated('Use restartRoundDescriptor instead') -const RestartRound$json = const { - '1': 'RestartRound', -}; - -/// Descriptor for `RestartRound`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List restartRoundDescriptor = $convert.base64Decode('CgxSZXN0YXJ0Um91bmQ='); -@$core.Deprecated('Use errorDescriptor instead') -const Error$json = const { - '1': 'Error', - '2': const [ - const {'1': 'message', '3': 1, '4': 1, '5': 9, '10': 'message'}, - ], -}; - -/// Descriptor for `Error`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List errorDescriptor = $convert.base64Decode('CgVFcnJvchIYCgdtZXNzYWdlGAEgASgJUgdtZXNzYWdl'); -@$core.Deprecated('Use pingDescriptor instead') -const Ping$json = const { - '1': 'Ping', -}; - -/// Descriptor for `Ping`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List pingDescriptor = $convert.base64Decode('CgRQaW5n'); -@$core.Deprecated('Use oKDescriptor instead') -const OK$json = const { - '1': 'OK', -}; - -/// Descriptor for `OK`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List oKDescriptor = $convert.base64Decode('CgJPSw=='); -@$core.Deprecated('Use clientMessageDescriptor instead') -const ClientMessage$json = const { - '1': 'ClientMessage', - '2': const [ - const {'1': 'clienthello', '3': 1, '4': 1, '5': 11, '6': '.fusion.ClientHello', '9': 0, '10': 'clienthello'}, - const {'1': 'joinpools', '3': 2, '4': 1, '5': 11, '6': '.fusion.JoinPools', '9': 0, '10': 'joinpools'}, - const {'1': 'playercommit', '3': 3, '4': 1, '5': 11, '6': '.fusion.PlayerCommit', '9': 0, '10': 'playercommit'}, - const {'1': 'myproofslist', '3': 5, '4': 1, '5': 11, '6': '.fusion.MyProofsList', '9': 0, '10': 'myproofslist'}, - const {'1': 'blames', '3': 6, '4': 1, '5': 11, '6': '.fusion.Blames', '9': 0, '10': 'blames'}, - ], - '8': const [ - const {'1': 'msg'}, - ], -}; - -/// Descriptor for `ClientMessage`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List clientMessageDescriptor = $convert.base64Decode('Cg1DbGllbnRNZXNzYWdlEjcKC2NsaWVudGhlbGxvGAEgASgLMhMuZnVzaW9uLkNsaWVudEhlbGxvSABSC2NsaWVudGhlbGxvEjEKCWpvaW5wb29scxgCIAEoCzIRLmZ1c2lvbi5Kb2luUG9vbHNIAFIJam9pbnBvb2xzEjoKDHBsYXllcmNvbW1pdBgDIAEoCzIULmZ1c2lvbi5QbGF5ZXJDb21taXRIAFIMcGxheWVyY29tbWl0EjoKDG15cHJvb2ZzbGlzdBgFIAEoCzIULmZ1c2lvbi5NeVByb29mc0xpc3RIAFIMbXlwcm9vZnNsaXN0EigKBmJsYW1lcxgGIAEoCzIOLmZ1c2lvbi5CbGFtZXNIAFIGYmxhbWVzQgUKA21zZw=='); -@$core.Deprecated('Use serverMessageDescriptor instead') -const ServerMessage$json = const { - '1': 'ServerMessage', - '2': const [ - const {'1': 'serverhello', '3': 1, '4': 1, '5': 11, '6': '.fusion.ServerHello', '9': 0, '10': 'serverhello'}, - const {'1': 'tierstatusupdate', '3': 2, '4': 1, '5': 11, '6': '.fusion.TierStatusUpdate', '9': 0, '10': 'tierstatusupdate'}, - const {'1': 'fusionbegin', '3': 3, '4': 1, '5': 11, '6': '.fusion.FusionBegin', '9': 0, '10': 'fusionbegin'}, - const {'1': 'startround', '3': 4, '4': 1, '5': 11, '6': '.fusion.StartRound', '9': 0, '10': 'startround'}, - const {'1': 'blindsigresponses', '3': 5, '4': 1, '5': 11, '6': '.fusion.BlindSigResponses', '9': 0, '10': 'blindsigresponses'}, - const {'1': 'allcommitments', '3': 6, '4': 1, '5': 11, '6': '.fusion.AllCommitments', '9': 0, '10': 'allcommitments'}, - const {'1': 'sharecovertcomponents', '3': 7, '4': 1, '5': 11, '6': '.fusion.ShareCovertComponents', '9': 0, '10': 'sharecovertcomponents'}, - const {'1': 'fusionresult', '3': 8, '4': 1, '5': 11, '6': '.fusion.FusionResult', '9': 0, '10': 'fusionresult'}, - const {'1': 'theirproofslist', '3': 9, '4': 1, '5': 11, '6': '.fusion.TheirProofsList', '9': 0, '10': 'theirproofslist'}, - const {'1': 'restartround', '3': 14, '4': 1, '5': 11, '6': '.fusion.RestartRound', '9': 0, '10': 'restartround'}, - const {'1': 'error', '3': 15, '4': 1, '5': 11, '6': '.fusion.Error', '9': 0, '10': 'error'}, - ], - '8': const [ - const {'1': 'msg'}, - ], -}; - -/// Descriptor for `ServerMessage`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List serverMessageDescriptor = $convert.base64Decode('Cg1TZXJ2ZXJNZXNzYWdlEjcKC3NlcnZlcmhlbGxvGAEgASgLMhMuZnVzaW9uLlNlcnZlckhlbGxvSABSC3NlcnZlcmhlbGxvEkYKEHRpZXJzdGF0dXN1cGRhdGUYAiABKAsyGC5mdXNpb24uVGllclN0YXR1c1VwZGF0ZUgAUhB0aWVyc3RhdHVzdXBkYXRlEjcKC2Z1c2lvbmJlZ2luGAMgASgLMhMuZnVzaW9uLkZ1c2lvbkJlZ2luSABSC2Z1c2lvbmJlZ2luEjQKCnN0YXJ0cm91bmQYBCABKAsyEi5mdXNpb24uU3RhcnRSb3VuZEgAUgpzdGFydHJvdW5kEkkKEWJsaW5kc2lncmVzcG9uc2VzGAUgASgLMhkuZnVzaW9uLkJsaW5kU2lnUmVzcG9uc2VzSABSEWJsaW5kc2lncmVzcG9uc2VzEkAKDmFsbGNvbW1pdG1lbnRzGAYgASgLMhYuZnVzaW9uLkFsbENvbW1pdG1lbnRzSABSDmFsbGNvbW1pdG1lbnRzElUKFXNoYXJlY292ZXJ0Y29tcG9uZW50cxgHIAEoCzIdLmZ1c2lvbi5TaGFyZUNvdmVydENvbXBvbmVudHNIAFIVc2hhcmVjb3ZlcnRjb21wb25lbnRzEjoKDGZ1c2lvbnJlc3VsdBgIIAEoCzIULmZ1c2lvbi5GdXNpb25SZXN1bHRIAFIMZnVzaW9ucmVzdWx0EkMKD3RoZWlycHJvb2ZzbGlzdBgJIAEoCzIXLmZ1c2lvbi5UaGVpclByb29mc0xpc3RIAFIPdGhlaXJwcm9vZnNsaXN0EjoKDHJlc3RhcnRyb3VuZBgOIAEoCzIULmZ1c2lvbi5SZXN0YXJ0Um91bmRIAFIMcmVzdGFydHJvdW5kEiUKBWVycm9yGA8gASgLMg0uZnVzaW9uLkVycm9ySABSBWVycm9yQgUKA21zZw=='); -@$core.Deprecated('Use covertMessageDescriptor instead') -const CovertMessage$json = const { - '1': 'CovertMessage', - '2': const [ - const {'1': 'component', '3': 1, '4': 1, '5': 11, '6': '.fusion.CovertComponent', '9': 0, '10': 'component'}, - const {'1': 'signature', '3': 2, '4': 1, '5': 11, '6': '.fusion.CovertTransactionSignature', '9': 0, '10': 'signature'}, - const {'1': 'ping', '3': 3, '4': 1, '5': 11, '6': '.fusion.Ping', '9': 0, '10': 'ping'}, - ], - '8': const [ - const {'1': 'msg'}, - ], -}; - -/// Descriptor for `CovertMessage`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List covertMessageDescriptor = $convert.base64Decode('Cg1Db3ZlcnRNZXNzYWdlEjcKCWNvbXBvbmVudBgBIAEoCzIXLmZ1c2lvbi5Db3ZlcnRDb21wb25lbnRIAFIJY29tcG9uZW50EkIKCXNpZ25hdHVyZRgCIAEoCzIiLmZ1c2lvbi5Db3ZlcnRUcmFuc2FjdGlvblNpZ25hdHVyZUgAUglzaWduYXR1cmUSIgoEcGluZxgDIAEoCzIMLmZ1c2lvbi5QaW5nSABSBHBpbmdCBQoDbXNn'); -@$core.Deprecated('Use covertResponseDescriptor instead') -const CovertResponse$json = const { - '1': 'CovertResponse', - '2': const [ - const {'1': 'ok', '3': 1, '4': 1, '5': 11, '6': '.fusion.OK', '9': 0, '10': 'ok'}, - const {'1': 'error', '3': 15, '4': 1, '5': 11, '6': '.fusion.Error', '9': 0, '10': 'error'}, - ], - '8': const [ - const {'1': 'msg'}, - ], -}; - -/// Descriptor for `CovertResponse`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List covertResponseDescriptor = $convert.base64Decode('Cg5Db3ZlcnRSZXNwb25zZRIcCgJvaxgBIAEoCzIKLmZ1c2lvbi5PS0gAUgJvaxIlCgVlcnJvchgPIAEoCzINLmZ1c2lvbi5FcnJvckgAUgVlcnJvckIFCgNtc2c='); diff --git a/lib/services/cashfusion/protobuf/fusion.proto b/lib/services/cashfusion/protobuf/fusion.proto deleted file mode 100644 index f2273f78f..000000000 --- a/lib/services/cashfusion/protobuf/fusion.proto +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Electron Cash - a lightweight Bitcoin Cash client - * CashFusion - an advanced coin anonymizer - * - * Copyright (C) 2020 Mark B. Lundeberg - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -syntax = "proto2"; - -package fusion; - -// Some primitives - -message InputComponent { - required bytes prev_txid = 1; // in 'reverse' order, just like in tx - required uint32 prev_index = 2; - required bytes pubkey = 3; - required uint64 amount = 4; - } - -message OutputComponent { - required bytes scriptpubkey = 1; - required uint64 amount = 2; - } - -message BlankComponent { - } - -message Component { - required bytes salt_commitment = 1; // 32 bytes - oneof component { - InputComponent input = 2; - OutputComponent output = 3; - BlankComponent blank = 4; - } - } - -message InitialCommitment { - required bytes salted_component_hash = 1; // 32 byte hash - required bytes amount_commitment = 2; // uncompressed point - required bytes communication_key = 3; // compressed point - } - -message Proof { - // During blame phase, messages of this form are encrypted and sent - // to a different player. It is already known which commitment this - // should apply to, so we only need to point at the component. - required fixed32 component_idx = 1; - required bytes salt = 2; // 32 bytes - required bytes pedersen_nonce = 3; // 32 bytes -} - - - -// Primary communication message types (and flow) - -// Setup phase - -message ClientHello { // from client - required bytes version = 1; - optional bytes genesis_hash = 2; // 32 byte hash (bitcoind little-endian memory order) -} - -message ServerHello { // from server - repeated uint64 tiers = 1; - required uint32 num_components = 2; - required uint64 component_feerate = 4; // sats/kB - required uint64 min_excess_fee = 5; // sats - required uint64 max_excess_fee = 6; // sats - - optional string donation_address = 15; // BCH Address "bitcoincash:qpx..." -} - -message JoinPools { // from client - message PoolTag { - // These tags can be used to client to stop the server from including - // the client too many times in the same fusion. Thus, the client can - // connect many times without fear of fusing with themselves. - required bytes id = 1; // allowed up to 20 bytes - required uint32 limit = 2; // between 1 and 5 inclusive - optional bool no_ip = 3; // whether to do an IP-less tag -- this will collide with all other users, make sure it's random so you can't get DoSed. - } - repeated uint64 tiers = 1; - repeated PoolTag tags = 2; // at most five tags. -} - -message TierStatusUpdate { // from server - message TierStatus { - // in future, we will want server to indicate 'remaining time' and mask number of players. - // note: if player is in queue then a status will be ommitted. - optional uint32 players = 1; - optional uint32 min_players = 2; // minimum required to start (may have delay to allow extra) - optional uint32 max_players = 3; // maximum allowed (immediate start) - optional uint32 time_remaining = 4; - } - map<uint64, TierStatus> statuses = 1; -} - -message FusionBegin { // from server - required uint64 tier = 1; - required bytes covert_domain = 2; - required uint32 covert_port = 3; - optional bool covert_ssl = 4; - required fixed64 server_time = 5; // server unix time when sending this message; can't be too far off from recipient's clock. -} - - -// Fusion round (repeatable multiple times per connection) - -message StartRound { // from server - required bytes round_pubkey = 1; - repeated bytes blind_nonce_points = 2; - required fixed64 server_time = 5; // server unix time when sending this message; can't be too far off from recipient's clock. - } - -// Phase 3 -message PlayerCommit { // from client - repeated bytes initial_commitments = 1; // serialized InitialCommitment messages; server will repeat them later, verbatim. - required uint64 excess_fee = 2; - required bytes pedersen_total_nonce = 3; // 32 bytes - required bytes random_number_commitment = 4; // 32 bytes - repeated bytes blind_sig_requests = 5; // 32 byte scalars - } - -// Phase 4 -message BlindSigResponses { // from server - repeated bytes scalars = 1; // 32 byte scalars -} - -message AllCommitments { - // All the commitments from all players. At ~140 bytes per commitment and hundreds of commitments, this can be quite large, so it gets sent in its own message during the covert phase. - repeated bytes initial_commitments = 1; - } - -//Phase 5 -message CovertComponent { // from covert client - // The round key is used to identify the pool if needed - optional bytes round_pubkey = 1; - required bytes signature = 2; - required bytes component = 3; // bytes so that it can be signed and hashed verbatim - } - -//Phase 6 -message ShareCovertComponents { // from server - // This is a large message! 168 bytes per initial commitment, ~112 bytes per input component. - // Can easily reach 100 kB or more. - repeated bytes components = 4; - optional bool skip_signatures = 5; // if the server already sees a problem in submitted components - optional bytes session_hash = 6; // the server's calculation of session hash, so clients can crosscheck. -} - -// Phase 7A -message CovertTransactionSignature { // from covert client - // The round key is used to identify the pool if needed - optional bytes round_pubkey = 1; - required uint32 which_input = 2; - required bytes txsignature = 3; - } - -// Phase 8 -message FusionResult { // from server - required bool ok = 1; - repeated bytes txsignatures = 2; // if ok - repeated uint32 bad_components = 3; // if not ok - } - -// Phase 9 -message MyProofsList { // from client - repeated bytes encrypted_proofs = 1; - required bytes random_number = 2; // the number we committed to, back in phase 3 - } - -message TheirProofsList { // from server - message RelayedProof { - required bytes encrypted_proof = 1; - required uint32 src_commitment_idx = 2; // which of the commitments is being proven (index in full list) - required uint32 dst_key_idx = 3; // which of the recipient's keys will unlock the encryption (index in player list) - } - repeated RelayedProof proofs = 1; - } - -// Phase 10 -message Blames { // from client - message BlameProof { - required uint32 which_proof = 1; - oneof decrypter { - bytes session_key = 2; // 32 byte, preferred if the proof decryption works at all - bytes privkey = 3; // 32 byte scalar - } - - // Some errors can only be discovered by checking the blockchain, - // Namely, if an input UTXO is missing/spent/unconfirmed/different - // scriptpubkey/different amount, than indicated. - optional bool need_lookup_blockchain = 4; - - // The client can indicate why it thinks the blame is deserved. In - // case the server finds no issue, this string might help for debugging. - optional string blame_reason = 5; - } - repeated BlameProof blames = 1; - } - -// Final message of the round -message RestartRound { -} - -// Fatal error from server, likely we did something wrong (it will disconnect us, but the message may help debugging). -message Error { - optional string message = 1; -} - -// Simple ping, as a keepalive. -message Ping { -} - -// Simple acknowledgement, nothing more to say. -message OK { -} - -// Primary communication channel types - -message ClientMessage { - oneof msg { - ClientHello clienthello = 1; - JoinPools joinpools = 2; - PlayerCommit playercommit = 3; - MyProofsList myproofslist = 5; - Blames blames = 6; - } - } - -message ServerMessage { - oneof msg { - ServerHello serverhello = 1; - TierStatusUpdate tierstatusupdate = 2; - FusionBegin fusionbegin = 3; - StartRound startround = 4; - BlindSigResponses blindsigresponses = 5; - AllCommitments allcommitments = 6; - ShareCovertComponents sharecovertcomponents = 7; - FusionResult fusionresult = 8; - TheirProofsList theirproofslist = 9; - - RestartRound restartround = 14; - Error error = 15; - } - } - -message CovertMessage { // client -> server, covertly - oneof msg { - CovertComponent component = 1; - CovertTransactionSignature signature = 2; - Ping ping = 3; - } - } - -message CovertResponse { // server -> a covert client - oneof msg { - OK ok = 1; - Error error = 15; - } -} diff --git a/lib/services/cashfusion/protocol.dart b/lib/services/cashfusion/protocol.dart deleted file mode 100644 index 65abb965c..000000000 --- a/lib/services/cashfusion/protocol.dart +++ /dev/null @@ -1,55 +0,0 @@ -class Protocol { - static const VERSION = 'alpha13'; - - static const FUSE_ID = 'FUZ\x00'; - -// Safety limits to prevent loss of funds / limit fees: - //(Note that if we enter multiply into the same fusion, our limits apply - //separately for each "player".) - // - //Deny server that asks for more than this component feerate (sat/kbyte). - static const MAX_COMPONENT_FEERATE = 5000; - //The largest 'excess fee' that we are willing to pay in a fusion (fees beyond - //those needed to pay for our components' inclusion) - static const MAX_EXCESS_FEE = 10000; - // Even if the server allows more, put at most this many inputs+outputs+blanks - static const MAX_COMPONENTS = 40; - // The largest total fee we are willing to pay (our contribution to transaction - // size should not exceed 7 kB even with 40 largest components). - static const MAX_FEE = MAX_COMPONENT_FEERATE * 7 + MAX_EXCESS_FEE; - // For privacy reasons, don't submit less than this many distinct tx components. - // (distinct tx inputs, and tx outputs) - static const MIN_TX_COMPONENTS = 11; - - static const MIN_OUTPUT = 10000; - - static const COVERT_CONNECT_TIMEOUT = 15.0; - static const COVERT_CONNECT_WINDOW = 15.0; - static const COVERT_SUBMIT_TIMEOUT = 3.0; - static const COVERT_SUBMIT_WINDOW = 5.0; - - static const COVERT_CONNECT_SPARES = 6; - - static const MAX_CLOCK_DISCREPANCY = 5.0; - - static const WARMUP_TIME = 30.0; - static const WARMUP_SLOP = 3.0; - - static const TS_EXPECTING_COMMITMENTS = 3.0; - - static const T_START_COMPS = 5.0; - - static const TS_EXPECTING_COVERT_COMPONENTS = 15.0; - - static const T_START_SIGS = 20.0; - - static const TS_EXPECTING_COVERT_SIGNATURES = 30.0; - - static const T_EXPECTING_CONCLUSION = 35.0; - - static const T_START_CLOSE = 45.0; - static const T_START_CLOSE_BLAME = 80.0; - - static const STANDARD_TIMEOUT = 3.0; - static const BLAME_VERIFY_TIME = 5.0; -} diff --git a/lib/services/cashfusion/socketwrapper.dart b/lib/services/cashfusion/socketwrapper.dart deleted file mode 100644 index 0a20670ab..000000000 --- a/lib/services/cashfusion/socketwrapper.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'dart:io'; - -class SocketWrapper { - late Socket _socket; - final String serverIP; - final int serverPort; - - late Stream<List<int>> - _receiveStream; // create a field for the broadcast stream - - SocketWrapper(this.serverIP, this.serverPort); - Socket get socket => _socket; - - Stream<List<int>> get receiveStream => - _receiveStream; // expose the stream with a getter - - Future<void> connect() async { - _socket = await Socket.connect(serverIP, serverPort); - _receiveStream = - _socket.asBroadcastStream(); // initialize the broadcast stream - _socket.done.then((_) { - print('......Socket has been closed'); - }); - _socket.handleError((error) { - print('Socket error: $error'); - }); - } - - void status() { - if (_socket != null) { - print( - "Socket connected to ${_socket.remoteAddress.address}:${_socket.remotePort}"); - } else { - print("Socket is not connected"); - } - } - - Future<void> send(List<int> data) async { - if (_socket != null) { - _socket.add(data); - await _socket.flush(); - } else { - // handle error - } - } - - void close() { - _socket.close(); - } -} diff --git a/lib/services/cashfusion/util.dart b/lib/services/cashfusion/util.dart deleted file mode 100644 index f8cf75404..000000000 --- a/lib/services/cashfusion/util.dart +++ /dev/null @@ -1,329 +0,0 @@ -import 'dart:convert'; -import 'dart:math'; -import 'dart:typed_data'; - -import 'package:crypto/crypto.dart' as crypto; -import 'package:pointycastle/ecc/api.dart'; - -import 'fusion.pb.dart'; -import 'protocol.dart'; - -class Address { - String addr = ""; - - Address( - {required this.addr}); // Constructor updated to accept addr as a named parameter - - Address._create({required this.addr}); - - static Address fromScriptPubKey(List<int> scriptPubKey) { - // This is just a placeholder code - String addr = ""; // This should be computed from the scriptPubKey - return Address(addr: addr); - } - - // Public constructor for testing - static Address fromString(String address) { - return Address._create(addr: address); - } - - List<int> toScript() { - return []; - } -} - -class Tuple<T1, T2> { - T1 item1; - T2 item2; - - Tuple(this.item1, this.item2); - - set setItem1(T1 value) { - this.item1 = value; - } - - set setItem2(T2 value) { - this.item2 = value; - } -} - -class Util { - static Uint8List hexToBytes(String hex) { - var result = new Uint8List(hex.length ~/ 2); - for (var i = 0; i < hex.length; i += 2) { - var byte = int.parse(hex.substring(i, i + 2), radix: 16); - result[i ~/ 2] = byte; - } - return result; - } - - static void checkInputElectrumX(InputComponent inputComponent) { - // Implementation needed here - // - } - - static int randPosition(Uint8List seed, int numPositions, int counter) { - // counter to bytes - var counterBytes = Uint8List(4); - var counterByteData = ByteData.sublistView(counterBytes); - counterByteData.setInt32(0, counter, Endian.big); - - // hash the seed and counter - var digest = crypto.sha256.convert([...seed, ...counterBytes]); - - // take the first 8 bytes - var first8Bytes = digest.bytes.take(8).toList(); - var int64 = ByteData.sublistView(Uint8List.fromList(first8Bytes)) - .getUint64(0, Endian.big); - - // perform the modulo operation - return ((int64 * numPositions) >> 64).toInt(); - } - - static List<String> pubkeysFromPrivkey(String privkey) { - // This is a placeholder implementation. - return ['public_key1_dummy', 'public_key2_dummy']; - } - - static int dustLimit(int length) { - // This is a dummy implementation. - return 500; - } - - static Address getAddressFromOutputScript(Uint8List scriptpubkey) { - // Dummy implementation... - - // Throw exception if this is not a standard P2PKH address! - - return Address.fromString('dummy_address'); - } - - static bool schnorrVerify( - ECPoint pubkey, List<int> signature, Uint8List messageHash) { - // Implementation needed: actual Schnorr signature verification - return true; - } - - static String formatSatoshis(sats, {int numZeros = 8}) { - // To implement - return ""; - } - - static void updateWalletLabel(String txid, String label) { - // Call the wallet layer. - } - - static Uint8List getRandomBytes(int length) { - final rand = Random.secure(); - final bytes = Uint8List(length); - for (int i = 0; i < length; i++) { - bytes[i] = rand.nextInt(256); - } - return bytes; - } - - static List<List<T>> zip<T>(List<T> list1, List<T> list2) { - int length = min(list1.length, list2.length); - return List<List<T>>.generate(length, (i) => [list1[i], list2[i]]); - } - - static List<int> calcInitialHash(int tier, Uint8List covertDomainB, - int covertPort, bool covertSsl, double beginTime) { - // Converting int to bytes in BigEndian order - var tierBytes = ByteData(8)..setInt64(0, tier, Endian.big); - var covertPortBytes = ByteData(4)..setInt32(0, covertPort, Endian.big); - var beginTimeBytes = ByteData(8) - ..setInt64(0, beginTime.toInt(), Endian.big); - - // Define constants - const version = Protocol.VERSION; - const cashFusionSession = "Cash Fusion Session"; - - // Creating the list of bytes - List<int> elements = []; - elements.addAll(utf8.encode(cashFusionSession)); - elements.addAll(utf8.encode(version)); - elements.addAll(tierBytes.buffer.asInt8List()); - elements.addAll(covertDomainB); - elements.addAll(covertPortBytes.buffer.asInt8List()); - elements.add(covertSsl ? 1 : 0); - elements.addAll(beginTimeBytes.buffer.asInt8List()); - - // Hashing the concatenated elements - var digest = crypto.sha256.convert(elements); - - return digest.bytes; - } - - static List<int> calcRoundHash( - List<int> lastHash, - List<int> roundPubkey, - int roundTime, - List<List<int>> allCommitments, - List<List<int>> allComponents) { - return listHash([ - utf8.encode('Cash Fusion Round'), - lastHash, - roundPubkey, - bigIntToBytes(BigInt.from(roundTime)), - listHash(allCommitments), - listHash(allComponents), - ]); - } - - static List<int> listHash(Iterable<List<int>> iterable) { - var bytes = <int>[]; - - for (var x in iterable) { - var length = ByteData(4)..setUint32(0, x.length, Endian.big); - bytes.addAll(length.buffer.asUint8List()); - bytes.addAll(x); - } - return crypto.sha256.convert(bytes).bytes; - } - - static Uint8List get_current_genesis_hash() { - var GENESIS = - "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"; - var _lastGenesisHash = hexToBytes(GENESIS).reversed.toList(); - return Uint8List.fromList(_lastGenesisHash); - } - - static List<Address> unreserve_change_address(Address addr) { - //implement later based on wallet. - return []; - } - - static List<Address> reserve_change_addresses(int number_addresses) { - //implement later based on wallet. - return []; - } - - static bool walletHasTransaction(String txid) { - // implement later based on wallet. - return true; - } - - static Uint8List bigIntToBytes(BigInt bigInt) { - return Uint8List.fromList( - bigInt.toRadixString(16).padLeft(32, '0').codeUnits); - } - - static Tuple<Uint8List, Uint8List> genKeypair() { - var params = ECDomainParameters('secp256k1'); - var privKeyBigInt = _generatePrivateKey(params.n.bitLength); - var pubKeyPoint = params.G * privKeyBigInt; - - if (pubKeyPoint == null) { - throw Exception("Error generating public key."); - } - - Uint8List privKey = bigIntToBytes(privKeyBigInt); - Uint8List pubKey = pubKeyPoint.getEncoded(true); - - return Tuple(privKey, pubKey); - } - -// Generates a cryptographically secure private key - static BigInt _generatePrivateKey(int bitLength) { - final random = Random.secure(); - var bytes = bitLength ~/ 8; // floor division - var remBit = bitLength % 8; - - // Generate random BigInt - List<int> rnd = List<int>.generate(bytes, (_) => random.nextInt(256)); - var rndBit = random.nextInt(1 << remBit); - rnd.add(rndBit); - var privateKey = BigInt.parse( - rnd.map((x) => x.toRadixString(16).padLeft(2, '0')).join(), - radix: 16); - - return privateKey; - } - - // Additional helper function to convert bytes to hex - static String bytesToHex(Uint8List bytes) { - return bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join(); - } - - static BigInt bytesToBigInt(Uint8List bytes) { - String hexString = bytesToHex(bytes); - return BigInt.parse(hexString, radix: 16); - } - - static Uint8List sha256(Uint8List bytes) { - crypto.Digest digest = crypto.sha256.convert(bytes); - return Uint8List.fromList(digest.bytes); - } - - static Uint8List tokenBytes([int nbytes = 32]) { - final Random _random = Random.secure(); - - return Uint8List.fromList( - List<int>.generate(nbytes, (i) => _random.nextInt(256))); - } - - static int componentFee(int size, int feerate) { - // feerate in sat/kB - // size and feerate should both be integer - // fee is always rounded up - return ((size * feerate) + 999) ~/ 1000; - } - - static ECPoint ser_to_point( - Uint8List serializedPoint, ECDomainParameters params) { - var point = params.curve.decodePoint(serializedPoint); - if (point == null) { - throw FormatException('Point decoding failed'); - } - return point; - } - - static Uint8List point_to_ser(ECPoint point, bool compress) { - return point.getEncoded(compress); - } - - static BigInt secureRandomBigInt(int bitLength) { - final random = Random.secure(); - final bytes = (bitLength + 7) ~/ 8; // ceil division - final Uint8List randomBytes = Uint8List(bytes); - - for (int i = 0; i < bytes; i++) { - randomBytes[i] = random.nextInt(256); - } - - BigInt randomNumber = BigInt.parse( - randomBytes.map((e) => e.toRadixString(16).padLeft(2, '0')).join(), - radix: 16); - return randomNumber; - } - - static ECPoint combinePubKeys(List<ECPoint> pubKeys) { - if (pubKeys.isEmpty) throw ArgumentError('pubKeys cannot be empty'); - - ECPoint combined = pubKeys.first.curve.infinity!; - for (var pubKey in pubKeys) { - combined = (combined + pubKey)!; - } - - if (combined.isInfinity) { - throw Exception('Combined point is at infinity'); - } - - return combined; - } - - static bool isPointOnCurve(ECPoint point, ECCurve curve) { - var x = point.x!.toBigInteger()!; - var y = point.y!.toBigInteger()!; - var a = curve.a!.toBigInteger()!; - var b = curve.b!.toBigInteger()!; - - // Calculate the left and right sides of the equation - var left = y * y; - var right = (x * x * x) + (a * x) + b; - - // Check if the point is on the curve - return left == right; - } -} // END OF CLASS diff --git a/lib/services/cashfusion/validation.dart b/lib/services/cashfusion/validation.dart deleted file mode 100644 index 95c2a6f5e..000000000 --- a/lib/services/cashfusion/validation.dart +++ /dev/null @@ -1,301 +0,0 @@ -import 'dart:typed_data'; - -import 'package:pointycastle/export.dart'; - -import 'encrypt.dart' as Encrypt; -import 'fusion.dart'; -import 'fusion.pb.dart' as pb; -import 'pedersen.dart'; -import 'util.dart'; - -class ValidationError implements Exception { - final String message; - ValidationError(this.message); - @override - String toString() => 'Validation error: $message'; -} - -int componentContrib(pb.Component component, int feerate) { - if (component.hasInput()) { - var inp = Input.fromInputComponent(component.input); - return inp.amount.toInt() - Util.componentFee(inp.sizeOfInput(), feerate); - } else if (component.hasOutput()) { - var out = Output.fromOutputComponent(component.output); - return -out.amount.toInt() - Util.componentFee(out.sizeOfOutput(), feerate); - } else if (component.hasBlank()) { - return 0; - } else { - throw ValidationError('Invalid component type'); - } -} - -void check(bool condition, String failMessage) { - if (!condition) { - throw ValidationError(failMessage); - } -} - -dynamic protoStrictParse(dynamic msg, List<int> blob) { - try { - if (msg.mergeFromBuffer(blob) != blob.length) { - throw ArgumentError('DecodeError'); - } - } catch (e) { - throw ArgumentError('ValidationError: decode error'); - } - - if (!msg.isInitialized()) { - throw ArgumentError('missing fields'); - } - - // Protobuf in dart does not support 'unknownFields' method - // if (!msg.unknownFields.isEmpty) { - // throw ArgumentError('has extra fields'); - // } - - if (msg.writeToBuffer().length != blob.length) { - throw ArgumentError('encoding too long'); - } - - return msg; -} - -List<pb.InitialCommitment> checkPlayerCommit(pb.PlayerCommit msg, - int minExcessFee, int maxExcessFee, int numComponents) { - check(msg.initialCommitments.length == numComponents, - "wrong number of component commitments"); - check(msg.blindSigRequests.length == numComponents, - "wrong number of blind sig requests"); - - check( - minExcessFee <= msg.excessFee.toInt() && - msg.excessFee.toInt() <= maxExcessFee, - "bad excess fee"); - - check(msg.randomNumberCommitment.length == 32, "bad random commit"); - check(msg.pedersenTotalNonce.length == 32, "bad nonce"); - check(msg.blindSigRequests.every((r) => r.length == 32), - "bad blind sig request"); - - List<pb.InitialCommitment> commitMessages = []; - for (var cblob in msg.initialCommitments) { - pb.InitialCommitment cmsg = protoStrictParse(pb.InitialCommitment(), cblob); - check(cmsg.saltedComponentHash.length == 32, "bad salted hash"); - var P = cmsg.amountCommitment; - check(P.length == 65 && P[0] == 4, "bad commitment point"); - check( - cmsg.communicationKey.length == 33 && - (cmsg.communicationKey[0] == 2 || cmsg.communicationKey[0] == 3), - "bad communication key"); - commitMessages.add(cmsg); - } - - Uint8List HBytes = - Uint8List.fromList([0x02] + 'CashFusion gives us fungibility.'.codeUnits); - ECDomainParameters params = ECDomainParameters('secp256k1'); - ECPoint? HMaybe = params.curve.decodePoint(HBytes); - if (HMaybe == null) { - throw Exception('Failed to decode point'); - } - ECPoint H = HMaybe; - PedersenSetup setup = PedersenSetup(H); - - var claimedCommit; - var pointsum; - // Verify pedersen commitment - try { - pointsum = Commitment.add_points(commitMessages - .map((m) => Uint8List.fromList(m.amountCommitment)) - .toList()); - claimedCommit = setup.commit(BigInt.from(msg.excessFee.toInt()), - nonce: Util.bytesToBigInt(Uint8List.fromList(msg.pedersenTotalNonce))); - - check(pointsum == claimedCommit.PUncompressed, - "pedersen commitment mismatch"); - } catch (e) { - throw ValidationError("pedersen commitment verification error"); - } - check( - pointsum == claimedCommit.PUncompressed, "pedersen commitment mismatch"); - return commitMessages; -} - -Tuple<String, int> checkCovertComponent( - pb.CovertComponent msg, ECPoint roundPubkey, int componentFeerate) { - var messageHash = Util.sha256(Uint8List.fromList(msg.component)); - - check(msg.signature.length == 64, "bad message signature"); - check(Util.schnorrVerify(roundPubkey, msg.signature, messageHash), - "bad message signature"); - - var cmsg = protoStrictParse(pb.Component(), msg.component); - check(cmsg.saltCommitment.length == 32, "bad salt commitment"); - - String sortKey; - - if (cmsg.hasInput()) { - var inp = cmsg.input; - check(inp.prevTxid.length == 32, "bad txid"); - check( - (inp.pubkey.length == 33 && - (inp.pubkey[0] == 2 || inp.pubkey[0] == 3)) || - (inp.pubkey.length == 65 && inp.pubkey[0] == 4), - "bad pubkey"); - sortKey = 'i' + - String.fromCharCodes(inp.prevTxid.reversed) + - inp.prevIndex.toString() + - String.fromCharCodes(cmsg.saltCommitment); - } else if (cmsg.hasOutput()) { - var out = cmsg.output; - Address addr; - // Basically just checks if its ok address. should throw error if not. - addr = Util.getAddressFromOutputScript(out.scriptpubkey); - - check(out.amount >= Util.dustLimit(out.scriptpubkey.length), "dust output"); - sortKey = 'o' + - out.amount.toString() + - String.fromCharCodes(out.scriptpubkey) + - String.fromCharCodes(cmsg.saltCommitment); - } else if (cmsg.hasBlank()) { - sortKey = 'b' + String.fromCharCodes(cmsg.saltCommitment); - } else { - throw ValidationError('missing component details'); - } - - return Tuple(sortKey, componentContrib(cmsg, componentFeerate)); -} - -pb.InputComponent? validateProofInternal( - Uint8List proofBlob, - pb.InitialCommitment commitment, - List<Uint8List> allComponents, - List<int> badComponents, - int componentFeerate, -) { - Uint8List HBytes = - Uint8List.fromList([0x02] + 'CashFusion gives us fungibility.'.codeUnits); - ECDomainParameters params = ECDomainParameters('secp256k1'); - ECPoint? HMaybe = params.curve.decodePoint(HBytes); - if (HMaybe == null) { - throw Exception('Failed to decode point'); - } - ECPoint H = HMaybe; - PedersenSetup setup = PedersenSetup(H); - - var msg = protoStrictParse(pb.Proof(), proofBlob); - - Uint8List componentBlob; - try { - componentBlob = allComponents[msg.componentIdx]; - } catch (e) { - throw ValidationError("component index out of range"); - } - - check(!badComponents.contains(msg.componentIdx), "component in bad list"); - - var comp = pb.Component(); - comp.mergeFromBuffer(componentBlob); - assert(comp.isInitialized()); - - check(msg.salt.length == 32, "salt wrong length"); - check( - Util.sha256(msg.salt) == comp.saltCommitment, - "salt commitment mismatch", - ); - check( - Util.sha256(Uint8List.fromList([...msg.salt, ...componentBlob])) == - commitment.saltedComponentHash, - "salted component hash mismatch", - ); - - var contrib = componentContrib(comp, componentFeerate); - - var PCommitted = commitment.amountCommitment; - - var claimedCommit = setup.commit( - BigInt.from(contrib), - nonce: Util.bytesToBigInt(msg.pedersenNonce), - ); - - check( - Uint8List.fromList(PCommitted) == claimedCommit.PUncompressed, - "pedersen commitment mismatch", - ); - - if (comp.hasInput()) { - return comp.input; - } else { - return null; - } -} - -Future<dynamic> validateBlame( - pb.Blames_BlameProof blame, - Uint8List encProof, - Uint8List srcCommitBlob, - Uint8List destCommitBlob, - List<Uint8List> allComponents, - List<int> badComponents, - int componentFeerate, -) async { - var destCommit = pb.InitialCommitment(); - destCommit.mergeFromBuffer(destCommitBlob); - var destPubkey = destCommit.communicationKey; - - var srcCommit = pb.InitialCommitment(); - srcCommit.mergeFromBuffer(srcCommitBlob); - - var decrypter = blame.whichDecrypter(); - ECDomainParameters params = ECDomainParameters('secp256k1'); - if (decrypter == pb.Blames_BlameProof_Decrypter.privkey) { - var privkey = Uint8List.fromList(blame.privkey); - check(privkey.length == 32, 'bad blame privkey'); - var privkeyHexStr = - Util.bytesToHex(privkey); // Convert bytes to hex string. - var privkeyBigInt = - BigInt.parse(privkeyHexStr, radix: 16); // Convert hex string to BigInt. - var privateKey = ECPrivateKey(privkeyBigInt, params); // Create ECPrivateKey - var pubkeys = Util.pubkeysFromPrivkey(privkeyHexStr); - check(destCommit.communicationKey == pubkeys[1], 'bad blame privkey'); - try { - Encrypt.decrypt(encProof, privateKey); - } catch (e) { - return 'undecryptable'; - } - throw ValidationError('blame gave privkey but decryption worked'); - } else if (decrypter != pb.Blames_BlameProof_Decrypter.sessionKey) { - throw ValidationError('unknown blame decrypter'); - } - var key = Uint8List.fromList(blame.sessionKey); - check(key.length == 32, 'bad blame session key'); - Uint8List proofBlob; - try { - proofBlob = await Encrypt.decryptWithSymmkey(encProof, key); - } catch (e) { - throw ValidationError('bad blame session key'); - } - pb.InputComponent? inpComp; - try { - inpComp = validateProofInternal( - proofBlob, - srcCommit, - allComponents, - badComponents, - componentFeerate, - ); - } catch (e) { - return e.toString(); - } - - if (!blame.needLookupBlockchain) { - throw ValidationError( - 'blame indicated internal inconsistency, none found!'); - } - - if (inpComp == null) { - throw ValidationError( - 'blame indicated blockchain error on a non-input component'); - } - - return inpComp; -} diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index 55c675940..d221f9c50 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -1,9 +1,9 @@ import 'dart:io'; +import 'package:fusiondart/fusion.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; -import 'package:stackwallet/services/cashfusion/fusion.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; mixin FusionInterface { @@ -130,6 +130,7 @@ mixin FusionInterface { Future<void> refreshFusion() { // TODO - throw UnimplementedError("TODO refreshFusion eg look up number of fusion participants connected/coordinating"); + throw UnimplementedError( + "TODO refreshFusion eg look up number of fusion participants connected/coordinating"); } } diff --git a/pubspec.lock b/pubspec.lock index cfdf7a710..c8f7267b2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -761,6 +761,13 @@ packages: description: flutter source: sdk version: "0.0.0" + fusiondart: + dependency: "direct main" + description: + path: fusiondart + relative: true + source: path + version: "0.0.1" glob: dependency: transitive description: @@ -1870,5 +1877,5 @@ packages: source: hosted version: "1.0.0" sdks: - dart: ">=3.0.2 <4.0.0" + dart: ">=3.0.3 <4.0.0" flutter: ">=3.10.3" diff --git a/pubspec.yaml b/pubspec.yaml index d3c93e77a..08403e18a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -139,6 +139,9 @@ dependencies: nanodart: ^2.0.0 basic_utils: ^5.5.4 stellar_flutter_sdk: ^1.6.0 + fusiondart: + path: ./fusiondart + dev_dependencies: flutter_test: From 945c21934dfb8bef85c5e0b15478c3f8fefb7a0a Mon Sep 17 00:00:00 2001 From: Josh Babb <sneurlax@gmail.com> Date: Thu, 27 Jul 2023 16:04:39 -0500 Subject: [PATCH 019/379] update fusiondart submodule pub --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index ddf883749..d7e42820f 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit ddf883749bf72eab6d0c61ac123f728dc47ec91f +Subproject commit d7e42820f0511636c47dd91e9c4f425f5f9d5be3 From 0d3c98c83c3e3c47f5aa09422b92e838218a8a2d Mon Sep 17 00:00:00 2001 From: Josh Babb <sneurlax@gmail.com> Date: Thu, 27 Jul 2023 16:36:41 -0500 Subject: [PATCH 020/379] downgrade fusiondart protobuf package for conflict resolution purposes --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index d7e42820f..7f49176cc 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit d7e42820f0511636c47dd91e9c4f425f5f9d5be3 +Subproject commit 7f49176cc83348f4c8306388162c8675c490a4a4 From f1854aea7f98998b9ef9edf39ff0ece9126cd700 Mon Sep 17 00:00:00 2001 From: Josh Babb <sneurlax@gmail.com> Date: Thu, 27 Jul 2023 16:36:41 -0500 Subject: [PATCH 021/379] downgrade fusiondart protobuf package for conflict resolution purposes From a35ad753f10afca4549b0d123dbe7c249512e5f3 Mon Sep 17 00:00:00 2001 From: Josh Babb <sneurlax@gmail.com> Date: Thu, 27 Jul 2023 17:17:44 -0500 Subject: [PATCH 022/379] fix protobuf --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 7f49176cc..818afbe2b 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 7f49176cc83348f4c8306388162c8675c490a4a4 +Subproject commit 818afbe2b7b823aaf9fad107cc81f93fa1d8357a From 8e767d200ec62a72c88e95d0d9e64841f671243a Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 27 Jul 2023 17:13:03 -0600 Subject: [PATCH 023/379] use updated package --- fusiondart | 2 +- lib/services/mixins/fusion_interface.dart | 2 +- pubspec.lock | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fusiondart b/fusiondart index 818afbe2b..ec6b38956 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 818afbe2b7b823aaf9fad107cc81f93fa1d8357a +Subproject commit ec6b389562dee82e4d45e15d06c403726d70cb6c diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index d221f9c50..a9b6fd5f8 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -1,6 +1,6 @@ import 'dart:io'; -import 'package:fusiondart/fusion.dart'; +import 'package:fusiondart/fusiondart.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; diff --git a/pubspec.lock b/pubspec.lock index c8f7267b2..ea3437af5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -767,7 +767,7 @@ packages: path: fusiondart relative: true source: path - version: "0.0.1" + version: "1.0.0" glob: dependency: transitive description: @@ -1877,5 +1877,5 @@ packages: source: hosted version: "1.0.0" sdks: - dart: ">=3.0.3 <4.0.0" + dart: ">=3.0.6 <4.0.0" flutter: ">=3.10.3" From f9fa0acb8c29fea4df964f31d7b15045147da304 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 27 Jul 2023 17:23:25 -0600 Subject: [PATCH 024/379] pass in only required utxo data --- fusiondart | 2 +- lib/services/mixins/fusion_interface.dart | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fusiondart b/fusiondart index ec6b38956..c643a1794 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit ec6b389562dee82e4d45e15d06c403726d70cb6c +Subproject commit c643a17948a3ceedb2e21d111cc5d4d4e7d8d6f4 diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index a9b6fd5f8..1d18b8f04 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -27,7 +27,9 @@ mixin FusionInterface { // await _updateUTXOs(); List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); Fusion mainFusionObject = Fusion(); - await mainFusionObject.add_coins_from_wallet(utxos); + await mainFusionObject.add_coins_from_wallet(utxos + .map((e) => (txid: e.txid, vout: e.vout, value: e.value)) + .toList()); await mainFusionObject.fusion_run(); //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); From 848a6ea1be860879feea3dfbdba5eff274f126a0 Mon Sep 17 00:00:00 2001 From: Josh Babb <sneurlax@gmail.com> Date: Fri, 28 Jul 2023 13:27:42 -0500 Subject: [PATCH 025/379] fusiondart#no_flutter --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index c643a1794..b91f205c4 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit c643a17948a3ceedb2e21d111cc5d4d4e7d8d6f4 +Subproject commit b91f205c4b5b60e2a597e5eadf4fc927268c3a13 From 9353867f6cac31b33bd9c8916a9088aad7e8e650 Mon Sep 17 00:00:00 2001 From: Josh Babb <sneurlax@gmail.com> Date: Tue, 1 Aug 2023 11:01:05 -0500 Subject: [PATCH 026/379] update fusiondart package --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index b91f205c4..fb04c5ca5 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit b91f205c4b5b60e2a597e5eadf4fc927268c3a13 +Subproject commit fb04c5ca572cbbefdcc3ed2070b7be36b040355b From 387e4ba99c31759035cd8f314997fa0d95c9a4e8 Mon Sep 17 00:00:00 2001 From: Jonald Fyookball <jonaldfyookball@outlook.com> Date: Thu, 3 Aug 2023 08:50:28 -0400 Subject: [PATCH 027/379] update fusion.dart to get to runround stage --- lib/services/cashfusion/fusion.dart | 95 ++++++++++++++++------------- 1 file changed, 52 insertions(+), 43 deletions(-) diff --git a/lib/services/cashfusion/fusion.dart b/lib/services/cashfusion/fusion.dart index ecef0f855..c3bf2bc55 100644 --- a/lib/services/cashfusion/fusion.dart +++ b/lib/services/cashfusion/fusion.dart @@ -204,7 +204,7 @@ class Fusion { Map<int, int> safety_exess_fees = {}; Map<int, List<int>> tierOutputs ={}; // not sure if this should be using outputs class. - int inactiveTimeLimit = 0; + int inactiveTimeLimit = 600000; // this is in ms... equates to 10 minutes. int tier = 0; int covertPort = 0; bool covertSSL = false; @@ -322,18 +322,13 @@ class Fusion { await registerAndWait(socketwrapper); - print ("FUSION DEBUG 273"); - print ("RETURNING early in fusion_run...."); - return; - - // launch the covert submitter - CovertSubmitter covert = await start_covert(); + CovertSubmitter covert = await startCovert(); try { // Pool started. Keep running rounds until fail or complete. while (true) { roundcount += 1; - if (await run_round(covert)) { + if (await runRound(covert)) { break; } } @@ -344,6 +339,9 @@ class Fusion { (await connection)?.close(); } + print ("RETURNING early in fusion_run...."); + return; + for (int i = 0; i < 60; i++) { if (stopping) { break; // not an error @@ -389,20 +387,6 @@ class Fusion { - Future<CovertSubmitter> start_covert() async { - // Function implementation here... - - // For now, just return a new instance of CovertSubmitter - return CovertSubmitter("dummy",0,true,"some_host",0,0,0,0); - } - - - Future<bool> run_round(CovertSubmitter covert) async { - // function implementation here... - - // placeholder return statement - return Future.value(false); - } void notify_server_status(bool b, {Tuple? tup}) { // Function implementation goes here @@ -823,7 +807,7 @@ static double nextDoubleNonZero(Random rng) { Future<void> registerAndWait(SocketWrapper socketwrapper) async { - print ("DEBUG register and wait top."); + var stopwatch = Stopwatch()..start(); // msg can be different classes depending on which protobuf msg is sent. dynamic? msg; @@ -865,11 +849,10 @@ static double nextDoubleNonZero(Random rng) { var tiersStrings = {for (var entry in tierOutputs.entries) entry.key: (entry.key * 1e-8).toStringAsFixed(8).replaceAll(RegExp(r'0+$'), '')}; while (true) { - print ("RECEIVE LOOP 870............DEBUG"); - var msg = await recv2(socketwrapper,['tierstatusupdate', 'fusionbegin'], timeout: Duration(seconds: 10)); - + msg = await recv2(socketwrapper,['tierstatusupdate', 'fusionbegin'], timeout: Duration(seconds: 10)); var fieldInfoFusionBegin = msg.info_.byName["fusionbegin"]; if (fieldInfoFusionBegin != null && msg.hasField(fieldInfoFusionBegin.tagNumber)) { + print ("DEBUG 867 Fusion Begin message..."); break; } @@ -886,7 +869,7 @@ static double nextDoubleNonZero(Random rng) { } bool messageIsTierStatusUpdate = msg.hasField(fieldInfo.tagNumber); - + print ("DEBUG 889 getting tier update."); if (!messageIsTierStatusUpdate) { throw FusionError('Expected a TierStatusUpdate message'); @@ -915,12 +898,8 @@ static double nextDoubleNonZero(Random rng) { } var fieldInfoTimeRemaining = entry.value.info_.byName["timeRemaining"]; - if (fieldInfoTimeRemaining == null) { - throw FusionError('Expected field not found in message: timeRemaining'); - } if (entry.value.hasField(fieldInfoTimeRemaining.tagNumber)) { - int tr = entry.value.timeRemaining.toInt(); if (besttime == null || tr < besttime) { besttime = tr; @@ -933,7 +912,9 @@ static double nextDoubleNonZero(Random rng) { var displayBest = <String>[]; var displayMid = <String>[]; var displayQueued = <String>[]; + for (var tier in tiersSorted) { + if (statuses.containsKey(tier)) { var tierStr = tiersStrings[tier]; if (tierStr == null) { @@ -951,6 +932,7 @@ static double nextDoubleNonZero(Random rng) { } } + var parts = <String>[]; if (displayBest.isNotEmpty || displayMid.isNotEmpty) { parts.add("Tiers: ${displayBest.join(', ')} ${displayMid.join(', ')}"); @@ -961,11 +943,16 @@ static double nextDoubleNonZero(Random rng) { var tiersString = parts.join(' '); if (besttime == null && inactiveTimeLimit != null) { - if (DateTime.now().millisecondsSinceEpoch > inactiveTimeLimit) { + if (stopwatch.elapsedMilliseconds > inactiveTimeLimit) { throw FusionError('stopping due to inactivity'); + } else { + ; } + } else { + ; } + if (besttime != null) { status = Tuple<String, String>('waiting', 'Starting in ${besttime}s. $tiersString'); } else if (maxfraction >= 1) { @@ -977,35 +964,47 @@ static double nextDoubleNonZero(Random rng) { } } + + var fieldInfoFusionBegin = msg.info_.byName["fusionbegin"]; + +// Check if fieldInfoFusionBegin is null if (fieldInfoFusionBegin == null) { throw FusionError('Expected field not found in message: fusionbegin'); } bool messageIsFusionBegin = msg.hasField(fieldInfoFusionBegin.tagNumber); + +// Print whether the message is FusionBegin or not if (!messageIsFusionBegin) { throw FusionError('Expected a FusionBegin message'); } - t_fusionBegin = DateTime.now(); + FusionBegin fusionBeginMsg = msg.fusionbegin; - var clockMismatch = msg.serverTime - DateTime.now().millisecondsSinceEpoch / 1000; - if (clockMismatch.abs() > Protocol.MAX_CLOCK_DISCREPANCY) { - throw FusionError("Clock mismatch too large: ${clockMismatch.toStringAsFixed(3)}."); + var elapsedSeconds = (stopwatch.elapsedMilliseconds / 1000).toInt(); + var clockMismatch = fusionBeginMsg.serverTime.toInt() - DateTime.now().millisecondsSinceEpoch / 1000; + + + + if (clockMismatch.abs().toDouble() > Protocol.MAX_CLOCK_DISCREPANCY) { + throw FusionError("Clock mismatch too large: ${(clockMismatch.toDouble()).toStringAsFixed(3)}."); } - tier = msg.tier; + + tier = fusionBeginMsg.tier.toInt(); + if (msg is FusionBegin) { covertDomainB = Uint8List.fromList(msg.covertDomain); } - covertPort = msg.covertPort; - covertSSL = msg.covertSSL; - beginTime = msg.serverTime; + covertPort = fusionBeginMsg.covertPort; + covertSSL = fusionBeginMsg.covertSsl; + beginTime = fusionBeginMsg.serverTime.toDouble(); lastHash = Util.calcInitialHash(tier, covertDomainB, covertPort, covertSSL, beginTime); @@ -1021,8 +1020,11 @@ static double nextDoubleNonZero(Random rng) { } Future<CovertSubmitter> startCovert() async { + + print ("DEBUG START COVERT!"); status = Tuple('running', 'Setting up Tor connections'); + String covertDomain; try { covertDomain = utf8.decode(covertDomainB); @@ -1047,6 +1049,8 @@ static double nextDoubleNonZero(Random rng) { connectTimeout: Protocol.COVERT_CONNECT_TIMEOUT.toInt() ); + print ("DEBUG return early from covert"); + return covert; // loop until a just a bit before we're expecting startRound, watching for status updates final tend = t_fusionBegin.add(Duration(seconds: (Protocol.WARMUP_TIME - Protocol.WARMUP_SLOP - 1).round())); @@ -1074,7 +1078,9 @@ static double nextDoubleNonZero(Random rng) { } - void runRound(CovertSubmitter covert) async { + Future<bool> runRound(CovertSubmitter covert) async { + print ("START OF RUN ROUND"); + status = Tuple('running', 'Starting round ${roundcount.toString()}'); int timeoutInSeconds = (2 * Protocol.WARMUP_SLOP + Protocol.STANDARD_TIMEOUT).toInt(); var msg = await recv(['startround'], timeout: Duration(seconds: timeoutInSeconds)); @@ -1158,6 +1164,9 @@ static double nextDoubleNonZero(Random rng) { final blindSigRequests = blindNoncePoints.map((e) => Schnorr.BlindSignatureRequest(roundPubKey, e, sha256(myComponents.elementAt(e)))).toList(); */ + print ("RETURNING EARLY FROM run round ....."); + return true; + final randomNumber = Util.getRandomBytes(32); covert.checkOk(); check_stop(); @@ -1581,8 +1590,8 @@ static double nextDoubleNonZero(Random rng) { // itself needs to check blockchain. await recv(['restartround'], timeout: Duration(seconds: 2 * (Protocol.STANDARD_TIMEOUT.round() + Protocol.BLAME_VERIFY_TIME.round()))); - - } // end of run_round() function. + return true; + } // end of runRound() function. From a2a34ce459aaf16212c548360c3d5cb1cb210b84 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sun, 6 Aug 2023 20:07:30 -0500 Subject: [PATCH 028/379] update fusiondart package to track fyookball/stack_wallet#fusion 387e4ba9 --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index fb04c5ca5..58f18edde 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit fb04c5ca572cbbefdcc3ed2070b7be36b040355b +Subproject commit 58f18eddee78be0ee393a23d03ccba94e252d8cf From 2692ebfc68137bb00f2a243690d2d71a40af7da3 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sun, 6 Aug 2023 21:15:05 -0500 Subject: [PATCH 029/379] WIP demo get current receiving address --- .../coins/bitcoincash/bitcoincash_wallet.dart | 6 +++- lib/services/mixins/fusion_interface.dart | 28 ++++++++++++++++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 6415f6693..ea2341ffd 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -134,7 +134,11 @@ class BitcoinCashWallet extends CoinServiceAPI _secureStore = secureStore; initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); - initFusionInterface(walletId: walletId, coin: coin, db: db); + initFusionInterface( + walletId: walletId, + coin: coin, + db: db, + getCurrentChangeAddress: () => currentChangeAddress); initCoinControlInterface( walletId: walletId, walletName: walletName, diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index 1d18b8f04..da5592d8d 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -3,37 +3,57 @@ import 'dart:io'; import 'package:fusiondart/fusiondart.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/address.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/logger.dart'; mixin FusionInterface { + // passed in wallet data late final String _walletId; late final Coin _coin; late final MainDB _db; + // passed in wallet functions + late final Future<String> Function() _getCurrentChangeAddress; + void initFusionInterface({ required String walletId, required Coin coin, required MainDB db, + required Future<String> Function() getCurrentChangeAddress, }) { _walletId = walletId; _coin = coin; _db = db; + _getCurrentChangeAddress = getCurrentChangeAddress; } void fuse() async { // Initial attempt for CashFusion integration goes here. - - // await _updateUTXOs(); - List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); Fusion mainFusionObject = Fusion(); + + // add stack utxos + List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); await mainFusionObject.add_coins_from_wallet(utxos .map((e) => (txid: e.txid, vout: e.vout, value: e.value)) .toList()); + + // add stack change address + final String currentChangeAddress = await _getCurrentChangeAddress(); + // await mainFusionObject.addChangeAddress(currentChangeAddress); + final Address? changeAddress = + await _db.getAddress(_walletId, currentChangeAddress); + Logging.instance.log( + "FusionInterface fuse() changeAddress: $changeAddress", + level: LogLevel.Info, + ); + + // fuse utxos await mainFusionObject.fusion_run(); //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); -/* + /* print("DEBUG: Waiting for any potential incoming data..."); try { await Future.delayed(Duration(seconds: 5)); // wait for 5 seconds From 6246b6c931dcd97bf762af81e8eba411680cdc60 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sun, 6 Aug 2023 22:02:40 -0500 Subject: [PATCH 030/379] refactor CashFusion Address model and add toFusionAddress method to go from Stack Address -> CashFusion Address --- fusiondart | 2 +- lib/models/isar/models/blockchain_data/address.dart | 13 +++++++++++++ lib/services/mixins/fusion_interface.dart | 7 ++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/fusiondart b/fusiondart index 58f18edde..b4209c152 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 58f18eddee78be0ee393a23d03ccba94e252d8cf +Subproject commit b4209c1523cf53d9db805ce0924e6902c716c0f3 diff --git a/lib/models/isar/models/blockchain_data/address.dart b/lib/models/isar/models/blockchain_data/address.dart index 028bee04a..630b61a57 100644 --- a/lib/models/isar/models/blockchain_data/address.dart +++ b/lib/models/isar/models/blockchain_data/address.dart @@ -10,6 +10,7 @@ import 'dart:convert'; +import 'package:fusiondart/src/models/address.dart' as FusionAddress; import 'package:isar/isar.dart'; import 'package:stackwallet/exceptions/address/address_exception.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/crypto_currency_address.dart'; @@ -212,3 +213,15 @@ class DerivationPath { @override int get hashCode => value.hashCode; } + +extension ToFusionAddress on Address { + FusionAddress.Address toFusionAddress() { + return FusionAddress.Address( + addr: value, + id: id.toString(), // Assuming id can be converted to a String + publicKey: + publicKey, // Assuming List<byte> and List<int> are compatible + derivationPath: + FusionAddress.DerivationPath(derivationPath?.value ?? "")); + } +} diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index da5592d8d..fc721d781 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:fusiondart/fusiondart.dart'; +import 'package:fusiondart/src/models/address.dart' as fusion_address; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/address.dart'; @@ -41,9 +42,13 @@ mixin FusionInterface { // add stack change address final String currentChangeAddress = await _getCurrentChangeAddress(); - // await mainFusionObject.addChangeAddress(currentChangeAddress); + // cast from String to Address final Address? changeAddress = await _db.getAddress(_walletId, currentChangeAddress); + // cast from Stack's Address to Fusiondart's Address + final fusion_address.Address fusionChangeAddress = + changeAddress!.toFusionAddress(); + await mainFusionObject.addChangeAddress(fusionChangeAddress); Logging.instance.log( "FusionInterface fuse() changeAddress: $changeAddress", level: LogLevel.Info, From c620a5e23a9a7e1012f91d996450bdd558942408 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sun, 6 Aug 2023 22:57:34 -0500 Subject: [PATCH 031/379] WIP nextChangeAddress WIP move reserve_change_addresses(int addresses) to fusion interface --- fusiondart | 2 +- .../coins/bitcoincash/bitcoincash_wallet.dart | 28 +++++++++++++++---- lib/services/mixins/fusion_interface.dart | 12 ++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/fusiondart b/fusiondart index b4209c152..ad107a683 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit b4209c1523cf53d9db805ce0924e6902c716c0f3 +Subproject commit ad107a683cfdf72040270921062fc6f43ae63f6b diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index ea2341ffd..e0e6b095c 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -26,7 +26,8 @@ import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/balance.dart'; -import 'package:stackwallet/models/isar/models/blockchain_data/address.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/address.dart' + as stack_address; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/models/signing_data.dart'; @@ -197,8 +198,25 @@ class BitcoinCashWallet extends CoinServiceAPI .findFirst()) ?? await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); - Future<String> get currentChangeAddress async => - (await _currentChangeAddress).value; + Future<String> get currentChangeAddress async => (await _currentChangeAddress) + .value; // could return Address to cast Stack's Address to Fusiondart's Address like `(await _currentChangeAddress).toFusionAddress();` + + Future<String> get nextChangeAddress async { + // get change <Address> + final currentChange = await _currentChangeAddress; + // use <Address>.derivationmIndex + 1 to get next change address derivation path + final int nextChangeIndex = currentChange.derivationIndex + 1; + // generate next change address + final stack_address.Address newChangeAddress = + await _generateAddressForChain( + 1, + nextChangeIndex, + DerivePathTypeExt.primaryFor( + coin)); // may need to pick other derive path type, eg 44, 49, 84 + + return newChangeAddress + .value; // could return Address to cast Stack's Address to Fusiondart's Address like `newChangeAddress.toFusionAddress();` + } Future<isar_models.Address> get _currentChangeAddress async => (await db @@ -2147,10 +2165,10 @@ class BitcoinCashWallet extends CoinServiceAPI walletId: walletId, value: possible, publicKey: [], - type: AddressType.nonWallet, + type: stack_address.AddressType.nonWallet, derivationIndex: -1, derivationPath: null, - subType: AddressSubType.nonWallet, + subType: stack_address.AddressSubType.nonWallet, ); } } else { diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index fc721d781..dcab0096e 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -30,6 +30,18 @@ mixin FusionInterface { _getCurrentChangeAddress = getCurrentChangeAddress; } + static List<Address> reserve_change_addresses(int number_addresses) { + // TODO + // get current change address + // get int number_addresses next addresses + return []; + } + + static List<Address> unreserve_change_address(Address addr) { + //implement later based on wallet. + return []; + } + void fuse() async { // Initial attempt for CashFusion integration goes here. Fusion mainFusionObject = Fusion(); From e00208b0f07500d0d0d29dcd0a5698b632bcad87 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 7 Aug 2023 13:06:41 -0500 Subject: [PATCH 032/379] remove id from fusion address model --- lib/models/isar/models/blockchain_data/address.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/models/isar/models/blockchain_data/address.dart b/lib/models/isar/models/blockchain_data/address.dart index 630b61a57..17576fbec 100644 --- a/lib/models/isar/models/blockchain_data/address.dart +++ b/lib/models/isar/models/blockchain_data/address.dart @@ -218,7 +218,6 @@ extension ToFusionAddress on Address { FusionAddress.Address toFusionAddress() { return FusionAddress.Address( addr: value, - id: id.toString(), // Assuming id can be converted to a String publicKey: publicKey, // Assuming List<byte> and List<int> are compatible derivationPath: From 221c4e3fb74203b2386390002a9d497ded656692 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 7 Aug 2023 13:07:34 -0500 Subject: [PATCH 033/379] WIP pass address generation function in --- fusiondart | 2 +- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 3 ++- lib/services/mixins/fusion_interface.dart | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/fusiondart b/fusiondart index ad107a683..c021a3e8f 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit ad107a683cfdf72040270921062fc6f43ae63f6b +Subproject commit c021a3e8fb815850de6ef655da360acfde34acf2 diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index e0e6b095c..cf2fcf91f 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -139,7 +139,8 @@ class BitcoinCashWallet extends CoinServiceAPI walletId: walletId, coin: coin, db: db, - getCurrentChangeAddress: () => currentChangeAddress); + getCurrentChangeAddress: () => currentChangeAddress, + getNextChangeAddress: () => nextChangeAddress); initCoinControlInterface( walletId: walletId, walletName: walletName, diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index dcab0096e..8579d3a11 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -17,17 +17,20 @@ mixin FusionInterface { // passed in wallet functions late final Future<String> Function() _getCurrentChangeAddress; + late final Future<String> Function() _getNextChangeAddress; void initFusionInterface({ required String walletId, required Coin coin, required MainDB db, required Future<String> Function() getCurrentChangeAddress, + required Future<String> Function() getNextChangeAddress, }) { _walletId = walletId; _coin = coin; _db = db; _getCurrentChangeAddress = getCurrentChangeAddress; + _getNextChangeAddress = getNextChangeAddress; } static List<Address> reserve_change_addresses(int number_addresses) { @@ -44,7 +47,8 @@ mixin FusionInterface { void fuse() async { // Initial attempt for CashFusion integration goes here. - Fusion mainFusionObject = Fusion(); + Fusion mainFusionObject = + Fusion(generateChangeAddress: () => _getNextChangeAddress()); // add stack utxos List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); From 6bbca5160e81e62d8ea2377d30b1c91d33701240 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 7 Aug 2023 13:06:55 -0500 Subject: [PATCH 034/379] WIP pass address generation function in --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index c021a3e8f..ad107a683 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit c021a3e8fb815850de6ef655da360acfde34acf2 +Subproject commit ad107a683cfdf72040270921062fc6f43ae63f6b From 5fc3f237790231e4aa4a67abc0375261a9436abc Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 7 Aug 2023 13:16:06 -0500 Subject: [PATCH 035/379] patch fusiondart to runnable state --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index ad107a683..79e435cfe 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit ad107a683cfdf72040270921062fc6f43ae63f6b +Subproject commit 79e435cfe1e099efd5b2ac39c8b8ed3d83fd8c50 From cdbbb0a3df295013140ee45605af777dc9cb4d6e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 7 Aug 2023 12:53:18 -0600 Subject: [PATCH 036/379] add copyWith to Address --- .../isar/models/blockchain_data/address.dart | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/models/isar/models/blockchain_data/address.dart b/lib/models/isar/models/blockchain_data/address.dart index 17576fbec..3200058b1 100644 --- a/lib/models/isar/models/blockchain_data/address.dart +++ b/lib/models/isar/models/blockchain_data/address.dart @@ -71,6 +71,29 @@ class Address extends CryptoCurrencyAddress { subType == AddressSubType.paynymSend || subType == AddressSubType.paynymReceive; + Address copyWith({ + String? walletId, + String? value, + List<byte>? publicKey, + int? derivationIndex, + AddressType? type, + AddressSubType? subType, + DerivationPath? derivationPath, + String? otherData, + }) { + return Address( + walletId: walletId ?? this.walletId, + value: value ?? this.value, + publicKey: publicKey ?? this.publicKey, + derivationIndex: derivationIndex ?? this.derivationIndex, + type: type ?? this.type, + subType: subType ?? this.subType, + derivationPath: derivationPath ?? this.derivationPath, + otherData: otherData ?? this.otherData, + ); + } + + @override String toString() => "{ " "id: $id, " From e4aa34509a9bdae41b9ca82ff1c1b1f3fb712da0 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 7 Aug 2023 12:54:44 -0600 Subject: [PATCH 037/379] WIP reserve addresses stuff --- .../coins/bitcoincash/bitcoincash_wallet.dart | 18 ++-- lib/services/mixins/fusion_interface.dart | 89 +++++++++++++++---- 2 files changed, 84 insertions(+), 23 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index cf2fcf91f..3a6afbeed 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -136,11 +136,11 @@ class BitcoinCashWallet extends CoinServiceAPI initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); initFusionInterface( - walletId: walletId, - coin: coin, - db: db, - getCurrentChangeAddress: () => currentChangeAddress, - getNextChangeAddress: () => nextChangeAddress); + walletId: walletId, + coin: coin, + db: db, + generateAddressForChain: _generateAddressForChain, + ); initCoinControlInterface( walletId: walletId, walletName: walletName, @@ -1569,6 +1569,8 @@ class BitcoinCashWallet extends CoinServiceAPI .typeEqualTo(type) .subTypeEqualTo(subType) .derivationPath((q) => q.valueStartsWith("m/$purpose'/$coinType")) + .not() + .otherDataEqualTo(kReservedFusionAddress) .sortByDerivationIndexDesc() .findFirst(); return address!.value; @@ -1829,8 +1831,10 @@ class BitcoinCashWallet extends CoinServiceAPI // Add that new change address await db.putAddress(newChangeAddress); } else { - // we need to update the address - await db.updateAddress(existing, newChangeAddress); + if (existing.otherData != kReservedFusionAddress) { + // we need to update the address + await db.updateAddress(existing, newChangeAddress); + } } // keep checking until address with no tx history is set as current await _checkChangeAddressForTransactions(); diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index 8579d3a11..b355f5028 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -4,11 +4,13 @@ import 'package:fusiondart/fusiondart.dart'; import 'package:fusiondart/src/models/address.dart' as fusion_address; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; -import 'package:stackwallet/models/isar/models/blockchain_data/address.dart'; -import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/logger.dart'; +const String kReservedFusionAddress = "reserved_fusion_address"; + mixin FusionInterface { // passed in wallet data late final String _walletId; @@ -16,33 +18,88 @@ mixin FusionInterface { late final MainDB _db; // passed in wallet functions - late final Future<String> Function() _getCurrentChangeAddress; - late final Future<String> Function() _getNextChangeAddress; + late final Future<Address> Function( + int chain, + int index, + DerivePathType derivePathType, + ) _generateAddressForChain; void initFusionInterface({ required String walletId, required Coin coin, required MainDB db, - required Future<String> Function() getCurrentChangeAddress, - required Future<String> Function() getNextChangeAddress, + required Future<Address> Function( + int, + int, + DerivePathType, + ) generateAddressForChain, }) { _walletId = walletId; _coin = coin; _db = db; - _getCurrentChangeAddress = getCurrentChangeAddress; - _getNextChangeAddress = getNextChangeAddress; + _generateAddressForChain = generateAddressForChain; } - static List<Address> reserve_change_addresses(int number_addresses) { - // TODO - // get current change address - // get int number_addresses next addresses - return []; + Future<Address> createNewReservedChangeAddress() async { + int? highestChangeIndex = await _db + .getAddresses(_walletId) + .filter() + .typeEqualTo(AddressType.p2pkh) + .subTypeEqualTo(AddressSubType.change) + .derivationPath((q) => q.not().valueStartsWith("m/44'/0'")) + .sortByDerivationIndexDesc() + .derivationIndexProperty() + .findFirst(); + + Address address = await _generateAddressForChain( + 1, // change chain + highestChangeIndex ?? 0, + DerivePathTypeExt.primaryFor(_coin), + ); + address = address.copyWith(otherData: kReservedFusionAddress); + + // TODO if we really want to be sure its not used, call electrumx and check it + + await _db.putAddress(address); + + return address; } - static List<Address> unreserve_change_address(Address addr) { - //implement later based on wallet. - return []; + Future<List<Address>> getUnusedReservedChangeAddresses( + int numberOfAddresses, + ) async { + final txns = await _db + .getTransactions(_walletId) + .filter() + .address((q) => q.otherDataEqualTo(kReservedFusionAddress)) + .findAll(); + + final List<String> usedAddresses = txns + .where((e) => e.address.value != null) + .map((e) => e.address.value!.value) + .toList(growable: false); + + final List<Address> addresses = await _db + .getAddresses(_walletId) + .filter() + .otherDataEqualTo(kReservedFusionAddress) + .findAll(); + + final List<Address> unusedAddresses = []; + + for (final address in addresses) { + if (!usedAddresses.contains(address.value)) { + unusedAddresses.add(address); + } + } + + if (unusedAddresses.length < numberOfAddresses) { + for (int i = unusedAddresses.length; i < numberOfAddresses; i++) { + unusedAddresses.add(await createNewReservedChangeAddress()); + } + } + + return unusedAddresses; } void fuse() async { From 32c0c558304feb7279509c5901d1a7487117eeb9 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 7 Aug 2023 14:15:08 -0500 Subject: [PATCH 038/379] WIP generateChangeAddress->createNewReservedChangeAddress --- fusiondart | 2 +- lib/services/mixins/fusion_interface.dart | 38 +++++++++++------------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/fusiondart b/fusiondart index 79e435cfe..20bf6d3c6 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 79e435cfe1e099efd5b2ac39c8b8ed3d83fd8c50 +Subproject commit 20bf6d3c671f50b43831bbf29c62763ae65af3fe diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index b355f5028..bbf425ea6 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -1,13 +1,12 @@ import 'dart:io'; import 'package:fusiondart/fusiondart.dart'; -import 'package:fusiondart/src/models/address.dart' as fusion_address; +import 'package:fusiondart/src/models/address.dart' as cash_fusion; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; -import 'package:stackwallet/utilities/logger.dart'; const String kReservedFusionAddress = "reserved_fusion_address"; @@ -40,7 +39,7 @@ mixin FusionInterface { _generateAddressForChain = generateAddressForChain; } - Future<Address> createNewReservedChangeAddress() async { + Future<cash_fusion.Address> createNewReservedChangeAddress() async { int? highestChangeIndex = await _db .getAddresses(_walletId) .filter() @@ -62,7 +61,7 @@ mixin FusionInterface { await _db.putAddress(address); - return address; + return address.toFusionAddress(); } Future<List<Address>> getUnusedReservedChangeAddresses( @@ -104,8 +103,8 @@ mixin FusionInterface { void fuse() async { // Initial attempt for CashFusion integration goes here. - Fusion mainFusionObject = - Fusion(generateChangeAddress: () => _getNextChangeAddress()); + Fusion mainFusionObject = Fusion( + createNewReservedChangeAddress: () => createNewReservedChangeAddress()); // add stack utxos List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); @@ -113,19 +112,20 @@ mixin FusionInterface { .map((e) => (txid: e.txid, vout: e.vout, value: e.value)) .toList()); - // add stack change address - final String currentChangeAddress = await _getCurrentChangeAddress(); - // cast from String to Address - final Address? changeAddress = - await _db.getAddress(_walletId, currentChangeAddress); - // cast from Stack's Address to Fusiondart's Address - final fusion_address.Address fusionChangeAddress = - changeAddress!.toFusionAddress(); - await mainFusionObject.addChangeAddress(fusionChangeAddress); - Logging.instance.log( - "FusionInterface fuse() changeAddress: $changeAddress", - level: LogLevel.Info, - ); + // TODO rework + // // add stack change address + // final String currentChangeAddress = await _getCurrentChangeAddress(); + // // cast from String to Address + // final Address? changeAddress = + // await _db.getAddress(_walletId, currentChangeAddress); + // // cast from Stack's Address to Fusiondart's Address + // final fusion_address.Address fusionChangeAddress = + // changeAddress!.toFusionAddress(); + // await mainFusionObject.addChangeAddress(fusionChangeAddress); + // Logging.instance.log( + // "FusionInterface fuse() changeAddress: $changeAddress", + // level: LogLevel.Info, + // ); // fuse utxos await mainFusionObject.fusion_run(); From 8eef870375d57653ca75f9c3232d97a801e967a8 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 7 Aug 2023 14:29:56 -0500 Subject: [PATCH 039/379] type disambiguation --- lib/services/mixins/fusion_interface.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index bbf425ea6..5ee14b93e 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -64,7 +64,7 @@ mixin FusionInterface { return address.toFusionAddress(); } - Future<List<Address>> getUnusedReservedChangeAddresses( + Future<List<cash_fusion.Address>> getUnusedReservedChangeAddresses( int numberOfAddresses, ) async { final txns = await _db @@ -84,11 +84,11 @@ mixin FusionInterface { .otherDataEqualTo(kReservedFusionAddress) .findAll(); - final List<Address> unusedAddresses = []; + final List<cash_fusion.Address> unusedAddresses = []; for (final address in addresses) { if (!usedAddresses.contains(address.value)) { - unusedAddresses.add(address); + unusedAddresses.add(address.toFusionAddress()); } } From 80ddbe2b200b7c3afd29b64895706cad2c9ab6ca Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 7 Aug 2023 14:39:46 -0500 Subject: [PATCH 040/379] implement reserve_change_addresses as _getUnusedReservedChangeAddresses and remove orphaned lib/services/cashfusion/fusion.dart --- fusiondart | 2 +- lib/services/cashfusion/fusion.dart | 1600 --------------------------- 2 files changed, 1 insertion(+), 1601 deletions(-) delete mode 100644 lib/services/cashfusion/fusion.dart diff --git a/fusiondart b/fusiondart index 20bf6d3c6..90f4b458f 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 20bf6d3c671f50b43831bbf29c62763ae65af3fe +Subproject commit 90f4b458f3883c0a381e0e6337b2ab462c2a1fac diff --git a/lib/services/cashfusion/fusion.dart b/lib/services/cashfusion/fusion.dart deleted file mode 100644 index c3bf2bc55..000000000 --- a/lib/services/cashfusion/fusion.dart +++ /dev/null @@ -1,1600 +0,0 @@ -import 'socketwrapper.dart'; -import 'package:protobuf/protobuf.dart'; -import 'dart:convert'; -import 'dart:math'; -import 'fusion.pb.dart'; -import 'util.dart'; -import 'dart:typed_data'; -import 'package:fixnum/fixnum.dart'; -import 'pedersen.dart'; -import 'dart:io'; -import 'package:crypto/crypto.dart'; -import 'dart:async'; -import 'comms.dart'; -import 'protocol.dart'; -import 'package:fixnum/fixnum.dart'; // so int and intt64 can be combined in some protobuff code -import 'encrypt.dart'; -import "package:pointycastle/export.dart"; -import 'covert.dart'; -import 'connection.dart'; -import 'package:collection/collection.dart'; -import 'package:convert/convert.dart'; -import 'validation.dart'; -import 'package:stackwallet/models/isar/models/blockchain_data/utxo.dart'; - - -class FusionError implements Exception { - final String message; - FusionError(this.message); - String toString() => "FusionError: $message"; -} - -class ComponentResult { - final Uint8List commitment; - final int counter; - final Uint8List component; - final Proof proof; - final Uint8List privateKey; - final dynamic pedersenAmount; // replace dynamic with actual type - final dynamic pedersenNonce; // replace dynamic with actual type - - ComponentResult( - this.commitment, - this.counter, - this.component, - this.proof, - this.privateKey, - {this.pedersenAmount, - this.pedersenNonce} - ); -} - -class Transaction { - List<Input> Inputs = []; - List<Output> Outputs = []; - - Transaction(); - - - static Tuple txFromComponents(List<dynamic> allComponents, List<dynamic> sessionHash) { - Transaction tx = Transaction(); // Initialize a new Transaction - // This should be based on wallet layer... implement the logic of constructing the transaction from components - // For now, it just initializes Inputs and Outputs as empty lists - tx.Inputs = []; - tx.Outputs = []; - - // For now, just returning an empty list for inputIndices - List<int> inputIndices = []; - - return Tuple(tx, inputIndices); - } - - List<int> serializePreimage(int index, int hashType, {bool useCache = true}) { - // Add implementation here - // For now, returning an empty byte array - return []; - } - - String serialize() { - // To implement... - return ""; - } - - bool isComplete() { - // implement based on wallet. - return true; - } - - String txid() { - // To implement... - return ""; - } -} - - -class Input { - List<int> prevTxid; - int prevIndex; - List<int> pubKey; - int amount; - List<dynamic> signatures =[]; - - Input({required this.prevTxid, required this.prevIndex, required this.pubKey, required this.amount}); - - int sizeOfInput() { - assert(1 < pubKey.length && pubKey.length < 76); // need to assume regular push opcode - return 108 + pubKey.length; - } - - int get value { - return amount; - } - - String getPubKey(int pubkey_index) { - // TO BE IMPLEMENTED... - return ""; - } - - String getPrivKey(int pubkey_index) { - // TO BE IMPLEMENTED... - return ""; - } - - - static Input fromInputComponent(InputComponent inputComponent) { - return Input( - prevTxid: inputComponent.prevTxid, // Make sure the types are matching - prevIndex: inputComponent.prevIndex.toInt(), - pubKey: inputComponent.pubkey, - amount: inputComponent.amount.toInt(), - ); - } - - static Input fromStackUTXO(UTXO utxo) { - return Input( - prevTxid: utf8.encode(utxo.txid), // Convert txid to a List<int> - prevIndex: utxo.vout, - pubKey: utf8.encode('0000'), // Placeholder - amount: utxo.value, - ); - } - -} - - - -class Output { - int value; - Address addr; - - int amount=0; - - Output({required this.value, required this.addr}); - - int sizeOfOutput() { - List<int> scriptpubkey = addr.toScript(); // assuming addr.toScript() returns List<int> that represents the scriptpubkey - assert(scriptpubkey.length < 253); - return 9 + scriptpubkey.length; - } - - static Output fromOutputComponent(OutputComponent outputComponent) { - Address address = Address.fromScriptPubKey(outputComponent.scriptpubkey); - return Output( - value: outputComponent.amount.toInt(), - addr: address, - ); - } - -} - - - -// Class to handle fusion -class Fusion { - - List<Input> coins = []; //"coins" and "inputs" are often synonmous in the original python code. - List<Output> outputs =[]; - bool server_connected_and_greeted = false; - bool stopping = false; - bool stopping_if_not_running = false; - String stopReason=""; - String tor_host=""; - bool server_ssl= false; - String server_host ="cashfusion.stackwallet.com"; - int server_port = 8787; - - //String server_host = "fusion.servo.cash"; - //int server_port = 8789; - - int tor_port = 0; - int roundcount = 0; - String txid=""; - - Tuple<String, String> status = Tuple("", ""); - Connection? connection; - - int numComponents =0; - double componentFeeRate=0; - double minExcessFee=0; - double maxExcessFee=0; - List<int> availableTiers =[]; - - int maxOutputs=0; - int safety_sum_in =0; - Map<int, int> safety_exess_fees = {}; - Map<int, List<int>> tierOutputs ={}; // not sure if this should be using outputs class. - - int inactiveTimeLimit = 600000; // this is in ms... equates to 10 minutes. - int tier = 0; - int covertPort = 0; - bool covertSSL = false; - double beginTime = 0.0; // represent time in seconds. - List<int> lastHash = <int>[]; - List<Address> reservedAddresses = <Address>[]; - int safetyExcessFee = 0; - DateTime t_fusionBegin = DateTime.now(); - Uint8List covertDomainB = Uint8List(0); - - var txInputIndices; - Transaction tx= Transaction(); - List<int> myComponentIndexes=[]; - List<int> myCommitmentIndexes=[]; - Set<int> badComponents ={}; - - Fusion () { - //initializeConnection(host, port) - } - /* - Future<void> initializeConnection(String host, int port) async { - Socket socket = await Socket.connect(host, port); - connection = Connection()..socket = socket; - } -*/ - - Future<void> add_coins_from_wallet(List<UTXO> utxoList) async { - // Convert each UTXO to an Input and add to 'coins' - for (UTXO utxo in utxoList) { - coins.add(Input.fromStackUTXO(utxo)); - } - } - - Future<void> fusion_run() async { - - print ("DEBUG FUSION 223...fusion run...."); - try { - - try { - - // Check compatibility - This was done in python version to see if fast libsec installed. - // For now , in dart, just pass this test. - ; - } on Exception catch(e) { - // handle exception, rethrow as a custom FusionError - throw FusionError("Incompatible: " + e.toString()); - } - - // Check if can connect to Tor proxy, if not, raise FusionError. Empty String treated as no host. - if (tor_host.isNotEmpty && tor_port != 0 && !await isTorPort(tor_host, tor_port)) { - throw FusionError("Can't connect to Tor proxy at $tor_host:$tor_port"); - } - - try { - // Check stop condition - check_stop(running: false); - } - catch (e) { - print (e); - } - - try { - // Check coins - check_coins(); - } - catch (e) { - print (e); - } - - - - // Connect to server - status = Tuple("connecting", ""); - try { - connection = await openConnection(server_host, server_port, connTimeout: 5.0, defaultTimeout: 5.0, ssl: server_ssl); - } catch (e) { - print("Connect failed: $e"); - String sslstr = server_ssl ? ' SSL ' : ''; - throw FusionError('Could not connect to $sslstr$server_host:$server_port'); - } - - - // Once connection is successful, wrap operations inside this block - // Within this block, version checks, downloads server params, handles coins and runs rounds - try { - - - SocketWrapper socketwrapper = SocketWrapper(server_host, server_port); - await socketwrapper.connect(); - - // Version check and download server params. - await greet(socketwrapper); - - socketwrapper.status(); - server_connected_and_greeted = true; - notify_server_status(true); - - // In principle we can hook a pause in here -- user can insert coins after seeing server params. - - try { - if (coins.isEmpty) { - throw FusionError('Started with no coins'); - return; - } - } - catch (e) { - print(e); - return; - } - - await allocateOutputs(socketwrapper); - // In principle we can hook a pause in here -- user can tweak tier_outputs, perhaps cancelling some unwanted tiers. - - // Register for tiers, wait for a pool. - await registerAndWait(socketwrapper); - - - // launch the covert submitter - CovertSubmitter covert = await startCovert(); - try { - // Pool started. Keep running rounds until fail or complete. - while (true) { - roundcount += 1; - if (await runRound(covert)) { - break; - } - } - } finally { - covert.stop(); - } - } finally { - (await connection)?.close(); - } - - print ("RETURNING early in fusion_run...."); - return; - - for (int i = 0; i < 60; i++) { - if (stopping) { - break; // not an error - } - - if (Util.walletHasTransaction(txid)) { - break; - } - - await Future.delayed(Duration(seconds: 1)); - } - - // Set status to 'complete' with 'time_wait' - status = Tuple('complete', 'txid: $txid'); - - // Wait for transaction to show up in wallets - // Set status to 'complete' with txid - - } on FusionError catch(err) { - print('Failed: ${err}'); - status.item1 = "failed"; - status.item2 = err.toString(); // setting the error message - } catch(exc) { - print('Exception: ${exc}'); - status.item1 = "failed"; - status.item2= "Exception: ${exc.toString()}"; // setting the exception message - } finally { - clear_coins(); - if (status.item1 != 'complete') { - for (var output in outputs) { - Util.unreserve_change_address(output.addr); - } - if (!server_connected_and_greeted) { - notify_server_status(false, tup: status); - } - } - } - - - } // end fusion_run function. - - - - - - - void notify_server_status(bool b, {Tuple? tup}) { - // Function implementation goes here - } - - - void stop([String reason = 'stopped', bool notIfRunning = false]) { - if (stopping) { - return; - } - if (notIfRunning) { - if (stopping_if_not_running) { - return; - } - stopReason = reason; - stopping_if_not_running = true; - } else { - stopReason = reason; - stopping = true; - } - // note the reason is only overwritten if we were not already stopping this way. - } - - void check_stop({bool running = true}) { - // Gets called occasionally from fusion thread to allow a stop point. - if (stopping || (!running && stopping_if_not_running)) { - throw FusionError(stopReason ?? 'Unknown stop reason'); - } - } - -void check_coins() { - // Implement by calling wallet layer to check the coins are ok. - return; -} - - static void foo() { -print ("hello"); -} - - void clear_coins() { - coins = []; - } - - void addCoins(List<Input> newCoins) { - coins.addAll(newCoins); - } - - void notify_coins_UI() { - return; - } - -static bool walletCanFuse() { - return true; - - // Implement logic here to return false if the wallet can't fuse. (If its read only or non P2PKH) -} - -static double nextDoubleNonZero(Random rng) { - double value = 0.0; - while (value == 0.0) { - value = rng.nextDouble(); - } - return value; -} - - static List<int>? randomOutputsForTier(Random rng, int inputAmount, int scale, int offset, int maxCount) { - - if (inputAmount < offset) { - return []; - } - double lambd = 1.0 / scale; - int remaining = inputAmount; - List<double> values = []; // list of fractional random values without offset - bool didBreak = false; // Add this flag to detect when a break is encountered - - for (int i = 0; i < maxCount + 1; i++) { - double val = -lambd * log(nextDoubleNonZero(rng)); - remaining -= (val.ceil() + offset); - if (remaining < 0) { - didBreak = true; // If you break, set this flag to true - break; - } - values.add(val); - } - - if (!didBreak && values.length > maxCount) { - values = values.sublist(0, maxCount); - } - - if (values.isEmpty) { - // Our first try put us over the limit, so we have nothing to work with. - // (most likely, scale was too large) - return []; - } - - int desiredRandomSum = inputAmount - values.length * offset; - assert(desiredRandomSum >= 0, 'desiredRandomSum is less than 0'); - - /*Now we need to rescale and round the values so they fill up the desired. - input amount exactly. We perform rounding in cumulative space so that the - sum is exact, and the rounding is distributed fairly. - */ - - // Dart equivalent of itertools.accumulate - List<double> cumsum = []; - double sum = 0; - for (double value in values) { - sum += value; - cumsum.add(sum); - } - - double rescale = desiredRandomSum / cumsum[cumsum.length - 1]; - List<int> normedCumsum = cumsum.map((v) => (rescale * v).round()).toList(); - assert(normedCumsum[normedCumsum.length - 1] == desiredRandomSum, 'Last element of normedCumsum is not equal to desiredRandomSum'); - List<int> differences = []; - differences.add(normedCumsum[0]); // First element - for (int i = 1; i < normedCumsum.length; i++) { - differences.add(normedCumsum[i] - normedCumsum[i - 1]); - } - - List<int> result = differences.map((d) => offset + d).toList(); - assert(result.reduce((a, b) => a + b) == inputAmount, 'Sum of result is not equal to inputAmount'); - return result; - - } - - - static List<ComponentResult> genComponents(int numBlanks, List<Input> inputs, List<Output> outputs, int feerate) { - assert(numBlanks >= 0); - - List<Tuple<Component, int>> components = []; - - // Set up Pedersen setup instance - Uint8List HBytes = Uint8List.fromList([0x02] + 'CashFusion gives us fungibility.'.codeUnits); - ECDomainParameters params = ECDomainParameters('secp256k1'); - ECPoint? HMaybe = params.curve.decodePoint(HBytes); - if (HMaybe == null) { - throw Exception('Failed to decode point'); - } - ECPoint H = HMaybe; - PedersenSetup setup = PedersenSetup(H); - - for (Input input in inputs) { - int fee = Util.componentFee(input.sizeOfInput(), feerate); - - var comp = Component(); - comp.input = InputComponent( - prevTxid: Uint8List.fromList(input.prevTxid.reversed.toList()), - prevIndex: input.prevIndex, - pubkey: input.pubKey, - amount: Int64(input.amount) - ); - components.add(Tuple<Component, int>(comp, input.amount - fee)); - } - - for (Output output in outputs) { - var script = output.addr.toScript(); - int fee = Util.componentFee(output.sizeOfOutput(), feerate); - - var comp = Component(); - comp.output = OutputComponent( - scriptpubkey: script, - amount: Int64(output.value) - ); - components.add(Tuple<Component, int>(comp, -output.value - fee)); - } - - for (int i = 0; i < numBlanks; i++) { - var comp = Component(); - comp.blank = BlankComponent(); - components.add(Tuple<Component, int>(comp, 0)); - } - - List<ComponentResult> resultList = []; - - components.asMap().forEach((cnum, Tuple<Component, int> componentTuple) { - Uint8List salt = Util.tokenBytes(32); - componentTuple.item1.saltCommitment = Util.sha256(salt); - var compser = componentTuple.item1.writeToBuffer(); - - Tuple<Uint8List, Uint8List> keyPair = Util.genKeypair(); - Uint8List privateKey = keyPair.item1; - Uint8List pubKey = keyPair.item2; - - Commitment commitmentInstance = setup.commit(BigInt.from(componentTuple.item2)); - Uint8List amountCommitment = commitmentInstance.PUncompressed; - - -// Convert BigInt nonce to Uint8List - Uint8List pedersenNonce = Uint8List.fromList([int.parse(commitmentInstance.nonce.toRadixString(16), radix: 16)]); - -// Generating initial commitment - InitialCommitment commitment = InitialCommitment( - saltedComponentHash: Util.sha256(Uint8List.fromList([...compser, ...salt])), - amountCommitment: amountCommitment, - communicationKey: pubKey - ); - - Uint8List commitser = commitment.writeToBuffer(); - - // Generating proof - Proof proof = Proof( - componentIdx: cnum, - salt: salt, - pedersenNonce: pedersenNonce - ); - - // Adding result to list - resultList.add(ComponentResult(commitser, cnum, compser, proof, privateKey)); - }); - - return resultList; -} - - - Future<GeneratedMessage> recv2(SocketWrapper socketwrapper, List<String> expectedMsgNames, {Duration? timeout}) async { - if (connection == null) { - throw FusionError('Connection not initialized'); - } - - var result = await recvPb2( - socketwrapper, - connection!, - ServerMessage, - expectedMsgNames, - timeout: timeout - ); - - var submsg = result.item1; - var mtype = result.item2; - - if (mtype == 'error') { - throw FusionError('server error: ${submsg.toString()}'); - } - - return submsg; - } - - - - Future<GeneratedMessage> recv(List<String> expectedMsgNames, {Duration? timeout}) async { - // DEPRECATED - if (connection == null) { - throw FusionError('Connection not initialized'); - } - - var result = await recvPb( - connection!, - ServerMessage, - expectedMsgNames, - timeout: timeout - ); - - var submsg = result.item1; - var mtype = result.item2; - - if (mtype == 'error') { - throw FusionError('server error: ${submsg.toString()}'); - } - - return submsg; - } - - - Future<void> send(GeneratedMessage submsg, {Duration? timeout}) async { - // DEPRECATED - if (connection != null) { - await sendPb(connection!, ClientMessage, submsg, timeout: timeout); - } else { - print('Connection is null'); - } - - } - - - Future<void> send2(SocketWrapper socketwrapper, GeneratedMessage submsg, {Duration? timeout}) async { - - if (connection != null) { - await sendPb2(socketwrapper, connection!, ClientMessage, submsg, timeout: timeout); - } else { - print('Connection is null'); - } - - } - - Future<void> greet(SocketWrapper socketwrapper) async { - ClientHello clientHello = ClientHello( - version: Uint8List.fromList(utf8.encode(Protocol.VERSION)), - genesisHash: Util.get_current_genesis_hash()); - - ClientMessage clientMessage = ClientMessage() - ..clienthello = clientHello; - - //deprecated - //Connection greet_connection_1 = Connection.withoutSocket(); - - /* - lets move this up a level to the fusion_run and pass it in.... - SocketWrapper socketwrapper = SocketWrapper(server_host, server_port); - await socketwrapper.connect(); -*/ - send2(socketwrapper,clientMessage); - - - var replyMsg = await recv2(socketwrapper, ['serverhello']); - if (replyMsg is ServerMessage) { - ServerHello reply = replyMsg.serverhello; - - numComponents = reply.numComponents; - componentFeeRate = reply.componentFeerate.toDouble(); - minExcessFee = reply.minExcessFee.toDouble(); - maxExcessFee = reply.maxExcessFee.toDouble(); - availableTiers = reply.tiers.map((tier) => tier.toInt()).toList(); - - // Enforce some sensible limits, in case server is crazy - if (componentFeeRate > Protocol.MAX_COMPONENT_FEERATE) { - throw FusionError('excessive component feerate from server'); - } - if (minExcessFee > 400) { // note this threshold should be far below MAX_EXCESS_FEE - throw FusionError('excessive min excess fee from server'); - } - if (minExcessFee > maxExcessFee) { - throw FusionError('bad config on server: fees'); - } - if (numComponents < Protocol.MIN_TX_COMPONENTS * 1.5) { - throw FusionError('bad config on server: num_components'); - } - } else { - throw Exception('Received unexpected message type: ${replyMsg.runtimeType}'); - } - } - - - Future<void> allocateOutputs(socketwrapper) async { - print ("DBUG allocateoutputs 746"); - - print ("CHECK socketwrapper 746"); - socketwrapper.status(); - assert(['setup', 'connecting'].contains(status.item1)); - - List<Input> inputs = coins; - int numInputs = inputs.length; - - int maxComponents = min(numComponents, Protocol.MAX_COMPONENTS); - int maxOutputs = maxComponents - numInputs; - if (maxOutputs < 1) { - throw FusionError('Too many inputs ($numInputs >= $maxComponents)'); - } - - if (maxOutputs != null) { - assert(maxOutputs >= 1); - maxOutputs = min(maxOutputs, maxOutputs); - } - - int numDistinct = inputs.map((e) => e.value).toSet().length; - int minOutputs = max(Protocol.MIN_TX_COMPONENTS - numDistinct, 1); - if (maxOutputs < minOutputs) { - throw FusionError('Too few distinct inputs selected ($numDistinct); cannot satisfy output count constraint (>= $minOutputs, <= $maxOutputs)'); - } - - - int sumInputsValue = inputs.map((e) => e.value).reduce((a, b) => a + b); - int inputFees = inputs.map((e) => Util.componentFee(e.sizeOfInput(), componentFeeRate.toInt())).reduce((a, b) => a + b); - int availForOutputs = sumInputsValue - inputFees - minExcessFee.toInt(); - - int feePerOutput = Util.componentFee(34, componentFeeRate.toInt()); - - int offsetPerOutput = Protocol.MIN_OUTPUT + feePerOutput; - - if (availForOutputs < offsetPerOutput) { - throw FusionError('Selected inputs had too little value'); - } - - var rng = Random(); - var seed = List<int>.generate(32, (_) => rng.nextInt(256)); - - print ("DBUG allocateoutputs 785"); - tierOutputs = {}; - var excessFees = <int, int>{}; - for (var scale in availableTiers) { - int fuzzFeeMax = scale ~/ 1000000; - int fuzzFeeMaxReduced = min(fuzzFeeMax, min(Protocol.MAX_EXCESS_FEE - minExcessFee.toInt(), maxExcessFee.toInt())); - - assert(fuzzFeeMaxReduced >= 0); - int fuzzFee = rng.nextInt(fuzzFeeMaxReduced + 1); - - int reducedAvailForOutputs = availForOutputs - fuzzFee; - if (reducedAvailForOutputs < offsetPerOutput) { - continue; - } - - var outputs = randomOutputsForTier(rng, reducedAvailForOutputs, scale, offsetPerOutput, maxOutputs); - if (outputs != null) { - print (outputs); - } - if (outputs == null || outputs.length < minOutputs) { - - - continue; - } - outputs = outputs.map((o) => o - feePerOutput).toList(); - - assert(inputs.length + (outputs?.length ?? 0) <= Protocol.MAX_COMPONENTS); - - excessFees[scale] = sumInputsValue - inputFees - reducedAvailForOutputs; - tierOutputs[scale] = outputs!; - } - - - print('Possible tiers: $tierOutputs'); - - safety_sum_in = sumInputsValue; - safety_exess_fees = excessFees; - return; - } - - - - Future<void> registerAndWait(SocketWrapper socketwrapper) async { - - var stopwatch = Stopwatch()..start(); - // msg can be different classes depending on which protobuf msg is sent. - dynamic? msg; - - var tierOutputs = this.tierOutputs; - var tiersSorted = tierOutputs.keys.toList()..sort(); - - if (tierOutputs.isEmpty) { - throw FusionError('No outputs available at any tier (selected inputs were too small / too large).'); - } - - print('registering for tiers: $tiersSorted'); - - int self_fuse = 1; // Temporary value for now - var cashfusionTag = [1];// temp value for now - - - - check_stop(running: false); - check_coins(); - - - var tags = [JoinPools_PoolTag(id: cashfusionTag, limit: self_fuse)]; - -// Create JoinPools message - JoinPools joinPools = JoinPools( - tiers: tiersSorted.map((i) => Int64(i)).toList(), - tags: tags - ); - -// Wrap it in a ClientMessage - ClientMessage clientMessage = ClientMessage() - ..joinpools = joinPools; - - send2(socketwrapper, clientMessage); - - - status = Tuple<String, String>('waiting', 'Registered for tiers'); - - var tiersStrings = {for (var entry in tierOutputs.entries) entry.key: (entry.key * 1e-8).toStringAsFixed(8).replaceAll(RegExp(r'0+$'), '')}; - - while (true) { - msg = await recv2(socketwrapper,['tierstatusupdate', 'fusionbegin'], timeout: Duration(seconds: 10)); - var fieldInfoFusionBegin = msg.info_.byName["fusionbegin"]; - if (fieldInfoFusionBegin != null && msg.hasField(fieldInfoFusionBegin.tagNumber)) { - print ("DEBUG 867 Fusion Begin message..."); - break; - } - - check_stop(running: false); - check_coins(); - - // Define the bool variable - - - - var fieldInfo = msg.info_.byName["tierstatusupdate"]; - if (fieldInfo == null) { - throw FusionError('Expected field not found in message: tierstatusupdate'); - } - - bool messageIsTierStatusUpdate = msg.hasField(fieldInfo.tagNumber); - print ("DEBUG 889 getting tier update."); - - if (!messageIsTierStatusUpdate) { - throw FusionError('Expected a TierStatusUpdate message'); - } - - late var statuses; - if (messageIsTierStatusUpdate) { - //TierStatusUpdate tierStatusUpdate = msg.tierstatusupdate; - var tierStatusUpdate = msg.getField(fieldInfo.tagNumber) as TierStatusUpdate; - statuses = tierStatusUpdate.statuses; - } - - - double maxfraction = 0.0; - var maxtiers = <int>[]; - int? besttime; - int? besttimetier; - for (var entry in statuses.entries) { - double frac = entry.value.players.toInt() / entry.value.minPlayers.toInt(); - if (frac >= maxfraction) { - if (frac > maxfraction) { - maxfraction = frac; - maxtiers.clear(); - } - maxtiers.add(entry.key.toInt()); - } - - var fieldInfoTimeRemaining = entry.value.info_.byName["timeRemaining"]; - - if (entry.value.hasField(fieldInfoTimeRemaining.tagNumber)) { - int tr = entry.value.timeRemaining.toInt(); - if (besttime == null || tr < besttime) { - besttime = tr; - besttimetier = entry.key.toInt(); - } - } - } - - - var displayBest = <String>[]; - var displayMid = <String>[]; - var displayQueued = <String>[]; - - for (var tier in tiersSorted) { - - if (statuses.containsKey(tier)) { - var tierStr = tiersStrings[tier]; - if (tierStr == null) { - throw FusionError('server reported status on tier we are not registered for'); - } - if (tier == besttimetier) { - displayBest.insert(0, '**$tierStr**'); - } else if (maxtiers.contains(tier)) { - displayBest.add('[$tierStr]'); - } else { - displayMid.add(tierStr); - } - } else { - displayQueued.add(tiersStrings[tier]!); - } - } - - - var parts = <String>[]; - if (displayBest.isNotEmpty || displayMid.isNotEmpty) { - parts.add("Tiers: ${displayBest.join(', ')} ${displayMid.join(', ')}"); - } - if (displayQueued.isNotEmpty) { - parts.add("Queued: ${displayQueued.join(', ')}"); - } - var tiersString = parts.join(' '); - - if (besttime == null && inactiveTimeLimit != null) { - if (stopwatch.elapsedMilliseconds > inactiveTimeLimit) { - throw FusionError('stopping due to inactivity'); - } else { - ; - } - } else { - ; - } - - - if (besttime != null) { - status = Tuple<String, String>('waiting', 'Starting in ${besttime}s. $tiersString'); - } else if (maxfraction >= 1) { - status = Tuple<String, String>('waiting', 'Starting soon. $tiersString'); - } else if (displayBest.isNotEmpty || displayMid.isNotEmpty) { - status = Tuple<String, String>('waiting', '${(maxfraction * 100).round()}% full. $tiersString'); - } else { - status = Tuple<String, String>('waiting', tiersString); - } - } - - - - var fieldInfoFusionBegin = msg.info_.byName["fusionbegin"]; - -// Check if fieldInfoFusionBegin is null - if (fieldInfoFusionBegin == null) { - throw FusionError('Expected field not found in message: fusionbegin'); - } - - bool messageIsFusionBegin = msg.hasField(fieldInfoFusionBegin.tagNumber); - -// Print whether the message is FusionBegin or not - if (!messageIsFusionBegin) { - throw FusionError('Expected a FusionBegin message'); - } - - - - t_fusionBegin = DateTime.now(); - - FusionBegin fusionBeginMsg = msg.fusionbegin; - - var elapsedSeconds = (stopwatch.elapsedMilliseconds / 1000).toInt(); - var clockMismatch = fusionBeginMsg.serverTime.toInt() - DateTime.now().millisecondsSinceEpoch / 1000; - - - - if (clockMismatch.abs().toDouble() > Protocol.MAX_CLOCK_DISCREPANCY) { - throw FusionError("Clock mismatch too large: ${(clockMismatch.toDouble()).toStringAsFixed(3)}."); - } - - - tier = fusionBeginMsg.tier.toInt(); - - if (msg is FusionBegin) { - covertDomainB = Uint8List.fromList(msg.covertDomain); - } - - covertPort = fusionBeginMsg.covertPort; - covertSSL = fusionBeginMsg.covertSsl; - beginTime = fusionBeginMsg.serverTime.toDouble(); - - lastHash = Util.calcInitialHash(tier, covertDomainB, covertPort, covertSSL, beginTime); - - var outAmounts = tierOutputs[tier]; - var outAddrs = Util.reserve_change_addresses(outAmounts?.length ?? 0); - - reservedAddresses = outAddrs; - outputs = Util.zip(outAmounts ?? [], outAddrs).map((pair) => Output(value: pair[0], addr: pair[1])).toList(); - - safetyExcessFee = safety_exess_fees[tier] ?? 0; - - print("starting fusion rounds at tier $tier: ${coins.length} inputs and ${outputs.length} outputs"); - } - - Future<CovertSubmitter> startCovert() async { - - print ("DEBUG START COVERT!"); - status = Tuple('running', 'Setting up Tor connections'); - - - String covertDomain; - try { - covertDomain = utf8.decode(covertDomainB); - } catch (e) { - throw FusionError('badly encoded covert domain'); - } - CovertSubmitter covert = CovertSubmitter( - covertDomain, - covertPort, - covertSSL, - tor_host, - tor_port, - numComponents, - Protocol.COVERT_SUBMIT_WINDOW, - Protocol.COVERT_SUBMIT_TIMEOUT - ); - try { - covert.scheduleConnections( - t_fusionBegin, - Duration(seconds: Protocol.COVERT_CONNECT_WINDOW.toInt()), - numSpares: Protocol.COVERT_CONNECT_SPARES.toInt(), - connectTimeout: Protocol.COVERT_CONNECT_TIMEOUT.toInt() - ); - - print ("DEBUG return early from covert"); - return covert; - - // loop until a just a bit before we're expecting startRound, watching for status updates - final tend = t_fusionBegin.add(Duration(seconds: (Protocol.WARMUP_TIME - Protocol.WARMUP_SLOP - 1).round())); - - while (DateTime.now().millisecondsSinceEpoch / 1000 < tend.millisecondsSinceEpoch / 1000) { - - int numConnected = covert.slots.where((s) => s.covConn?.connection != null).length; - - int numSpareConnected = covert.spareConnections.where((c) => c.connection != null).length; - - status = Tuple('running', 'Setting up Tor connections ($numConnected+$numSpareConnected out of $numComponents)'); - - await Future.delayed(Duration(seconds: 1)); - - covert.checkOk(); - this.check_stop(); - this.check_coins(); - } - } catch (e) { - covert.stop(); - rethrow; - } - - return covert; - } - - - Future<bool> runRound(CovertSubmitter covert) async { - print ("START OF RUN ROUND"); - - status = Tuple('running', 'Starting round ${roundcount.toString()}'); - int timeoutInSeconds = (2 * Protocol.WARMUP_SLOP + Protocol.STANDARD_TIMEOUT).toInt(); - var msg = await recv(['startround'], timeout: Duration(seconds: timeoutInSeconds)); - - // Record the time we got this message; it forms the basis time for all covert activities. - final covertT0 = DateTime.now().millisecondsSinceEpoch / 1000; - double covertClock() => (DateTime.now().millisecondsSinceEpoch / 1000) - covertT0; - - final roundTime = (msg as StartRound).serverTime; - - // Check the server's declared unix time, which will be committed. - final clockMismatch = (msg as StartRound).serverTime - DateTime.now().millisecondsSinceEpoch / 1000; - if (clockMismatch.abs() > Protocol.MAX_CLOCK_DISCREPANCY) { - throw FusionError("Clock mismatch too large: ${clockMismatch.toInt().toStringAsPrecision(3)}."); - } - - if (t_fusionBegin != null) { - // On the first startround message, check that the warmup time was within acceptable bounds. - final lag = covertT0 - (t_fusionBegin.millisecondsSinceEpoch / 1000) - Protocol.WARMUP_TIME; - if (lag.abs() > Protocol.WARMUP_SLOP) { - throw FusionError("Warmup period too different from expectation (|${lag.toStringAsFixed(3)}s| > ${Protocol.WARMUP_SLOP.toStringAsFixed(3)}s)."); - } - t_fusionBegin = DateTime.now(); - } - - print("round starting at ${DateTime.now().millisecondsSinceEpoch / 1000}"); - - final inputFees = coins.map((e) => Util.componentFee(e.sizeOfInput(), componentFeeRate.toInt())).reduce((a, b) => a + b); - final outputFees = outputs.length * Util.componentFee(34, componentFeeRate.toInt()); - - final sumIn = coins.map((e) => e.amount).reduce((a, b) => a + b); - final sumOut = outputs.map((e) => e.value).reduce((a, b) => a + b); - - final totalFee = sumIn - sumOut; - final excessFee = totalFee - inputFees - outputFees; - final safeties = [ - sumIn == safety_sum_in, - excessFee == safetyExcessFee, - excessFee <= Protocol.MAX_EXCESS_FEE, - totalFee <= Protocol.MAX_FEE, - ]; - - if (!safeties.every((element) => element)) { - throw Exception("(BUG!) Funds re-check failed -- aborting for safety. ${safeties.toString()}"); - } - - final roundPubKey = (msg as StartRound).roundPubkey; - - final blindNoncePoints = (msg as StartRound).blindNoncePoints; - if (blindNoncePoints.length != numComponents) { - throw FusionError('blind nonce miscount'); - } - - final numBlanks = numComponents - coins.length - outputs.length; - final List<ComponentResult> genComponentsResults = genComponents(numBlanks, coins, outputs, componentFeeRate.toInt()); - - final List<Uint8List> myCommitments = []; - final List<int> myComponentSlots = []; - final List<Uint8List> myComponents = []; - final List<Proof> myProofs = []; - final List<Uint8List> privKeys = []; - final List<dynamic> pedersenAmount = []; // replace dynamic with the actual type - final List<dynamic> pedersenNonce = []; // replace dynamic with the actual type - - for (var genComponentResult in genComponentsResults) { - myCommitments.add(genComponentResult.commitment); - myComponentSlots.add(genComponentResult.counter); - myComponents.add(genComponentResult.component); - myProofs.add(genComponentResult.proof); - privKeys.add(genComponentResult.privateKey); - pedersenAmount.add(genComponentResult.pedersenAmount); - pedersenNonce.add(genComponentResult.pedersenNonce); - } - assert(excessFee == pedersenAmount.reduce((a, b) => a + b)); // sanity check that we didn't mess up the above - assert(myComponents.toSet().length == myComponents.length); // no duplicates - - // Need to implement this! schnorr is from EC schnorr.py - var blindSigRequests = <dynamic>[]; - - /* - final blindSigRequests = blindNoncePoints.map((e) => Schnorr.BlindSignatureRequest(roundPubKey, e, sha256(myComponents.elementAt(e)))).toList(); - -*/ - print ("RETURNING EARLY FROM run round ....."); - return true; - - final randomNumber = Util.getRandomBytes(32); - covert.checkOk(); - check_stop(); - check_coins(); - - - await send(PlayerCommit( - initialCommitments: myCommitments, - excessFee: Int64(excessFee), - pedersenTotalNonce: pedersenNonce.cast<int>(), - randomNumberCommitment: sha256.convert(randomNumber).bytes, - blindSigRequests: blindSigRequests.map((r) => r.getRequest() as List<int>).toList(), - )); - - - msg = await recv(['blindsigresponses'], timeout: Duration(seconds: Protocol.T_START_COMPS.toInt())); - - - if (msg is BlindSigResponses) { - var typedMsg = msg as BlindSigResponses; - assert(typedMsg.scalars.length == blindSigRequests.length); - } else { - // Handle the case where msg is not of type BlindSigResponses - throw Exception('Unexpected message type: ${msg.runtimeType}'); - } - - final blindSigs = List.generate( - blindSigRequests.length, - (index) { - if (msg is BlindSigResponses) { - var typedMsg = msg as BlindSigResponses; - return blindSigRequests[index].finalize(typedMsg.scalars[index], check: true); - } else { - // Handle the case where msg is not of type BlindSigResponses - throw Exception('Unexpected message type: ${msg.runtimeType}'); - } - }, - ); - - -// Sleep until the covert component phase really starts, to catch covert connection failures. - var remainingTime = Protocol.T_START_COMPS - covertClock(); - if (remainingTime < 0) { - throw FusionError('Arrived at covert-component phase too slowly.'); - } - await Future.delayed(Duration(seconds: remainingTime.floor())); - -// Our final check to leave the fusion pool, before we start telling our -// components. This is much more annoying since it will cause the round -// to fail, but since we would end up killing the round anyway then it's -// best for our privacy if we just leave now. -// (This also is our first call to check_connected.) - covert.checkConnected(); - check_coins(); - -// Start covert component submissions - print("starting covert component submission"); - status = Tuple('running', 'covert submission: components'); - -// If we fail after this point, we want to stop connections gradually and -// randomly. We don't want to stop them all at once, since if we had already -// provided our input components then it would be a leak to have them all drop at once. - covert.setStopTime((covertT0 + Protocol.T_START_CLOSE).toInt()); - - - // Schedule covert submissions. - List<CovertComponent?> messages = List.filled(myComponents.length, null); - - for (var i = 0; i < myComponents.length; i++) { - messages[myComponentSlots[i]] = CovertComponent( - roundPubkey: roundPubKey, - signature: blindSigs[i], - component: myComponents[i] - ); - } - if (messages.any((element) => element == null)) { - throw FusionError('Messages list includes null values.'); - } - - final targetDateTime = DateTime.fromMillisecondsSinceEpoch(((covertT0 + Protocol.T_START_COMPS) * 1000).toInt()); - covert.scheduleSubmissions(targetDateTime, messages); - - - // While submitting, we download the (large) full commitment list. - msg = await recv(['allcommitments'], timeout: Duration(seconds: Protocol.T_START_SIGS.toInt())); - AllCommitments allCommitmentsMsg = msg as AllCommitments; - List<InitialCommitment> allCommitments = allCommitmentsMsg.initialCommitments.map((commitmentBytes) { - return InitialCommitment.fromBuffer(commitmentBytes); - }).toList(); - - - // Quick check on the commitment list. - if (allCommitments.toSet().length != allCommitments.length) { - throw FusionError('Commitments list includes duplicates.'); - } - try { - List<Uint8List> allCommitmentsBytes = allCommitments.map((commitment) => commitment.writeToBuffer()).toList(); - myCommitmentIndexes = myCommitments.map((c) => allCommitmentsBytes.indexOf(c)).toList(); - - - } on Exception { - throw FusionError('One or more of my commitments missing.'); - } - - remainingTime = Protocol.T_START_SIGS - covertClock(); - if (remainingTime < 0) { - throw FusionError('took too long to download commitments list'); - } - - // Once all components are received, the server shares them with us: - msg = await recv(['sharecovertcomponents'], timeout: Duration(seconds: Protocol.T_START_SIGS.toInt())); - - ShareCovertComponents shareCovertComponentsMsg = msg as ShareCovertComponents; - List<List<int>> allComponents = shareCovertComponentsMsg.components; - bool skipSignatures = msg.getField(2); - - // Critical check on server's response timing. - if (covertClock() > Protocol.T_START_SIGS) { - throw FusionError('Shared components message arrived too slowly.'); - } - - covert.checkDone(); - - try { - myComponentIndexes = myComponents.map((c) => allComponents.indexWhere((element) => ListEquality().equals(element, c))).toList(); - if (myComponentIndexes.contains(-1)) { - throw FusionError('One or more of my components missing.'); - } - } on StateError { - throw FusionError('One or more of my components missing.'); - } - - // Need to implement: check the components list and see if there are enough inputs/outputs - // for there to be significant privacy. - - List<List<int>> allCommitmentsBytes = allCommitments.map((commitment) => commitment.writeToBuffer().toList()).toList(); - List<int> sessionHash = Util.calcRoundHash(lastHash, roundPubKey, roundTime.toInt(), allCommitmentsBytes, allComponents); - - - if (shareCovertComponentsMsg.sessionHash != null && !ListEquality().equals(shareCovertComponentsMsg.sessionHash, sessionHash)) { - - throw FusionError('Session hash mismatch (bug!)'); - } - - if (!shareCovertComponentsMsg.skipSignatures) { - print("starting covert signature submission"); - status = Tuple('running', 'covert submission: signatures'); - - if (allComponents - .toSet() - .length != allComponents.length) { - throw FusionError('Server component list includes duplicates.'); - } - - - var txInputIndices = Transaction.txFromComponents( - allComponents, sessionHash); - - - Tuple txData = Transaction.txFromComponents(allComponents, sessionHash); - tx = txData.item1; - List<int> inputIndices = txData.item2; - - - List< - CovertTransactionSignature?> covertTransactionSignatureMessages = List< - CovertTransactionSignature?>.filled(myComponents.length, null); - - var my_combined = List<Tuple<int, Input>>.generate( - inputIndices.length, - (index) => Tuple(inputIndices[index], tx.Inputs[index]), - ); - - - - for (var i = 0; i < my_combined.length; i++) { - int cIdx = my_combined[i].item1; - Input inp = my_combined[i].item2; - - int myCompIdx = myComponentIndexes.indexOf(cIdx); - if (myCompIdx == -1) continue; // not my input - - var pubKey = inp.getPubKey(0); - var sec = inp.getPrivKey(0); - - var preimageBytes = tx.serializePreimage(i, 0x41, useCache: true); - var sighash = sha256.convert(sha256.convert(preimageBytes).bytes); - - //var sig = schnorr.sign(sec, sighash); // Needs implementation - var sig = <int>[0, 1, 2, 3, 4]; // dummy placeholder - - covertTransactionSignatureMessages[myComponentSlots[myCompIdx]] = - CovertTransactionSignature(txsignature: sig, whichInput: i); - } - - DateTime covertT0DateTime = DateTime.fromMillisecondsSinceEpoch( - covertT0.toInt() * 1000); // covertT0 is in seconds - covert.scheduleSubmissions( - covertT0DateTime.add( - Duration(milliseconds: Protocol.T_START_SIGS.toInt())), - covertTransactionSignatureMessages - ); - - - // wait for result - int timeoutMillis = (Protocol.T_EXPECTING_CONCLUSION - - Protocol.TS_EXPECTING_COVERT_COMPONENTS).toInt(); - Duration timeout = Duration(milliseconds: timeoutMillis); - msg = await recv(['fusionresult'], timeout: timeout); - - - // Critical check on server's response timing. - if (covertClock() > Protocol.T_EXPECTING_CONCLUSION) { - throw FusionError('Fusion result message arrived too slowly.'); - } - - covert.checkDone(); - FusionResult fusionResultMsg = msg as FusionResult; - if (fusionResultMsg.ok) { - List<List<int>> allSigs = msg.txsignatures; - - // assemble the transaction. - if (allSigs.length != tx.Inputs.length) { - throw FusionError('Server gave wrong number of signatures.'); - } - for (var i = 0; i < allSigs.length; i++) { - List<int> sigBytes = allSigs[i]; - String sig = base64.encode(sigBytes); - Input inp = tx.Inputs[i]; - if (sig.length != 64) { - throw FusionError('server relayed bad signature'); - } - inp.signatures = [sig + '41']; - } - - assert(tx.isComplete()); - String txHex = tx.serialize(); - - txid = tx.txid(); - String sumInStr = Util.formatSatoshis(sumIn, - numZeros: 8); - String feeStr = totalFee - .toString(); - String feeLoc = 'fee'; - - String label = "CashFusion ${coins.length}⇢${outputs - .length}, ${sumInStr} BCH (−${feeStr} sats ${feeLoc})"; - - Util.updateWalletLabel(txid, label); - } - - else { - badComponents = msg.badComponents.toSet(); - if (badComponents.intersection(myComponentIndexes.toSet()).isNotEmpty) { - print("bad components: ${badComponents.toList()} mine: ${myComponentIndexes.toList()}"); - throw FusionError("server thinks one of my components is bad!"); - } - } - - - } - else { // skip_signatures True - Set<int> badComponents = Set<int>(); - } - -// ### Blame phase ### - - - covert.setStopTime((covertT0 + Protocol.T_START_CLOSE_BLAME).floor()); - - print("sending proofs"); - status = Tuple('running', 'round failed - sending proofs'); - - -// create a list of commitment indexes, but leaving out mine. - List<int> othersCommitmentIdxes = []; - for(int i=0; i<allCommitments.length; i++) { - if (!myCommitmentIndexes.contains(i)) { - othersCommitmentIdxes.add(i); - } - } - int N = othersCommitmentIdxes.length; - assert(N == allCommitments.length - myCommitments.length); - if (N == 0) { - throw FusionError("Fusion failed with only me as player -- I can only blame myself."); - } - -// where should I send my proofs? - List<InitialCommitment> dstCommits = []; - for(int i=0; i<myCommitments.length; i++) { - dstCommits.add(allCommitments[othersCommitmentIdxes[Util.randPosition(randomNumber, N, i)]]); - } - -// generate the encrypted proofs - List<String> encproofs = List<String>.filled(myCommitments.length, ''); - - - ECDomainParameters params = ECDomainParameters('secp256k1'); - for (int i=0; i<dstCommits.length; i++) { - InitialCommitment msg = dstCommits[i]; - Proof proof = myProofs[i]; - proof.componentIdx = myComponentIndexes[i]; - - ECPoint? communicationKeyPointMaybe = params.curve.decodePoint(Uint8List.fromList(msg.communicationKey)); - if (communicationKeyPointMaybe == null) { - // handle the error case here, e.g., throw an exception or skip this iteration. - continue; - } - ECPoint communicationKeyPoint = communicationKeyPointMaybe; - - try { - Uint8List encryptedData = await encrypt(proof.writeToBuffer(), communicationKeyPoint, padToLength: 80); - encproofs[i] = String.fromCharCodes(encryptedData); - } catch (EncryptionFailed) { - // The communication key was bad (probably invalid x coordinate). - // We will just send a blank. They can't even blame us since there is no private key! :) - continue; - } - } - - List<Uint8List> encodedEncproofs = encproofs.map((e) => Uint8List.fromList(e.codeUnits)).toList(); - this.send(MyProofsList(encryptedProofs: encodedEncproofs, randomNumber: randomNumber)); - - status = Tuple('running', 'round failed - checking proofs'); - - print("receiving proofs"); - msg = await this.recv(['theirproofslist'], timeout: Duration(seconds: (2 * Protocol.STANDARD_TIMEOUT).round())); - - List<Blames_BlameProof> blames = []; - - int countInputs = 0; - - TheirProofsList proofsList = msg as TheirProofsList; - - var privKey; - var commitmentBlob; - for (var i = 0; i < proofsList.proofs.length; i++) { - var rp = msg.proofs[i]; - try { - privKey = privKeys[rp.dstKeyIdx]; - commitmentBlob = allCommitments[rp.srcCommitmentIdx]; - } on RangeError catch (e) { - throw FusionError("Server relayed bad proof indices"); - } - - var sKey; - var proofBlob; - - - - try { - var result = await decrypt(Uint8List.fromList(rp.encryptedProof), privKey); - proofBlob = result.item1; // First item is the decrypted data - sKey = result.item2; // Second item is the symmetric key - } on Exception catch (e) { - print("found an undecryptable proof"); - blames.add(Blames_BlameProof(whichProof: i, privkey: privKey, blameReason: 'undecryptable')); - continue; - } - - - var commitment = InitialCommitment(); - try { - commitment.mergeFromBuffer(commitmentBlob); // Method to parse protobuf data - } on FormatException catch (e) { - throw FusionError("Server relayed bad commitment"); - } - - var inpComp; - - try { - // Convert allComponents to List<Uint8List> - List<Uint8List> allComponentsUint8 = allComponents.map((component) => Uint8List.fromList(component)).toList(); - // Convert badComponents to List<int> - List<int> badComponentsList = badComponents.toList(); - // Convert componentFeeRate to int if it's double - int componentFeerateInt = componentFeeRate.round(); // or use .toInt() if you want to truncate instead of rounding - - var inpComp = validateProofInternal(proofBlob, commitment, allComponentsUint8, badComponentsList, componentFeerateInt); - } on Exception catch (e) { - print("found an erroneous proof: ${e.toString()}"); - var blameProof = Blames_BlameProof(); - blameProof.whichProof = i; - blameProof.sessionKey = sKey; - blameProof.blameReason = e.toString(); - blames.add(blameProof); - continue; - } - - - if (inpComp != null) { - countInputs++; - try { - Util.checkInputElectrumX(inpComp); - } on Exception catch (e) { - print("found a bad input [${rp.srcCommitmentIdx}]: $e (${inpComp.prevTxid.reversed.toList().toHex()}:${inpComp.prevIndex})"); - - var blameProof = Blames_BlameProof(); - blameProof.whichProof = i; - blameProof.sessionKey = sKey; - blameProof.blameReason = 'input does not match blockchain: ' + e.toString(); - blameProof.needLookupBlockchain = true; - blames.add(blameProof); - - } catch (e) { - print("verified an input internally, but was unable to check it against blockchain: ${e}"); - } - } - - - } - print("checked ${msg.proofs.length} proofs, $countInputs of them inputs"); - - print("sending blames"); - send(Blames(blames: blames)); - - status = Tuple('running', 'awaiting restart'); - -// Await the final 'restartround' message. It might take some time -// to arrive since other players might be slow, and then the server -// itself needs to check blockchain. - await recv(['restartround'], timeout: Duration(seconds: 2 * (Protocol.STANDARD_TIMEOUT.round() + Protocol.BLAME_VERIFY_TIME.round()))); - - return true; - } // end of runRound() function. - - - - -} // END OF CLASS - From bae46bb27d29cf6e64fd8a00a5dc47c97964e1de Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 8 Aug 2023 09:32:11 -0500 Subject: [PATCH 041/379] pass getUnusedReservedChangeAddresses to Fusion class --- lib/services/mixins/fusion_interface.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index 5ee14b93e..451db5588 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -104,7 +104,10 @@ mixin FusionInterface { void fuse() async { // Initial attempt for CashFusion integration goes here. Fusion mainFusionObject = Fusion( - createNewReservedChangeAddress: () => createNewReservedChangeAddress()); + createNewReservedChangeAddress: () => createNewReservedChangeAddress(), + getUnusedReservedChangeAddresses: (int numberOfAddresses) => + getUnusedReservedChangeAddresses(numberOfAddresses), + ); // add stack utxos List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); From e90fc3f27191c2ee1099aca9a8855c70f8a1021b Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 14 Aug 2023 11:00:35 -0500 Subject: [PATCH 042/379] remove misleading comment --- lib/services/mixins/fusion_interface.dart | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_interface.dart index 451db5588..e61a45665 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_interface.dart @@ -115,21 +115,6 @@ mixin FusionInterface { .map((e) => (txid: e.txid, vout: e.vout, value: e.value)) .toList()); - // TODO rework - // // add stack change address - // final String currentChangeAddress = await _getCurrentChangeAddress(); - // // cast from String to Address - // final Address? changeAddress = - // await _db.getAddress(_walletId, currentChangeAddress); - // // cast from Stack's Address to Fusiondart's Address - // final fusion_address.Address fusionChangeAddress = - // changeAddress!.toFusionAddress(); - // await mainFusionObject.addChangeAddress(fusionChangeAddress); - // Logging.instance.log( - // "FusionInterface fuse() changeAddress: $changeAddress", - // level: LogLevel.Info, - // ); - // fuse utxos await mainFusionObject.fusion_run(); //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); From 49ed035692df804f0d845a1dd9e2f321a10d8573 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 17 Aug 2023 17:09:45 -0500 Subject: [PATCH 043/379] implement blind signature request --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 90f4b458f..2893498ff 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 90f4b458f3883c0a381e0e6337b2ab462c2a1fac +Subproject commit 2893498ffee3e852d1d5c408bf2d8f3ba166e3ae From dd4955952d89db4a49faaa2670ac7485e1334a2d Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 18 Aug 2023 16:13:46 -0500 Subject: [PATCH 044/379] merge fusiondart#schnorr to fusiondart#staging --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 2893498ff..5094f0df4 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 2893498ffee3e852d1d5c408bf2d8f3ba166e3ae +Subproject commit 5094f0df4a51ba080bc6aa46b7cf0cef6d68665b From b5cef81bf712daec46ec890a0261e937a5b31ab7 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 21 Aug 2023 16:31:01 -0500 Subject: [PATCH 045/379] apply types, comments, warning reduction --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 5094f0df4..89ef6c98b 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 5094f0df4a51ba080bc6aa46b7cf0cef6d68665b +Subproject commit 89ef6c98b6a351f5d617836b86fa494900dfcf30 From 4821dfd795072a7ecc81b3f271edcd9cece1a03b Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 22 Aug 2023 17:52:41 -0500 Subject: [PATCH 046/379] impl BlindSignatureRequest: _calcInitial, jacobi, get request, finalize --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 89ef6c98b..01cce4a44 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 89ef6c98b6a351f5d617836b86fa494900dfcf30 +Subproject commit 01cce4a4443db6cb17967ba6b2b53dca3700abc6 From 5870417133d55440f64b0fe3e208e4ece25c33ef Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 23 Aug 2023 09:20:17 -0500 Subject: [PATCH 047/379] flutter pub add bip340 --- pubspec.lock | 8 ++++++++ pubspec.yaml | 1 + 2 files changed, 9 insertions(+) diff --git a/pubspec.lock b/pubspec.lock index ea3437af5..78444847c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -90,6 +90,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" + bip340: + dependency: "direct main" + description: + name: bip340 + sha256: "2a92f6ed68959f75d67c9a304c17928b9c9449587d4f75ee68f34152f7f69e87" + url: "https://pub.dev" + source: hosted + version: "0.2.0" bip39: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 056668440..7a218d72e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -141,6 +141,7 @@ dependencies: stellar_flutter_sdk: ^1.6.0 fusiondart: path: ./fusiondart + bip340: ^0.2.0 dev_dependencies: From 28a66a85cc4f832b894b49022592bb7247ea5d56 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 23 Aug 2023 10:12:08 -0500 Subject: [PATCH 048/379] use Util.bigIntToBytes --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 01cce4a44..d9f7ec135 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 01cce4a4443db6cb17967ba6b2b53dca3700abc6 +Subproject commit d9f7ec135b2613f30fcc6d6ab2509d5458dc2235 From a381cd0a47739bcd9570e1cf7781ebdbdf88a4d4 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 24 Aug 2023 11:22:13 -0500 Subject: [PATCH 049/379] FusionInterface->FusionWalletInterface a la PayNymWalletInterface (big ups, mad respec) --- lib/pages/cashfusion/cashfusion_view.dart | 6 +++--- .../cashfusion/desktop_cashfusion_view.dart | 4 ++-- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 4 ++-- lib/services/coins/manager.dart | 4 ++-- .../{fusion_interface.dart => fusion_wallet_interface.dart} | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) rename lib/services/mixins/{fusion_interface.dart => fusion_wallet_interface.dart} (99%) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index d7ef249a2..2d61828d4 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -12,7 +12,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; -import 'package:stackwallet/services/mixins/fusion_interface.dart'; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/show_loading.dart'; @@ -81,7 +81,7 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { (ref .read(walletsChangeNotifierProvider) .getManager(widget.walletId) - .wallet as FusionInterface) + .wallet as FusionWalletInterface) .refreshFusion() ]), context: context, @@ -113,7 +113,7 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { (ref .read(walletsChangeNotifierProvider) .getManager(widget.walletId) - .wallet as FusionInterface) + .wallet as FusionWalletInterface) .fuse() }, child: Text( diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 88da3b5f5..8e0d93ea9 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -12,7 +12,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; -import 'package:stackwallet/services/mixins/fusion_interface.dart'; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/text_styles.dart'; @@ -107,7 +107,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { (ref .read(walletsChangeNotifierProvider) .getManager(widget.walletId) - .wallet as FusionInterface) + .wallet as FusionWalletInterface) .fuse() }, child: Text( diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 3a6afbeed..9ac2164a6 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -38,7 +38,7 @@ import 'package:stackwallet/services/event_bus/events/global/updated_in_backgrou import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/services/mixins/coin_control_interface.dart'; -import 'package:stackwallet/services/mixins/fusion_interface.dart'; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/services/mixins/wallet_cache.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/mixins/xpubable.dart'; @@ -114,7 +114,7 @@ String constructDerivePath({ } class BitcoinCashWallet extends CoinServiceAPI - with WalletCache, WalletDB, CoinControlInterface, FusionInterface + with WalletCache, WalletDB, CoinControlInterface, FusionWalletInterface implements XPubAble { BitcoinCashWallet({ required String walletId, diff --git a/lib/services/coins/manager.dart b/lib/services/coins/manager.dart index f40b23cc6..d94f7a99e 100644 --- a/lib/services/coins/manager.dart +++ b/lib/services/coins/manager.dart @@ -21,8 +21,8 @@ import 'package:stackwallet/services/event_bus/events/global/node_connection_sta import 'package:stackwallet/services/event_bus/events/global/updated_in_background_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/services/mixins/coin_control_interface.dart'; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/services/mixins/ordinals_interface.dart'; -import 'package:stackwallet/services/mixins/fusion_interface.dart'; import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/services/mixins/xpubable.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; @@ -252,7 +252,7 @@ class Manager with ChangeNotifier { bool get hasWhirlpoolSupport => false; - bool get hasFusionSupport => _currentWallet is FusionInterface; + bool get hasFusionSupport => _currentWallet is FusionWalletInterface; int get rescanOnOpenVersion => DB.instance.get<dynamic>( diff --git a/lib/services/mixins/fusion_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart similarity index 99% rename from lib/services/mixins/fusion_interface.dart rename to lib/services/mixins/fusion_wallet_interface.dart index e61a45665..519a72a2d 100644 --- a/lib/services/mixins/fusion_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -10,7 +10,7 @@ import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; const String kReservedFusionAddress = "reserved_fusion_address"; -mixin FusionInterface { +mixin FusionWalletInterface { // passed in wallet data late final String _walletId; late final Coin _coin; From 5f1e9364351d0c52b3f0bd73b9ef4fa670716fa1 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 25 Aug 2023 13:50:18 -0500 Subject: [PATCH 050/379] WIP refactoring, documentation, comments, warning reduction, formatting --- fusiondart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/fusiondart b/fusiondart index d9f7ec135..e260d0151 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit d9f7ec135b2613f30fcc6d6ab2509d5458dc2235 +Subproject commit e260d01513dc8bce1ba3e3fc67a21fa94b4e5854 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 519a72a2d..0bb648b82 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -111,12 +111,11 @@ mixin FusionWalletInterface { // add stack utxos List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); - await mainFusionObject.add_coins_from_wallet(utxos - .map((e) => (txid: e.txid, vout: e.vout, value: e.value)) - .toList()); + await mainFusionObject.addCoinsFromWallet( + utxos.map((e) => (e.txid, e.vout, e.value)).toList()); // fuse utxos - await mainFusionObject.fusion_run(); + await mainFusionObject.fuse(); //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); /* From aba37faacb94dfc221c60967068471756b4b76cd Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 30 Aug 2023 11:40:39 -0500 Subject: [PATCH 051/379] WIP join session, return early from covert TODO fix `pubKey`s, `amount`s, etc passed in as 0000 or String? (whereas parameter is String for example, ie null awareness/safety) Can instantiate a cached electrum client and call eg txid for info missing from the transaction blockchain model --- fusiondart | 2 +- lib/db/isar/main_db.dart | 8 +++ .../models/blockchain_data/transaction.dart | 36 ++++++++++- .../isar/models/blockchain_data/utxo.dart | 13 ++++ .../mixins/fusion_wallet_interface.dart | 63 ++++++++++++++++--- 5 files changed, 111 insertions(+), 11 deletions(-) diff --git a/fusiondart b/fusiondart index e260d0151..527a80ff1 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit e260d01513dc8bce1ba3e3fc67a21fa94b4e5854 +Subproject commit 527a80ff1ff65f6e0e7450867dbda2cf642c12b6 diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart index 9465de12b..796914117 100644 --- a/lib/db/isar/main_db.dart +++ b/lib/db/isar/main_db.dart @@ -241,6 +241,14 @@ class MainDB { QueryBuilder<UTXO, UTXO, QAfterWhereClause> getUTXOs(String walletId) => isar.utxos.where().walletIdEqualTo(walletId); + QueryBuilder<UTXO, UTXO, QAfterFilterCondition> getUTXOsByAddress( + String walletId, String address) => + isar.utxos + .where() + .walletIdEqualTo(walletId) + .filter() + .addressEqualTo(address); + Future<void> putUTXO(UTXO utxo) => isar.writeTxn(() async { await isar.utxos.put(utxo); }); diff --git a/lib/models/isar/models/blockchain_data/transaction.dart b/lib/models/isar/models/blockchain_data/transaction.dart index 5b32142c2..c52f584fc 100644 --- a/lib/models/isar/models/blockchain_data/transaction.dart +++ b/lib/models/isar/models/blockchain_data/transaction.dart @@ -11,6 +11,10 @@ import 'dart:convert'; import 'dart:math'; +import 'package:fusiondart/src/models/address.dart' as fusion_address; +import 'package:fusiondart/src/models/input.dart' as fusion_input; +import 'package:fusiondart/src/models/output.dart' as fusion_output; +import 'package:fusiondart/src/models/transaction.dart' as fusion_tx; import 'package:isar/isar.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/address.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/input.dart'; @@ -22,7 +26,6 @@ part 'transaction.g.dart'; @Collection() class Transaction { - Transaction({ required this.walletId, required this.txid, @@ -232,6 +235,37 @@ class Transaction { return Tuple2(transaction, address); } } + + // Convert to fusiondart's Transaction type. + fusion_tx.Transaction toFusionTransaction() { + // Initialize Fusion Dart's Transaction object. + fusion_tx.Transaction fusionTransaction = fusion_tx.Transaction(); + + // Map the Inputs and Outputs to Fusion Dart's format + fusionTransaction.Inputs = inputs + .map((e) => fusion_input.Input( + prevTxid: utf8.encode(e.txid), + prevIndex: e.vout, + pubKey: utf8.encode(e.witness), // TODO fix + amount: 0, // TODO fix + )) + .toList(); + + fusionTransaction.Outputs = outputs + .map((e) => fusion_output.Output( + addr: fusion_address.Address( + addr: e.scriptPubKeyAddress, + publicKey: utf8.encode(e.scriptPubKey), + derivationPath: fusion_address.DerivationPath(), // TODO fix + ), + value: e.value, + )) + .toList(); + + // If any other information needs to be altered/added, do so here. + + return fusionTransaction; + } } // Used in Isar db and stored there as int indexes so adding/removing values diff --git a/lib/models/isar/models/blockchain_data/utxo.dart b/lib/models/isar/models/blockchain_data/utxo.dart index 3a87957f0..4c5f5718f 100644 --- a/lib/models/isar/models/blockchain_data/utxo.dart +++ b/lib/models/isar/models/blockchain_data/utxo.dart @@ -8,8 +8,10 @@ * */ +import 'dart:convert'; import 'dart:math'; +import 'package:fusiondart/src/models/input.dart' as FusionInput; import 'package:isar/isar.dart'; part 'utxo.g.dart'; @@ -145,3 +147,14 @@ class UTXO { @ignore int get hashCode => Object.hashAll([walletId, txid, vout]); } + +extension ToFusionInput on UTXO { + FusionInput.Input toFusionInput({required List<int> pubKey}) { + return FusionInput.Input( + prevTxid: utf8.encode(txid), + prevIndex: vout, + pubKey: pubKey, + amount: value, + ); + } +} diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 0bb648b82..265ea8798 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -1,7 +1,10 @@ +import 'dart:convert'; import 'dart:io'; import 'package:fusiondart/fusiondart.dart'; -import 'package:fusiondart/src/models/address.dart' as cash_fusion; +import 'package:fusiondart/src/models/address.dart' as fusion_address; +import 'package:fusiondart/src/models/input.dart' as fusion_input; +import 'package:fusiondart/src/models/transaction.dart' as fusion_tx; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; @@ -39,7 +42,30 @@ mixin FusionWalletInterface { _generateAddressForChain = generateAddressForChain; } - Future<cash_fusion.Address> createNewReservedChangeAddress() async { + Future<List<fusion_address.Address>> getFusionAddresses() async { + List<Address> _addresses = await _db.getAddresses(_walletId).findAll(); + return _addresses.map((address) => address.toFusionAddress()).toList(); + } + + Future<Set<fusion_tx.Transaction>> getTransactionsByAddress( + String address) async { + var _txs = await _db.getTransactions(_walletId).findAll(); + + return _txs + .map((tx) => tx.toFusionTransaction()) + .toSet(); // TODO feed in proper public key + } + + Future<List<fusion_input.Input>> getInputsByAddress(String address) async { + var _utxos = await _db.getUTXOsByAddress(_walletId, address).findAll(); + + return _utxos + .map((utxo) => utxo.toFusionInput( + pubKey: utf8.encode('0000'))) // TODO feed in proper public key + .toList(); + } + + Future<fusion_address.Address> createNewReservedChangeAddress() async { int? highestChangeIndex = await _db .getAddresses(_walletId) .filter() @@ -57,14 +83,20 @@ mixin FusionWalletInterface { ); address = address.copyWith(otherData: kReservedFusionAddress); - // TODO if we really want to be sure its not used, call electrumx and check it + // TODO if we really want to be sure it's not used, call electrumx and check it - await _db.putAddress(address); + Address? _address = await _db.getAddress(_walletId, address.value); + if (_address != null) { + // throw Exception("Address already exists"); + await _db.updateAddress(_address, address); + } else { + await _db.putAddress(address); + } return address.toFusionAddress(); } - Future<List<cash_fusion.Address>> getUnusedReservedChangeAddresses( + Future<List<fusion_address.Address>> getUnusedReservedChangeAddresses( int numberOfAddresses, ) async { final txns = await _db @@ -84,7 +116,7 @@ mixin FusionWalletInterface { .otherDataEqualTo(kReservedFusionAddress) .findAll(); - final List<cash_fusion.Address> unusedAddresses = []; + final List<fusion_address.Address> unusedAddresses = []; for (final address in addresses) { if (!usedAddresses.contains(address.value)) { @@ -104,17 +136,30 @@ mixin FusionWalletInterface { void fuse() async { // Initial attempt for CashFusion integration goes here. Fusion mainFusionObject = Fusion( - createNewReservedChangeAddress: () => createNewReservedChangeAddress(), + getAddresses: () => getFusionAddresses(), + getTransactionsByAddress: (String address) => + getTransactionsByAddress(address), + getInputsByAddress: (String address) => getInputsByAddress(address), + // createNewReservedChangeAddress: () => createNewReservedChangeAddress(), getUnusedReservedChangeAddresses: (int numberOfAddresses) => getUnusedReservedChangeAddresses(numberOfAddresses), ); - // add stack utxos + // Pass wallet functions to the Fusion object + mainFusionObject.initFusion( + getAddresses: getFusionAddresses, + getTransactionsByAddress: getTransactionsByAddress, + getInputsByAddress: getInputsByAddress, + /*createNewReservedChangeAddress: createNewReservedChangeAddress,*/ + getUnusedReservedChangeAddresses: getUnusedReservedChangeAddresses); + + // Add stack UTXOs. List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); + await mainFusionObject.addCoinsFromWallet( utxos.map((e) => (e.txid, e.vout, e.value)).toList()); - // fuse utxos + // Fuse UTXOs. await mainFusionObject.fuse(); //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); From 47fd03817a75be2d660cd22cd19440e407605a90 Mon Sep 17 00:00:00 2001 From: Josh Babb <sneurlax@gmail.com> Date: Thu, 14 Sep 2023 15:45:30 -0500 Subject: [PATCH 052/379] fix stellar_flutter_sdk dep --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 352d6f09c..d1fc2d154 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -141,7 +141,7 @@ dependencies: desktop_drop: ^0.4.1 nanodart: ^2.0.0 basic_utils: ^5.5.4 - stellar_flutter_sdk: ^1.6.0 + stellar_flutter_sdk: ^1.5.3 fusiondart: path: ./fusiondart bip340: ^0.2.0 From ba826d28edd01b1ec7779a2658bb9478eb21bda4 Mon Sep 17 00:00:00 2001 From: Josh Babb <sneurlax@gmail.com> Date: Thu, 14 Sep 2023 16:05:54 -0500 Subject: [PATCH 053/379] "fix" toFusion methods this isn't a fix really, more TODO --- lib/models/isar/models/blockchain_data/transaction.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/transaction.dart b/lib/models/isar/models/blockchain_data/transaction.dart index c52f584fc..46e784eac 100644 --- a/lib/models/isar/models/blockchain_data/transaction.dart +++ b/lib/models/isar/models/blockchain_data/transaction.dart @@ -246,7 +246,7 @@ class Transaction { .map((e) => fusion_input.Input( prevTxid: utf8.encode(e.txid), prevIndex: e.vout, - pubKey: utf8.encode(e.witness), // TODO fix + pubKey: utf8.encode(e.witness ?? ""), // TODO fix amount: 0, // TODO fix )) .toList(); @@ -255,8 +255,8 @@ class Transaction { .map((e) => fusion_output.Output( addr: fusion_address.Address( addr: e.scriptPubKeyAddress, - publicKey: utf8.encode(e.scriptPubKey), - derivationPath: fusion_address.DerivationPath(), // TODO fix + publicKey: utf8.encode(e.scriptPubKey ?? ""), // TODO fix + derivationPath: fusion_address.DerivationPath("m/49'/0'/0'/0/0"), // TODO fix ), value: e.value, )) From 1f1ceaae5af18ba660e84abfdcb7149ba8c61932 Mon Sep 17 00:00:00 2001 From: Josh Babb <sneurlax@gmail.com> Date: Thu, 14 Sep 2023 16:11:27 -0500 Subject: [PATCH 054/379] update fusiondart ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 527a80ff1..04c8bd01b 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 527a80ff1ff65f6e0e7450867dbda2cf642c12b6 +Subproject commit 04c8bd01b1982d1543f3f0a2554361056eb7ef38 From fafdb45e48cfcaa03e9aa21d8e720797d6afa726 Mon Sep 17 00:00:00 2001 From: Josh Babb <sneurlax@gmail.com> Date: Thu, 14 Sep 2023 17:28:11 -0500 Subject: [PATCH 055/379] add getSocksProxyAddress passin, documentation, and comments --- fusiondart | 2 +- .../mixins/fusion_wallet_interface.dart | 74 +++++++++++++++++-- lib/services/tor_service.dart | 2 + 3 files changed, 71 insertions(+), 7 deletions(-) diff --git a/fusiondart b/fusiondart index 04c8bd01b..fb563fb37 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 04c8bd01b1982d1543f3f0a2554361056eb7ef38 +Subproject commit fb563fb37b0867cd1ada29e0b956778836049ebe diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 265ea8798..90bfa7c57 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:convert'; import 'dart:io'; @@ -11,15 +12,20 @@ import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +import 'package:stackwallet/services/tor_service.dart'; + const String kReservedFusionAddress = "reserved_fusion_address"; + +/// A mixin for the BitcoinCashWallet class that adds CashFusion functionality. mixin FusionWalletInterface { - // passed in wallet data + // Passed in wallet data. late final String _walletId; late final Coin _coin; late final MainDB _db; + late final TorService _torService; - // passed in wallet functions + // Passed in wallet functions. late final Future<Address> Function( int chain, int index, @@ -40,13 +46,29 @@ mixin FusionWalletInterface { _coin = coin; _db = db; _generateAddressForChain = generateAddressForChain; + _torService = TorService.sharedInstance; + + // Start the Tor service if it's not already running. + if (_torService.proxyInfo.port == -1) { // -1 indicates that the proxy is not running. + // Initialize the ffi lib instance if it hasn't already been set. + _torService.init(); + + // Start the Tor service. + // + // TODO should we await this? At this point I don't want to make this init function async. + // The risk would be that the Tor service is not started before the Fusion library tries to + // connect to it. + unawaited(_torService.start()); + } } + /// Returns a list of all addresses in the wallet. Future<List<fusion_address.Address>> getFusionAddresses() async { List<Address> _addresses = await _db.getAddresses(_walletId).findAll(); return _addresses.map((address) => address.toFusionAddress()).toList(); } + /// Returns a list of all transactions in the wallet for the given address. Future<Set<fusion_tx.Transaction>> getTransactionsByAddress( String address) async { var _txs = await _db.getTransactions(_walletId).findAll(); @@ -56,6 +78,7 @@ mixin FusionWalletInterface { .toSet(); // TODO feed in proper public key } + /// Returns a list of all UTXOs in the wallet for the given address. Future<List<fusion_input.Input>> getInputsByAddress(String address) async { var _utxos = await _db.getUTXOsByAddress(_walletId, address).findAll(); @@ -65,6 +88,7 @@ mixin FusionWalletInterface { .toList(); } + /// Creates a new reserved change address. Future<fusion_address.Address> createNewReservedChangeAddress() async { int? highestChangeIndex = await _db .getAddresses(_walletId) @@ -96,44 +120,78 @@ mixin FusionWalletInterface { return address.toFusionAddress(); } + /// Returns a list of unused reserved change addresses. + /// + /// If there are not enough unused reserved change addresses, new ones are created. Future<List<fusion_address.Address>> getUnusedReservedChangeAddresses( int numberOfAddresses, ) async { + // Fetch all transactions that have been sent to a reserved change address. final txns = await _db .getTransactions(_walletId) .filter() .address((q) => q.otherDataEqualTo(kReservedFusionAddress)) .findAll(); + // Fetch all addresses that have been used in a transaction. final List<String> usedAddresses = txns .where((e) => e.address.value != null) .map((e) => e.address.value!.value) .toList(growable: false); + // Fetch all reserved change addresses. final List<Address> addresses = await _db .getAddresses(_walletId) .filter() .otherDataEqualTo(kReservedFusionAddress) .findAll(); + // Initialize a list of unused reserved change addresses. final List<fusion_address.Address> unusedAddresses = []; + // Add any unused reserved change addresses to the list. for (final address in addresses) { if (!usedAddresses.contains(address.value)) { unusedAddresses.add(address.toFusionAddress()); } } + // If there are not enough unused reserved change addresses, create new ones. if (unusedAddresses.length < numberOfAddresses) { for (int i = unusedAddresses.length; i < numberOfAddresses; i++) { unusedAddresses.add(await createNewReservedChangeAddress()); } } + // Return the list of unused reserved change addresses. return unusedAddresses; } - void fuse() async { + /// Returns the current Tor proxy address. + Future<({InternetAddress host, int port})> getSocksProxyAddress() async { + /* + // Start the Tor service if it's not already running. + if (_torService.proxyInfo.port == -1) { // -1 indicates that the proxy is not running. + await _torService.start(); // We already unawaited this in initFusionInterface... + } + */ + + // TODO make sure we've properly awaited the Tor service starting before + // returning the proxy address. + + // Return the proxy address. + return _torService.proxyInfo; + } + + // Initial attempt for CashFusion integration goes here. + + /// Fuse the wallet's UTXOs. + /// + /// This function is called when the user taps the "Fuse" button in the UI. + /// + /// Returns: + /// A `Future<void>` that resolves when the fusion operation is finished. + Future<void> fuse() async { // Initial attempt for CashFusion integration goes here. Fusion mainFusionObject = Fusion( getAddresses: () => getFusionAddresses(), @@ -143,6 +201,7 @@ mixin FusionWalletInterface { // createNewReservedChangeAddress: () => createNewReservedChangeAddress(), getUnusedReservedChangeAddresses: (int numberOfAddresses) => getUnusedReservedChangeAddresses(numberOfAddresses), + getSocksProxyAddress: () => getSocksProxyAddress(), ); // Pass wallet functions to the Fusion object @@ -151,7 +210,8 @@ mixin FusionWalletInterface { getTransactionsByAddress: getTransactionsByAddress, getInputsByAddress: getInputsByAddress, /*createNewReservedChangeAddress: createNewReservedChangeAddress,*/ - getUnusedReservedChangeAddresses: getUnusedReservedChangeAddresses); + getUnusedReservedChangeAddresses: getUnusedReservedChangeAddresses, + getSocksProxyAddress: getSocksProxyAddress); // Add stack UTXOs. List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); @@ -160,9 +220,11 @@ mixin FusionWalletInterface { utxos.map((e) => (e.txid, e.vout, e.value)).toList()); // Fuse UTXOs. - await mainFusionObject.fuse(); + return await mainFusionObject.fuse(); //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); + // TODO remove or fix code below. + /* print("DEBUG: Waiting for any potential incoming data..."); try { @@ -172,7 +234,6 @@ mixin FusionWalletInterface { print (e); } print("DEBUG: Done waiting."); - */ bool mydebug1 = false; if (mydebug1 == true) { @@ -258,6 +319,7 @@ mixin FusionWalletInterface { // await _checkCurrentChangeAddressesForTransactions(); // await _checkCurrentReceivingAddressesForTransactions(); + */ } Future<void> refreshFusion() { diff --git a/lib/services/tor_service.dart b/lib/services/tor_service.dart index ead6ab5fa..1f6e2a8eb 100644 --- a/lib/services/tor_service.dart +++ b/lib/services/tor_service.dart @@ -25,6 +25,8 @@ class TorService { static final sharedInstance = TorService._(); /// Getter for the proxyInfo. + /// + /// Returns a Map with the host and port of the Tor proxy. ({ InternetAddress host, int port, From e17366071587e327e3a71a10bcf2ef18ee038153 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 15 Sep 2023 14:21:36 -0500 Subject: [PATCH 056/379] formatting --- lib/services/mixins/fusion_wallet_interface.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 90bfa7c57..0ddcfa208 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -9,14 +9,12 @@ import 'package:fusiondart/src/models/transaction.dart' as fusion_tx; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; -import 'package:stackwallet/services/tor_service.dart'; - const String kReservedFusionAddress = "reserved_fusion_address"; - /// A mixin for the BitcoinCashWallet class that adds CashFusion functionality. mixin FusionWalletInterface { // Passed in wallet data. From a220b76c3426167d33ff0e064b4b4a25c3854aee Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 15 Sep 2023 14:22:05 -0500 Subject: [PATCH 057/379] add todo note about fusion tor service --- lib/services/mixins/fusion_wallet_interface.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 0ddcfa208..8f1689d84 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -47,7 +47,10 @@ mixin FusionWalletInterface { _torService = TorService.sharedInstance; // Start the Tor service if it's not already running. - if (_torService.proxyInfo.port == -1) { // -1 indicates that the proxy is not running. + // TODO fix this. It will cause all Stack Wallet traffic to start being routed + // through Tor, which is not what we want. + if (_torService.proxyInfo.port == -1) { + // -1 indicates that the proxy is not running. // Initialize the ffi lib instance if it hasn't already been set. _torService.init(); From b2203a6cc76be1f6b9e13ddca9281757f3726073 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 15 Sep 2023 16:01:23 -0500 Subject: [PATCH 058/379] resolve the futures --- lib/services/tor_service.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/services/tor_service.dart b/lib/services/tor_service.dart index c4e7a0117..52af4ed7e 100644 --- a/lib/services/tor_service.dart +++ b/lib/services/tor_service.dart @@ -79,6 +79,9 @@ class TorService { status: TorConnectionStatus.connected, message: "TorService.start call success", ); + + // Complete the future. + return; } catch (e, s) { Logging.instance.log( "TorService.start failed: $e\n$s", @@ -110,6 +113,8 @@ class TorService { status: TorConnectionStatus.disconnected, message: "TorService.disable call success", ); + + return; } void _updateStatusAndFireEvent({ From ea223ff7cddc1d4076a2230221217c8abaf43a23 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 15 Sep 2023 16:01:31 -0500 Subject: [PATCH 059/379] docs --- lib/services/tor_service.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/services/tor_service.dart b/lib/services/tor_service.dart index 52af4ed7e..3458f1612 100644 --- a/lib/services/tor_service.dart +++ b/lib/services/tor_service.dart @@ -12,7 +12,7 @@ class TorService { Tor? _tor; String? _torDataDirPath; - /// Current status. Same as that fired on the event bus + /// Current status. Same as that fired on the event bus. TorConnectionStatus get status => _status; TorConnectionStatus _status = TorConnectionStatus.disconnected; @@ -26,7 +26,7 @@ class TorService { /// Getter for the proxyInfo. /// - /// Returns null if disabled on the stack wallet level. + /// Throws if Tor is not connected. ({ InternetAddress host, int port, @@ -55,7 +55,8 @@ class TorService { /// /// This will start the Tor service and establish a Tor circuit. /// - /// Throws an exception if the Tor service fails to start. + /// Throws an exception if the Tor library was not inited or if the Tor + /// service fails to start. /// /// Returns a Future that completes when the Tor service has started. Future<void> start() async { From 2dcb82f049bb5871cc73076aad88282789876ff5 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 15 Sep 2023 16:02:25 -0500 Subject: [PATCH 060/379] update tor handling in fusion wallet interface removed inaccurate comments ... Stack shouldn't use Tor unless useTor --- .../mixins/fusion_wallet_interface.dart | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 8f1689d84..de2a5bdbc 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -12,6 +12,7 @@ import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +import 'package:stackwallet/utilities/stack_file_system.dart'; const String kReservedFusionAddress = "reserved_fusion_address"; @@ -30,7 +31,12 @@ mixin FusionWalletInterface { DerivePathType derivePathType, ) _generateAddressForChain; - void initFusionInterface({ + /// Initializes the FusionWalletInterface mixin. + /// + /// This function must be called before any other functions in this mixin. + /// + /// Returns a `Future<void>` that resolves when Tor has been started. + Future<void> initFusionInterface({ required String walletId, required Coin coin, required MainDB db, @@ -39,27 +45,29 @@ mixin FusionWalletInterface { int, DerivePathType, ) generateAddressForChain, - }) { + }) async { + // Set passed in wallet data. _walletId = walletId; _coin = coin; _db = db; _generateAddressForChain = generateAddressForChain; _torService = TorService.sharedInstance; - // Start the Tor service if it's not already running. - // TODO fix this. It will cause all Stack Wallet traffic to start being routed - // through Tor, which is not what we want. - if (_torService.proxyInfo.port == -1) { - // -1 indicates that the proxy is not running. - // Initialize the ffi lib instance if it hasn't already been set. - _torService.init(); + // Try getting the proxy info. + // + // Start the Tor service if it's not already running. Returns if Tor is already + // connected or else after Tor returns from start(). + try { + _torService.getProxyInfo(); + // Proxy info successfully retrieved, Tor is connected. + return; + } catch (e) { + // Init the Tor service if it hasn't already been. + final torDir = await StackFileSystem.applicationTorDirectory(); + _torService.init(torDataDirPath: torDir.path); // Start the Tor service. - // - // TODO should we await this? At this point I don't want to make this init function async. - // The risk would be that the Tor service is not started before the Fusion library tries to - // connect to it. - unawaited(_torService.start()); + return await _torService.start(); } } @@ -181,7 +189,7 @@ mixin FusionWalletInterface { // returning the proxy address. // Return the proxy address. - return _torService.proxyInfo; + return _torService.getProxyInfo(); } // Initial attempt for CashFusion integration goes here. From 346d255280a202347d32e2d2dea97aa793a08366 Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Fri, 15 Sep 2023 12:57:01 -0600 Subject: [PATCH 061/379] WIP: cashfusion ui; app bar and text card --- .../cashfusion/desktop_cashfusion_view.dart | 167 ++++++++++++------ 1 file changed, 111 insertions(+), 56 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 8e0d93ea9..352b19f15 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -19,6 +19,7 @@ import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; class DesktopCashFusionView extends ConsumerStatefulWidget { const DesktopCashFusionView({ @@ -55,67 +56,121 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { isCompactHeight: true, useSpacers: false, leading: Expanded( - child: Row( - children: [ - const SizedBox( - width: 32, - ), - AppBarIconButton( - size: 32, - color: Theme.of(context) - .extension<StackColors>()! - .textFieldDefaultBG, - shadows: const [], - icon: SvgPicture.asset( - Assets.svg.arrowLeft, - width: 18, - height: 18, - color: Theme.of(context) - .extension<StackColors>()! - .topNavIconPrimary, + child: Padding( + padding: const EdgeInsets.all(24.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + // const SizedBox( + // width: 32, + // ), + AppBarIconButton( + size: 32, + color: Theme.of(context) + .extension<StackColors>()! + .textFieldDefaultBG, + shadows: const [], + icon: SvgPicture.asset( + Assets.svg.arrowLeft, + width: 18, + height: 18, + color: Theme.of(context) + .extension<StackColors>()! + .topNavIconPrimary, + ), + onPressed: Navigator.of(context).pop, + ), + const SizedBox( + width: 15, + ), + SvgPicture.asset( + Assets.svg.cashFusion, + width: 32, + height: 32, + ), + const SizedBox( + width: 12, + ), + Text( + "CashFusion", + style: STextStyles.desktopH3(context), + ), + ], ), - onPressed: Navigator.of(context).pop, - ), - const SizedBox( - width: 15, - ), - SvgPicture.asset( - Assets.svg.cashFusion, - width: 32, - height: 32, - ), - const SizedBox( - width: 12, - ), - Text( - "CashFusion", - style: STextStyles.desktopH3(context), - ) - ], + MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () {}, + child: Row( + children: [ + SvgPicture.asset( + Assets.svg.circleQuestion, + color: Theme.of(context) + .extension<StackColors>()! + .radioButtonIconBorder, + ), + const SizedBox( + width: 6, + ), + RichText( + text: TextSpan( + text: "What is CashFusion?", + style: STextStyles.richLink(context).copyWith( + fontSize: 16, + ), + ), + ), + ], + ), + ), + ), + ], + ), ), ), ), - body: Padding( - padding: const EdgeInsets.all(24), - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Text("TODO FusionParticipantList"), - const SizedBox( - height: 16, - ), - TextButton( - onPressed: () => { - (ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface) - .fuse() - }, - child: Text( - "Fuse", - style: STextStyles.desktopTextMedium(context), + body: Row( + children: [ + Padding( + padding: const EdgeInsets.all(24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 460, + child: RoundedWhiteContainer( + child: Row( + children: [ + Text( + "CashFustion allows you to anonymize your BCH coins." + "\nYou must be connected to the Tor network."), + ], + ), + ), + ), + const Text("TODO FusionParticipantList"), + const SizedBox( + height: 16, + ), + TextButton( + onPressed: () => { + (ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface) + .fuse() + }, + child: Text( + "Fuse", + style: STextStyles.desktopTextMedium(context), + ), + ), + ], ), - ) - ]), + ), + ], ), ); } From ecb6860e39e5d15e210a142056128038d6e2aa09 Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Fri, 15 Sep 2023 16:38:35 -0600 Subject: [PATCH 062/379] WIP: cashfusion card, server settings and rounds of fusion --- .../cashfusion/desktop_cashfusion_view.dart | 276 ++++++++++++++++-- 1 file changed, 258 insertions(+), 18 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 352b19f15..abc238d2b 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -11,15 +11,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:stackwallet/providers/global/wallets_provider.dart'; -import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; +import 'package:stackwallet/providers/ui/check_box_state_provider.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:stackwallet/widgets/stack_text_field.dart'; class DesktopCashFusionView extends ConsumerStatefulWidget { const DesktopCashFusionView({ @@ -36,13 +38,44 @@ class DesktopCashFusionView extends ConsumerStatefulWidget { } class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { + late final TextEditingController serverController; + late final FocusNode serverFocusNode; + late final TextEditingController portController; + late final FocusNode portFocusNode; + + String _serverTerm = ""; + String _portTerm = ""; + + bool _useSSL = false; + bool _trusted = false; + int? port; + late bool enableSSLCheckbox; + + late final bool enableAuthFields; + + void _updateState() {} + @override void initState() { + serverController = TextEditingController(); + portController = TextEditingController(); + + serverFocusNode = FocusNode(); + portFocusNode = FocusNode(); + + enableSSLCheckbox = true; + super.initState(); } @override void dispose() { + serverController.dispose(); + portController.dispose(); + + serverFocusNode.dispose(); + portFocusNode.dispose(); + super.dispose(); } @@ -112,7 +145,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { .radioButtonIconBorder, ), const SizedBox( - width: 6, + width: 8, ), RichText( text: TextSpan( @@ -144,27 +177,234 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { child: Row( children: [ Text( - "CashFustion allows you to anonymize your BCH coins." - "\nYou must be connected to the Tor network."), + "CashFusion allows you to anonymize your BCH coins." + "\nYou must be connected to the Tor network.", + style: + STextStyles.desktopTextExtraExtraSmall(context), + ), ], ), ), ), - const Text("TODO FusionParticipantList"), const SizedBox( - height: 16, + height: 24, ), - TextButton( - onPressed: () => { - (ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface) - .fuse() - }, - child: Text( - "Fuse", - style: STextStyles.desktopTextMedium(context), + SizedBox( + width: 460, + child: RoundedWhiteContainer( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Server settings", + style: + STextStyles.desktopTextExtraExtraSmall(context), + ), + const SizedBox( + height: 12, + ), + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: false, + enableSuggestions: false, + controller: serverController, + focusNode: serverFocusNode, + onChanged: (value) { + setState(() { + _serverTerm = value; + }); + }, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "Server", + serverFocusNode, + context, + desktopMed: true, + ) + // .copyWith(labelStyle: ), + ), + ), + const SizedBox( + height: 12, + ), + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: false, + enableSuggestions: false, + controller: portController, + focusNode: portFocusNode, + onChanged: (value) { + setState(() { + _portTerm = value; + }); + }, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "Port", + portFocusNode, + context, + desktopMed: true, + ), + ), + ), + const SizedBox( + height: 12, + ), + GestureDetector( + onTap: () { + final value = + ref.read(checkBoxStateProvider.state).state; + ref.read(checkBoxStateProvider.state).state = + !value; + }, + child: Container( + color: Colors.transparent, + child: Row( + children: [ + SizedBox( + width: 20, + height: 20, + child: Checkbox( + // fillColor: enableSSLCheckbox + // ? null + // : MaterialStateProperty.all( + // Theme.of(context) + // .extension<StackColors>()! + // .checkboxBGDisabled), + materialTapTargetSize: + MaterialTapTargetSize.shrinkWrap, + value: ref + .watch(checkBoxStateProvider.state) + .state, + onChanged: (newValue) { + ref + .watch(checkBoxStateProvider.state) + .state = newValue!; + }, + ), + ), + const SizedBox( + width: 12, + ), + Text( + "Use SSL", + style: STextStyles.itemSubtitle12(context), + ), + ], + ), + ), + ), + const SizedBox( + height: 20, + ), + Text( + "Rounds of fusion", + style: + STextStyles.desktopTextExtraExtraSmall(context), + ), + const SizedBox( + height: 10, + ), + Stack( + children: [ + TextField( + autocorrect: false, + enableSuggestions: false, + readOnly: true, + textInputAction: TextInputAction.none, + style: STextStyles.desktopTextFieldLabel(context) + .copyWith( + fontSize: 16, + ), + decoration: const InputDecoration( + contentPadding: EdgeInsets.symmetric( + vertical: 18, + horizontal: 16, + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 12, + ), + child: RawMaterialButton( + splashColor: Theme.of(context) + .extension<StackColors>()! + .highlight, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + onPressed: () {}, + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + "Continuous", + style: + STextStyles.itemSubtitle12(context), + ), + SvgPicture.asset( + Assets.svg.chevronDown, + width: 8, + height: 4, + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle2, + ), + ], + ), + ), + ), + ], + ), + const SizedBox( + height: 20, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Tor status", + style: STextStyles.desktopTextExtraExtraSmall( + context), + ), + Text( + "Disconnect", + style: STextStyles.richLink(context).copyWith( + fontSize: 14, + ), + ), + ], + ), + const SizedBox( + height: 10, + ), + RoundedWhiteContainer( + borderColor: Theme.of(context) + .extension<StackColors>()! + .shadow, + child: Row( + children: [], + ), + ), + const SizedBox( + height: 20, + ), + PrimaryButton( + label: "Start", + onPressed: () {}, + ), + ], + ), ), ), ], From 4695ed2b8fe5b697730669948665481a964e72c4 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 15 Sep 2023 17:41:17 -0500 Subject: [PATCH 063/379] progress cashfusion into startround phase --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index fb563fb37..102a596d6 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit fb563fb37b0867cd1ada29e0b956778836049ebe +Subproject commit 102a596d633e00799ffd7ea82e83a02f8a14d984 From 7c4d3038ad230f1efa4ce1b293cf5202330c8664 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 18 Sep 2023 11:13:50 -0500 Subject: [PATCH 064/379] remove tor as submodule --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 3aa333e4a..cf4975167 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,9 +7,6 @@ [submodule "crypto_plugins/flutter_liblelantus"] path = crypto_plugins/flutter_liblelantus url = https://github.com/cypherstack/flutter_liblelantus.git -[submodule "crypto_plugins/tor"] - path = crypto_plugins/tor - url = https://github.com/cypherstack/tor.git [submodule "fusiondart"] path = fusiondart url = https://github.com/cypherstack/fusiondart.git From 289a36996536d64cb2b1fca94be2a44e0eaee85d Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 18 Sep 2023 14:02:15 -0500 Subject: [PATCH 065/379] add derivationPath with hack. needs null safety checks --- lib/models/isar/models/blockchain_data/transaction.dart | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/transaction.dart b/lib/models/isar/models/blockchain_data/transaction.dart index 46e784eac..86c6d8d76 100644 --- a/lib/models/isar/models/blockchain_data/transaction.dart +++ b/lib/models/isar/models/blockchain_data/transaction.dart @@ -246,7 +246,7 @@ class Transaction { .map((e) => fusion_input.Input( prevTxid: utf8.encode(e.txid), prevIndex: e.vout, - pubKey: utf8.encode(e.witness ?? ""), // TODO fix + pubKey: utf8.encode(e.witness ?? ""), // TODO fix or failsafe. amount: 0, // TODO fix )) .toList(); @@ -255,8 +255,11 @@ class Transaction { .map((e) => fusion_output.Output( addr: fusion_address.Address( addr: e.scriptPubKeyAddress, - publicKey: utf8.encode(e.scriptPubKey ?? ""), // TODO fix - derivationPath: fusion_address.DerivationPath("m/49'/0'/0'/0/0"), // TODO fix + publicKey: utf8.encode(e.scriptPubKey ?? + address!.value.toString()), // TODO fix or failsafe. + derivationPath: fusion_address.DerivationPath(address! + .value!.derivationPath! + .toString()), // TODO failsafe the (non-)null assertions. ), value: e.value, )) From 1e8b5ed700a41e31181651c1657eebaf6241bd29 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 18 Sep 2023 15:56:40 -0500 Subject: [PATCH 066/379] hook up start button to fuse() TODO link form inputs to fusion --- .../cashfusion/desktop_cashfusion_view.dart | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index abc238d2b..9bb9f725b 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -11,7 +11,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/ui/check_box_state_provider.dart'; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; @@ -392,7 +394,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { borderColor: Theme.of(context) .extension<StackColors>()! .shadow, - child: Row( + child: const Row( children: [], ), ), @@ -401,7 +403,13 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { ), PrimaryButton( label: "Start", - onPressed: () {}, + onPressed: () async { + await (ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface) + .fuse(); + }, ), ], ), From 309fce399fb98182553c42256a7783a9a12ddce5 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 18 Sep 2023 16:03:28 -0500 Subject: [PATCH 067/379] WIP null "safety" it's as "safe" as it is "short", "straightforward", and "elegant" --- .../models/blockchain_data/transaction.dart | 74 +++++++++++++------ 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/transaction.dart b/lib/models/isar/models/blockchain_data/transaction.dart index 86c6d8d76..c16d59e2c 100644 --- a/lib/models/isar/models/blockchain_data/transaction.dart +++ b/lib/models/isar/models/blockchain_data/transaction.dart @@ -242,30 +242,60 @@ class Transaction { fusion_tx.Transaction fusionTransaction = fusion_tx.Transaction(); // Map the Inputs and Outputs to Fusion Dart's format - fusionTransaction.Inputs = inputs - .map((e) => fusion_input.Input( - prevTxid: utf8.encode(e.txid), - prevIndex: e.vout, - pubKey: utf8.encode(e.witness ?? ""), // TODO fix or failsafe. - amount: 0, // TODO fix - )) - .toList(); + fusionTransaction.Inputs = inputs.map((e) { + return fusion_input.Input( + prevTxid: utf8.encode(e.txid), + prevIndex: e.vout, + pubKey: utf8.encode(address.value.toString()), // TODO is this valid? + amount: amount, // TODO is this valid? + ); + }).toList(); - fusionTransaction.Outputs = outputs - .map((e) => fusion_output.Output( - addr: fusion_address.Address( - addr: e.scriptPubKeyAddress, - publicKey: utf8.encode(e.scriptPubKey ?? - address!.value.toString()), // TODO fix or failsafe. - derivationPath: fusion_address.DerivationPath(address! - .value!.derivationPath! - .toString()), // TODO failsafe the (non-)null assertions. - ), - value: e.value, - )) - .toList(); + fusionTransaction.Outputs = outputs.map((e) { + /* + if (e.scriptPubKey == null) { + // TODO calculate scriptPubKey if it is null. + } + */ - // If any other information needs to be altered/added, do so here. + fusion_address.DerivationPath? derivationPath; + List<int>? pubKey; + + // Validate that we have all the required data. + if (address.value == null) { + // TODO calculate address if it is null. + throw Exception( + "address value is null for input: ${e.scriptPubKeyAddress}"); + } else { + if (address.value!.publicKey.isEmpty || e.scriptPubKey != null) { + pubKey = utf8.encode(e.scriptPubKey!); + // TODO is this valid? + } else { + pubKey = address.value!.publicKey; + } + if (address.value!.derivationPath != null) { + derivationPath = fusion_address.DerivationPath( + address.value!.derivationPath!.toString()); + } else { + // TODO calculate derivation path if it is null. + /* + throw Exception( + "derivationPath is null for input: ${e.scriptPubKeyAddress}"); + */ + } + } + + // TODO handle case where address.value.publicKey is empty and e.scriptPubKey is null + + return fusion_output.Output( + addr: fusion_address.Address( + addr: e.scriptPubKeyAddress, + publicKey: pubKey, + derivationPath: derivationPath, + ), + value: e.value, + ); + }).toList(); return fusionTransaction; } From 932c8d6bb916457f52a4e7a42f37db296481e4b7 Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Mon, 18 Sep 2023 14:42:38 -0600 Subject: [PATCH 068/379] Changed Tor info dialogs so padding looks better --- .../tor_settings/tor_settings.dart | 120 +++++++++--------- 1 file changed, 57 insertions(+), 63 deletions(-) diff --git a/lib/pages_desktop_specific/settings/settings_menu/tor_settings/tor_settings.dart b/lib/pages_desktop_specific/settings/settings_menu/tor_settings/tor_settings.dart index ff507b79e..5e0c51996 100644 --- a/lib/pages_desktop_specific/settings/settings_menu/tor_settings/tor_settings.dart +++ b/lib/pages_desktop_specific/settings/settings_menu/tor_settings/tor_settings.dart @@ -215,40 +215,37 @@ class _TorSettingsState extends ConsumerState<TorSettings> { return DesktopDialog( maxWidth: 580, maxHeight: double.infinity, - child: Column( - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Padding( - padding: - const EdgeInsets.only( - left: 32, - ), - child: Text( + child: Padding( + padding: const EdgeInsets.only( + top: 10, + left: 20, + bottom: 20, + right: 10, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text( "What is Tor?", style: STextStyles.desktopH2( context), ), - ), - DesktopDialogCloseButton( - onPressedOverride: () => - Navigator.of(context) - .pop(true), - ), - ], - ), - Padding( - padding: const EdgeInsets.only( - top: 12, - left: 32, - bottom: 32, - right: 32, + DesktopDialogCloseButton( + onPressedOverride: () => + Navigator.of(context) + .pop(true), + ), + ], ), - child: Text( + const SizedBox( + height: 16, + ), + Text( "Short for \"The Onion Router\", is an open-source software that enables internet communication" " to remain anonymous by routing internet traffic through a series of layered nodes," " to obscure the origin and destination of data.", @@ -261,8 +258,8 @@ class _TorSettingsState extends ConsumerState<TorSettings> { .textDark3, ), ), - ), - ], + ], + ), ), ); }, @@ -324,40 +321,37 @@ class _TorSettingsState extends ConsumerState<TorSettings> { return DesktopDialog( maxWidth: 580, maxHeight: double.infinity, - child: Column( - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Padding( - padding: - const EdgeInsets.only( - left: 32, - ), - child: Text( + child: Padding( + padding: const EdgeInsets.only( + top: 10, + left: 20, + bottom: 20, + right: 10, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text( "What is Tor killswitch?", style: STextStyles .desktopH2(context), ), - ), - DesktopDialogCloseButton( - onPressedOverride: () => - Navigator.of(context) - .pop(true), - ), - ], - ), - Padding( - padding: - const EdgeInsets.only( - top: 12, - left: 32, - bottom: 32, - right: 32, + DesktopDialogCloseButton( + onPressedOverride: () => + Navigator.of( + context) + .pop(true), + ), + ], ), - child: Text( + const SizedBox( + height: 16, + ), + Text( "A security feature that protects your information from accidental exposure by" " disconnecting your device from the Tor network if the" " connection is disrupted or compromised.", @@ -371,16 +365,16 @@ class _TorSettingsState extends ConsumerState<TorSettings> { .textDark3, ), ), - ), - ], + ], + ), ), ); }, ); }, ), - ), - ], + ], + ), ), ], ), From 13ac3ac10cfb058898cf622b4b13bc1a629c625c Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Mon, 18 Sep 2023 14:43:36 -0600 Subject: [PATCH 069/379] WIP: tor status section works + cash fusion info dialog --- .../cashfusion/desktop_cashfusion_view.dart | 187 +++++++++++++++++- 1 file changed, 178 insertions(+), 9 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 9bb9f725b..6501febed 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -8,11 +8,22 @@ * */ +import 'dart:async'; + +import 'package:event_bus/event_bus.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_native_splash/cli_commands.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/pages_desktop_specific/desktop_menu.dart'; +import 'package:stackwallet/pages_desktop_specific/settings/settings_menu.dart'; +import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/ui/check_box_state_provider.dart'; +import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart'; +import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; @@ -20,6 +31,8 @@ import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; @@ -55,7 +68,66 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { late final bool enableAuthFields; - void _updateState() {} + /// The global event bus. + late final EventBus eventBus; + + /// The subscription to the TorConnectionStatusChangedEvent. + late final StreamSubscription<TorConnectionStatusChangedEvent> + _torConnectionStatusSubscription; + + /// The current status of the Tor connection. + late TorConnectionStatus _torConnectionStatus = + TorConnectionStatus.disconnected; + + /// Build the connect/disconnect button + /// pushes to Tor settings + Widget _buildConnectButton(TorConnectionStatus status) { + switch (status) { + case TorConnectionStatus.disconnected: + return MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () { + ref.read(currentDesktopMenuItemProvider.state).state = + DesktopMenuItemId.settings; + ref.watch(selectedSettingsMenuItemStateProvider.state).state = 4; + }, + child: Text( + "Connect", + style: STextStyles.richLink(context).copyWith( + fontSize: 14, + ), + ), + ), + ); + case TorConnectionStatus.connecting: + return AbsorbPointer( + child: Text( + "Connecting", + style: STextStyles.richLink(context).copyWith( + fontSize: 14, + ), + ), + ); + case TorConnectionStatus.connected: + return MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () { + ref.read(currentDesktopMenuItemProvider.state).state = + DesktopMenuItemId.settings; + ref.watch(selectedSettingsMenuItemStateProvider.state).state = 4; + }, + child: Text( + "Disconnect", + style: STextStyles.richLink(context).copyWith( + fontSize: 14, + ), + ), + ), + ); + } + } @override void initState() { @@ -67,6 +139,23 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { enableSSLCheckbox = true; + // Initialize the global event bus. + eventBus = GlobalEventBus.instance; + + // Initialize the TorConnectionStatus. + _torConnectionStatus = ref.read(pTorService).status; + + // Subscribe to the TorConnectionStatusChangedEvent. + _torConnectionStatusSubscription = + eventBus.on<TorConnectionStatusChangedEvent>().listen( + (event) async { + // Rebuild the widget. + setState(() { + _torConnectionStatus = event.newStatus; + }); + }, + ); + super.initState(); } @@ -155,6 +244,67 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { style: STextStyles.richLink(context).copyWith( fontSize: 16, ), + recognizer: TapGestureRecognizer() + ..onTap = () { + showDialog<dynamic>( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return DesktopDialog( + maxWidth: 580, + maxHeight: double.infinity, + child: Padding( + padding: const EdgeInsets.only( + top: 10, + left: 20, + bottom: 20, + right: 10, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text( + "What is CashFusion?", + style: STextStyles.desktopH2( + context), + ), + DesktopDialogCloseButton( + onPressedOverride: () => + Navigator.of(context) + .pop(true), + ), + ], + ), + const SizedBox( + height: 16, + ), + Text( + "A fully decentralized privacy protocol that allows " + "anyone to create multi-party transactions with other " + "network participants. This process obscures your real " + "spending and makes it difficult for chain-analysis " + "companies to track your coins.", + style: + STextStyles.desktopTextMedium( + context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark3, + ), + ), + ], + ), + ), + ); + }, + ); + }, ), ), ], @@ -379,12 +529,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { style: STextStyles.desktopTextExtraExtraSmall( context), ), - Text( - "Disconnect", - style: STextStyles.richLink(context).copyWith( - fontSize: 14, - ), - ), + _buildConnectButton(_torConnectionStatus), ], ), const SizedBox( @@ -394,8 +539,32 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { borderColor: Theme.of(context) .extension<StackColors>()! .shadow, - child: const Row( - children: [], + child: Row( + children: [ + SvgPicture.asset( + Assets.svg.circleTor, + width: 48, + height: 48, + ), + const SizedBox( + width: 10, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Tor Network", + style: STextStyles.itemSubtitle12(context), + ), + const SizedBox( + height: 4, + ), + Text(_torConnectionStatus.name.capitalize(), + style: STextStyles + .desktopTextExtraExtraSmall(context)), + ], + ) + ], ), ), const SizedBox( From 2d20d0856dc03ff2e22f57e388719834ace3f289 Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Mon, 18 Sep 2023 15:40:52 -0600 Subject: [PATCH 070/379] WIP: fusion rounds drop down menu --- .../cashfusion/desktop_cashfusion_view.dart | 106 +++++++++--------- 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 6501febed..e96cfa032 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -10,6 +10,7 @@ import 'dart:async'; +import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:event_bus/event_bus.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -23,6 +24,7 @@ import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/ui/check_box_state_provider.dart'; import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; @@ -38,6 +40,11 @@ import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/stack_text_field.dart'; +enum FusionRounds { + Continuous, + Custom; +} + class DesktopCashFusionView extends ConsumerStatefulWidget { const DesktopCashFusionView({ super.key, @@ -65,9 +72,10 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { bool _trusted = false; int? port; late bool enableSSLCheckbox; - late final bool enableAuthFields; + FusionRounds _roundType = FusionRounds.Continuous; + /// The global event bus. late final EventBus eventBus; @@ -463,60 +471,58 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { const SizedBox( height: 10, ), - Stack( - children: [ - TextField( - autocorrect: false, - enableSuggestions: false, - readOnly: true, - textInputAction: TextInputAction.none, - style: STextStyles.desktopTextFieldLabel(context) - .copyWith( - fontSize: 16, - ), - decoration: const InputDecoration( - contentPadding: EdgeInsets.symmetric( - vertical: 18, - horizontal: 16, - ), - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12, - ), - child: RawMaterialButton( - splashColor: Theme.of(context) - .extension<StackColors>()! - .highlight, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, + DropdownButtonHideUnderline( + child: DropdownButton2<FusionRounds>( + value: _roundType, + items: [ + ...FusionRounds.values.map( + (e) => DropdownMenuItem( + value: e, + child: Text( + e.name, + style: + STextStyles.desktopTextMedium(context), ), ), - onPressed: () {}, - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Text( - "Continuous", - style: - STextStyles.itemSubtitle12(context), - ), - SvgPicture.asset( - Assets.svg.chevronDown, - width: 8, - height: 4, - color: Theme.of(context) - .extension<StackColors>()! - .textSubtitle2, - ), - ], + ), + ], + onChanged: (value) { + if (value is FusionRounds) { + setState(() { + _roundType = value; + }); + } + }, + isExpanded: true, + iconStyleData: IconStyleData( + icon: SvgPicture.asset( + Assets.svg.chevronDown, + width: 12, + height: 6, + color: Theme.of(context) + .extension<StackColors>()! + .textFieldActiveSearchIconRight, + ), + ), + dropdownStyleData: DropdownStyleData( + offset: const Offset(0, -10), + elevation: 0, + decoration: BoxDecoration( + color: Theme.of(context) + .extension<StackColors>()! + .textFieldActiveBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, ), ), ), - ], + menuItemStyleData: const MenuItemStyleData( + padding: EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + ), + ), ), const SizedBox( height: 20, From e5800d4ec209a8400bbb03be1be233d93f66d5bf Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Mon, 18 Sep 2023 15:51:00 -0600 Subject: [PATCH 071/379] resolve merge conflicts --- .../tor_settings/tor_settings.dart | 198 +++++++++--------- 1 file changed, 97 insertions(+), 101 deletions(-) diff --git a/lib/pages_desktop_specific/settings/settings_menu/tor_settings/tor_settings.dart b/lib/pages_desktop_specific/settings/settings_menu/tor_settings/tor_settings.dart index 5e0c51996..28b585c75 100644 --- a/lib/pages_desktop_specific/settings/settings_menu/tor_settings/tor_settings.dart +++ b/lib/pages_desktop_specific/settings/settings_menu/tor_settings/tor_settings.dart @@ -284,103 +284,99 @@ class _TorSettingsState extends ConsumerState<TorSettings> { ), Padding( padding: const EdgeInsets.all(10.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Tor killswitch", - style: STextStyles.desktopTextExtraExtraSmall( - context) - .copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textDark), - ), - const SizedBox( - height: 8, - ), - RichText( - textAlign: TextAlign.start, - text: TextSpan( - text: "What is Tor killswitch?", - style: STextStyles.richLink(context).copyWith( - fontSize: 14, - ), - recognizer: TapGestureRecognizer() - ..onTap = () { - showDialog<dynamic>( - context: context, - useSafeArea: false, - barrierDismissible: true, - builder: (context) { - return DesktopDialog( - maxWidth: 580, - maxHeight: double.infinity, - child: Padding( - padding: const EdgeInsets.only( - top: 10, - left: 20, - bottom: 20, - right: 10, - ), - child: Column( - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment - .spaceBetween, - children: [ - Text( - "What is Tor killswitch?", - style: STextStyles - .desktopH2(context), - ), - DesktopDialogCloseButton( - onPressedOverride: () => - Navigator.of( - context) - .pop(true), - ), - ], - ), - const SizedBox( - height: 16, - ), - Text( - "A security feature that protects your information from accidental exposure by" - " disconnecting your device from the Tor network if the" - " connection is disrupted or compromised.", - style: STextStyles - .desktopTextMedium( - context) - .copyWith( - color: Theme.of(context) - .extension< - StackColors>()! - .textDark3, - ), - ), - ], - ), - ), - ); - }, - ); - }, - ), - ], + child: Expanded( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Tor killswitch", + style: STextStyles.desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark), ), - ), - ], - ), - Padding( - padding: const EdgeInsets.only(right: 8.0), - child: SizedBox( + const SizedBox( + height: 8, + ), + RichText( + textAlign: TextAlign.start, + text: TextSpan( + text: "What is Tor killswitch?", + style: STextStyles.richLink(context).copyWith( + fontSize: 14, + ), + recognizer: TapGestureRecognizer() + ..onTap = () { + showDialog<dynamic>( + context: context, + useSafeArea: false, + barrierDismissible: true, + builder: (context) { + return DesktopDialog( + maxWidth: 580, + maxHeight: double.infinity, + child: Padding( + padding: const EdgeInsets.only( + top: 10, + left: 20, + bottom: 20, + right: 10, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + Text( + "What is Tor killswitch?", + style: + STextStyles.desktopH2( + context), + ), + DesktopDialogCloseButton( + onPressedOverride: () => + Navigator.of(context) + .pop(true), + ), + ], + ), + const SizedBox( + height: 16, + ), + Text( + "A security feature that protects your information from accidental exposure by" + " disconnecting your device from the Tor network if the" + " connection is disrupted or compromised.", + style: STextStyles + .desktopTextMedium( + context) + .copyWith( + color: Theme.of(context) + .extension< + StackColors>()! + .textDark3, + ), + ), + ], + ), + ), + ); + }, + ); + }, + ), + ), + ], + ), + const Spacer(), + SizedBox( height: 20, width: 40, child: DraggableSwitchButton( @@ -395,13 +391,13 @@ class _TorSettingsState extends ConsumerState<TorSettings> { }, ), ), - ), - ], + const SizedBox( + height: 10, + ), + ], + ), ), ), - const SizedBox( - height: 10, - ), ], ), ), From 183ac9dd2778ea97255bb329f19fb635bf93de44 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 19 Sep 2023 14:28:15 -0500 Subject: [PATCH 072/379] placeholder pubkey and comment updates --- fusiondart | 2 +- lib/models/isar/models/blockchain_data/transaction.dart | 4 ++-- lib/services/mixins/fusion_wallet_interface.dart | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fusiondart b/fusiondart index 102a596d6..6f354562f 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 102a596d633e00799ffd7ea82e83a02f8a14d984 +Subproject commit 6f354562f2bc2e4807816cc7abc90c465afda157 diff --git a/lib/models/isar/models/blockchain_data/transaction.dart b/lib/models/isar/models/blockchain_data/transaction.dart index c16d59e2c..dbacfe544 100644 --- a/lib/models/isar/models/blockchain_data/transaction.dart +++ b/lib/models/isar/models/blockchain_data/transaction.dart @@ -246,8 +246,8 @@ class Transaction { return fusion_input.Input( prevTxid: utf8.encode(e.txid), prevIndex: e.vout, - pubKey: utf8.encode(address.value.toString()), // TODO is this valid? - amount: amount, // TODO is this valid? + pubKey: utf8.encode(address.value.toString()), // TODO fix public key. + amount: amount, // TODO is this valid? Probably not. ); }).toList(); diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index de2a5bdbc..1b5640512 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -84,7 +84,7 @@ mixin FusionWalletInterface { return _txs .map((tx) => tx.toFusionTransaction()) - .toSet(); // TODO feed in proper public key + .toSet(); // TODO fix public key. } /// Returns a list of all UTXOs in the wallet for the given address. @@ -93,7 +93,7 @@ mixin FusionWalletInterface { return _utxos .map((utxo) => utxo.toFusionInput( - pubKey: utf8.encode('0000'))) // TODO feed in proper public key + pubKey: utf8.encode(address.toString()))) // TODO fix public key. .toList(); } From 8f629426dbc2f6a70fe9fa5074f63ba8f16f9c9e Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Tue, 19 Sep 2023 14:14:15 -0600 Subject: [PATCH 073/379] fusion progress dialog --- .../cashfusion/desktop_cashfusion_view.dart | 21 +- .../cashfusion/sub_widgets/fusion_dialog.dart | 305 ++++++++++++++++++ 2 files changed, 318 insertions(+), 8 deletions(-) create mode 100644 lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index e96cfa032..82870da5f 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -17,16 +17,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_native_splash/cli_commands.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_menu.dart'; import 'package:stackwallet/pages_desktop_specific/settings/settings_menu.dart'; import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart'; -import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/ui/check_box_state_provider.dart'; import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; -import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/services/tor_service.dart'; -import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; @@ -579,11 +577,18 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { PrimaryButton( label: "Start", onPressed: () async { - await (ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface) - .fuse(); + // await (ref + // .read(walletsChangeNotifierProvider) + // .getManager(widget.walletId) + // .wallet as FusionWalletInterface) + // .fuse(); + + await showDialog( + context: context, + builder: (context) { + return FusionDialog(); + }, + ); }, ), ], diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart new file mode 100644 index 000000000..3b5dad6ee --- /dev/null +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -0,0 +1,305 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_item_card.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/rounded_container.dart'; + +enum CashFustionStatus { waiting, restoring, success, failed } + +class FusionDialog extends StatelessWidget { + const FusionDialog({ + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + Widget _getIconForState(CashFustionStatus state) { + switch (state) { + case CashFustionStatus.waiting: + return SvgPicture.asset( + Assets.svg.loader, + color: + Theme.of(context).extension<StackColors>()!.buttonBackSecondary, + ); + case CashFustionStatus.restoring: + return SvgPicture.asset( + Assets.svg.loader, + color: Theme.of(context).extension<StackColors>()!.accentColorGreen, + ); + case CashFustionStatus.success: + return SvgPicture.asset( + Assets.svg.checkCircle, + color: Theme.of(context).extension<StackColors>()!.accentColorGreen, + ); + case CashFustionStatus.failed: + return SvgPicture.asset( + Assets.svg.circleAlert, + color: Theme.of(context).extension<StackColors>()!.textError, + ); + } + } + + return DesktopDialog( + maxHeight: 600, + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.only( + top: 10, + left: 20, + bottom: 20, + right: 10, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 10.0), + child: Text( + "Fusion progress", + style: STextStyles.desktopH2(context), + ), + ), + DesktopDialogCloseButton( + onPressedOverride: () => Navigator.of(context).pop(true), + ), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Column( + children: [ + const SizedBox( + height: 20, + ), + RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackError, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Do not close this window. If you exit, " + "the process will be canceled.", + style: STextStyles.smallMed14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark, + ), + ), + ], + ), + ), + const SizedBox( + height: 20, + ), + RoundedContainer( + padding: EdgeInsets.zero, + color: + Theme.of(context).extension<StackColors>()!.popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.node, + width: 16, + height: 16, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: SvgPicture.asset(Assets.svg.circleQuestion), + ), + title: "Connecting to server", + ), + ), + const SizedBox( + height: 12, + ), + RoundedContainer( + padding: EdgeInsets.zero, + color: + Theme.of(context).extension<StackColors>()!.popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.upFromLine, + width: 30, + height: 30, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: SvgPicture.asset(Assets.svg.circleQuestion), + ), + title: "Allocating outputs", + ), + ), + const SizedBox( + height: 12, + ), + RoundedContainer( + padding: EdgeInsets.zero, + color: + Theme.of(context).extension<StackColors>()!.popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.peers, + width: 30, + height: 30, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: SvgPicture.asset(Assets.svg.circleQuestion), + ), + title: "Waiting for peers", + ), + ), + const SizedBox( + height: 12, + ), + RoundedContainer( + padding: EdgeInsets.zero, + color: + Theme.of(context).extension<StackColors>()!.popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.fusing, + width: 30, + height: 30, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: SvgPicture.asset(Assets.svg.circleQuestion), + ), + title: "Fusing", + ), + ), + const SizedBox( + height: 12, + ), + RoundedContainer( + padding: EdgeInsets.zero, + color: + Theme.of(context).extension<StackColors>()!.popupBG, + borderColor: + Theme.of(context).extension<StackColors>()!.shadow, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.checkCircle, + width: 16, + height: 16, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: SvgPicture.asset(Assets.svg.circleQuestion), + ), + title: "Complete", + ), + ), + const SizedBox( + height: 12, + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + SecondaryButton( + width: 248, + buttonHeight: ButtonHeight.m, + enabled: true, + label: "Cancel", + onPressed: () { + Navigator.of(context).pop(true); + }, + ), + ], + ), + ], + ), + ), + ], + ), + ), + ), + ); + } +} From 0ef9759434afdd124d4b1f57fa14ffee6b922d91 Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Tue, 19 Sep 2023 14:15:15 -0600 Subject: [PATCH 074/379] svgs for fusion progress dialog --- lib/utilities/assets.dart | 3 +++ pubspec.yaml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart index ad90c1ce0..78f0edf28 100644 --- a/lib/utilities/assets.dart +++ b/lib/utilities/assets.dart @@ -92,6 +92,9 @@ class _SVG { final coinControl = const _COIN_CONTROL(); + String get peers => "assets/svg/peers.svg"; + String get fusing => "assets/svg/fusing.svg"; + String get upFromLine => "assets/svg/up-from-line.svg"; String get connectedButton => "assets/svg/connected-button.svg"; String get connectingButton => "assets/svg/connecting-button.svg"; String get disconnectedButton => "assets/svg/disconnected-button.svg"; diff --git a/pubspec.yaml b/pubspec.yaml index 5f49fb4a3..74a885744 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -362,6 +362,9 @@ flutter: - assets/svg/connected-button.svg - assets/svg/connecting-button.svg - assets/svg/disconnected-button.svg + - assets/svg/up-from-line.svg + - assets/svg/peers.svg + - assets/svg/fusing.svg # coin control icons - assets/svg/coin_control/ From abd6e6fccafa8f80f0c691db0093011fda834d9c Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Tue, 19 Sep 2023 14:16:11 -0600 Subject: [PATCH 075/379] fix typo --- .../cashfusion/sub_widgets/fusion_dialog.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 3b5dad6ee..20b20d494 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -9,7 +9,7 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; -enum CashFustionStatus { waiting, restoring, success, failed } +enum CashFusionStatus { waiting, restoring, success, failed } class FusionDialog extends StatelessWidget { const FusionDialog({ @@ -18,25 +18,25 @@ class FusionDialog extends StatelessWidget { @override Widget build(BuildContext context) { - Widget _getIconForState(CashFustionStatus state) { + Widget _getIconForState(CashFusionStatus state) { switch (state) { - case CashFustionStatus.waiting: + case CashFusionStatus.waiting: return SvgPicture.asset( Assets.svg.loader, color: Theme.of(context).extension<StackColors>()!.buttonBackSecondary, ); - case CashFustionStatus.restoring: + case CashFusionStatus.restoring: return SvgPicture.asset( Assets.svg.loader, color: Theme.of(context).extension<StackColors>()!.accentColorGreen, ); - case CashFustionStatus.success: + case CashFusionStatus.success: return SvgPicture.asset( Assets.svg.checkCircle, color: Theme.of(context).extension<StackColors>()!.accentColorGreen, ); - case CashFustionStatus.failed: + case CashFusionStatus.failed: return SvgPicture.asset( Assets.svg.circleAlert, color: Theme.of(context).extension<StackColors>()!.textError, From 93cfca7ddf4d075bf593a217a14903b10977f6d6 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 19 Sep 2023 17:58:17 -0500 Subject: [PATCH 076/379] update fusiondart ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 6f354562f..465df4196 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 6f354562f2bc2e4807816cc7abc90c465afda157 +Subproject commit 465df4196798b35ac85937df7dd73a861105472c From ef38e58b573a8bfe654fd04980830bbb95987d98 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 19 Sep 2023 17:58:55 -0500 Subject: [PATCH 077/379] query electrum for missing tx info --- lib/electrumx_rpc/electrumx.dart | 8 +++ .../models/blockchain_data/transaction.dart | 59 ++++++++++++++++--- .../coins/bitcoincash/bitcoincash_wallet.dart | 1 + .../mixins/fusion_wallet_interface.dart | 53 +++++++++++++++-- 4 files changed, 107 insertions(+), 14 deletions(-) diff --git a/lib/electrumx_rpc/electrumx.dart b/lib/electrumx_rpc/electrumx.dart index dc07890cf..88c49cc45 100644 --- a/lib/electrumx_rpc/electrumx.dart +++ b/lib/electrumx_rpc/electrumx.dart @@ -726,6 +726,14 @@ class ElectrumX { return {"rawtx": response["result"] as String}; } + if (response["result"] == null) { + Logging.instance.log( + "getTransaction($txHash) returned null response", + level: LogLevel.Error, + ); + throw 'getTransaction($txHash) returned null response'; + } + return Map<String, dynamic>.from(response["result"] as Map); } catch (e) { Logging.instance.log( diff --git a/lib/models/isar/models/blockchain_data/transaction.dart b/lib/models/isar/models/blockchain_data/transaction.dart index dbacfe544..304ebcfbb 100644 --- a/lib/models/isar/models/blockchain_data/transaction.dart +++ b/lib/models/isar/models/blockchain_data/transaction.dart @@ -11,15 +11,18 @@ import 'dart:convert'; import 'dart:math'; +import 'package:decimal/decimal.dart'; import 'package:fusiondart/src/models/address.dart' as fusion_address; import 'package:fusiondart/src/models/input.dart' as fusion_input; import 'package:fusiondart/src/models/output.dart' as fusion_output; import 'package:fusiondart/src/models/transaction.dart' as fusion_tx; import 'package:isar/isar.dart'; +import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/address.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/input.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/output.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:tuple/tuple.dart'; part 'transaction.g.dart'; @@ -237,19 +240,57 @@ class Transaction { } // Convert to fusiondart's Transaction type. - fusion_tx.Transaction toFusionTransaction() { + // + // This is bad because in the FusionWalletInterface in getTransactionsByAddress + // we already getAllTransactions, then for each transaction here we also getTransaction + // for each transaction again. But the data we need--the input's value--isn't + // here anyways. + Future<fusion_tx.Transaction> toFusionTransaction( + CachedElectrumX cachedElectrumX) async { // Initialize Fusion Dart's Transaction object. fusion_tx.Transaction fusionTransaction = fusion_tx.Transaction(); - // Map the Inputs and Outputs to Fusion Dart's format - fusionTransaction.Inputs = inputs.map((e) { - return fusion_input.Input( - prevTxid: utf8.encode(e.txid), - prevIndex: e.vout, - pubKey: utf8.encode(address.value.toString()), // TODO fix public key. - amount: amount, // TODO is this valid? Probably not. + // Map the Inputs and Outputs to Fusion Dart's format. + // + // This takes an exqcessive amount of time because we have to get the + // transaction for each input. We already have the transaction for each + // input in getTransactionsByAddress, but we don't have the input's value. + // So we have to get the transaction again here. + fusionTransaction.Inputs = await Future.wait(inputs.map((e) async { + // Find input amount. + print("2 getting tx ${e.txid}"); + Map<String, dynamic> _tx = await cachedElectrumX.getTransaction( + coin: Coin.bitcoincash, + txHash: e.txid, + verbose: true); // TODO is verbose needed? + + // Check if output amount is available. + if (_tx == null) { + throw Exception("Transaction not found for input: ${e.txid}"); + } + if (_tx["vout"] == null) { + throw Exception("Vout in transaction ${e.txid} is null"); + } + if (_tx["vout"][e.vout] == null) { + throw Exception("Vout index ${e.vout} in transaction is null"); + } + if (_tx["vout"][e.vout]["value"] == null) { + throw Exception("Value of vout index ${e.vout} in transaction is null"); + } + + // Assign vout value to amount. + final value = Amount.fromDecimal( + Decimal.parse(_tx["vout"][e.vout]["value"].toString()), + fractionDigits: Coin.bitcoincash.decimals, ); - }).toList(); + + return fusion_input.Input( + prevTxid: utf8.encode(e.txid), // TODO verify this is what we want. + prevIndex: e.vout, // TODO verify this is what we want. + pubKey: utf8.encode(address.value.toString()), // TODO fix public key. + amount: value.raw.toInt(), + ); + }).toList()); fusionTransaction.Outputs = outputs.map((e) { /* diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 5b674cb1e..6dbafcce8 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -140,6 +140,7 @@ class BitcoinCashWallet extends CoinServiceAPI coin: coin, db: db, generateAddressForChain: _generateAddressForChain, + cachedElectrumX: cachedElectrumXClient, ); initCoinControlInterface( walletId: walletId, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 1b5640512..0615f0435 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -8,6 +8,8 @@ import 'package:fusiondart/src/models/input.dart' as fusion_input; import 'package:fusiondart/src/models/transaction.dart' as fusion_tx; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; +import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; +import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -22,6 +24,7 @@ mixin FusionWalletInterface { late final String _walletId; late final Coin _coin; late final MainDB _db; + late final CachedElectrumX _cachedElectrumX; late final TorService _torService; // Passed in wallet functions. @@ -45,6 +48,7 @@ mixin FusionWalletInterface { int, DerivePathType, ) generateAddressForChain, + required CachedElectrumX cachedElectrumX, }) async { // Set passed in wallet data. _walletId = walletId; @@ -52,6 +56,7 @@ mixin FusionWalletInterface { _db = db; _generateAddressForChain = generateAddressForChain; _torService = TorService.sharedInstance; + _cachedElectrumX = cachedElectrumX; // Try getting the proxy info. // @@ -82,9 +87,11 @@ mixin FusionWalletInterface { String address) async { var _txs = await _db.getTransactions(_walletId).findAll(); - return _txs - .map((tx) => tx.toFusionTransaction()) - .toSet(); // TODO fix public key. + // Use Future.wait to await all the futures in the set and then convert it to a set. + var resultSet = await Future.wait( + _txs.map((tx) => tx.toFusionTransaction(_cachedElectrumX))); + + return resultSet.toSet(); } /// Returns a list of all UTXOs in the wallet for the given address. @@ -224,9 +231,45 @@ mixin FusionWalletInterface { // Add stack UTXOs. List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); + List<(String, int, int, List<int>)> coinList = []; - await mainFusionObject.addCoinsFromWallet( - utxos.map((e) => (e.txid, e.vout, e.value)).toList()); + // Loop through UTXOs, checking and adding valid ones. + for (var e in utxos) { + // Check if address is available. + if (e.address == null) { + // TODO we could continue here (and below during scriptPubKey validation) instead of throwing. + throw Exception("UTXO ${e.txid}:${e.vout} address is null"); + } + + // Find public key. + print("1 getting tx ${e.txid}"); + Map<String, dynamic> tx = await _cachedElectrumX.getTransaction(coin: _coin, + txHash: e.txid, verbose: true); // TODO is verbose needed? + + // Check if scriptPubKey is available. + if (tx["vout"] == null) { + throw Exception("Vout in transaction ${e.txid} is null"); + } + if (tx["vout"][e.vout] == null) { + throw Exception("Vout index ${e.vout} in transaction is null"); + } + if (tx["vout"][e.vout]["scriptPubKey"] == null) { + throw Exception("scriptPubKey at vout index ${e.vout} is null"); + } + if (tx["vout"][e.vout]["scriptPubKey"]["hex"] == null) { + throw Exception("hex in scriptPubKey at vout index ${e.vout} is null"); + } + + // Assign scriptPubKey to pubKey. TODO verify this is correct. + List<int> pubKey = + utf8.encode("${tx["vout"][e.vout]["scriptPubKey"]["hex"]}"); + + // Add UTXO to coinList. + coinList.add((e.txid, e.vout, e.value, pubKey)); + } + + // Add Stack UTXOs. + await mainFusionObject.addCoinsFromWallet(coinList); // Fuse UTXOs. return await mainFusionObject.fuse(); From 4180cf6c44201008a577817dacae0ed233fd8c9d Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 19 Sep 2023 22:14:34 -0500 Subject: [PATCH 078/379] refactor interface changes back into the interface --- .../models/blockchain_data/transaction.dart | 109 -------------- .../isar/models/blockchain_data/utxo.dart | 13 -- .../mixins/fusion_wallet_interface.dart | 134 +++++++++++++++++- 3 files changed, 131 insertions(+), 125 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/transaction.dart b/lib/models/isar/models/blockchain_data/transaction.dart index 304ebcfbb..a5a814786 100644 --- a/lib/models/isar/models/blockchain_data/transaction.dart +++ b/lib/models/isar/models/blockchain_data/transaction.dart @@ -11,18 +11,11 @@ import 'dart:convert'; import 'dart:math'; -import 'package:decimal/decimal.dart'; -import 'package:fusiondart/src/models/address.dart' as fusion_address; -import 'package:fusiondart/src/models/input.dart' as fusion_input; -import 'package:fusiondart/src/models/output.dart' as fusion_output; -import 'package:fusiondart/src/models/transaction.dart' as fusion_tx; import 'package:isar/isar.dart'; -import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/address.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/input.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/output.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; -import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:tuple/tuple.dart'; part 'transaction.g.dart'; @@ -238,108 +231,6 @@ class Transaction { return Tuple2(transaction, address); } } - - // Convert to fusiondart's Transaction type. - // - // This is bad because in the FusionWalletInterface in getTransactionsByAddress - // we already getAllTransactions, then for each transaction here we also getTransaction - // for each transaction again. But the data we need--the input's value--isn't - // here anyways. - Future<fusion_tx.Transaction> toFusionTransaction( - CachedElectrumX cachedElectrumX) async { - // Initialize Fusion Dart's Transaction object. - fusion_tx.Transaction fusionTransaction = fusion_tx.Transaction(); - - // Map the Inputs and Outputs to Fusion Dart's format. - // - // This takes an exqcessive amount of time because we have to get the - // transaction for each input. We already have the transaction for each - // input in getTransactionsByAddress, but we don't have the input's value. - // So we have to get the transaction again here. - fusionTransaction.Inputs = await Future.wait(inputs.map((e) async { - // Find input amount. - print("2 getting tx ${e.txid}"); - Map<String, dynamic> _tx = await cachedElectrumX.getTransaction( - coin: Coin.bitcoincash, - txHash: e.txid, - verbose: true); // TODO is verbose needed? - - // Check if output amount is available. - if (_tx == null) { - throw Exception("Transaction not found for input: ${e.txid}"); - } - if (_tx["vout"] == null) { - throw Exception("Vout in transaction ${e.txid} is null"); - } - if (_tx["vout"][e.vout] == null) { - throw Exception("Vout index ${e.vout} in transaction is null"); - } - if (_tx["vout"][e.vout]["value"] == null) { - throw Exception("Value of vout index ${e.vout} in transaction is null"); - } - - // Assign vout value to amount. - final value = Amount.fromDecimal( - Decimal.parse(_tx["vout"][e.vout]["value"].toString()), - fractionDigits: Coin.bitcoincash.decimals, - ); - - return fusion_input.Input( - prevTxid: utf8.encode(e.txid), // TODO verify this is what we want. - prevIndex: e.vout, // TODO verify this is what we want. - pubKey: utf8.encode(address.value.toString()), // TODO fix public key. - amount: value.raw.toInt(), - ); - }).toList()); - - fusionTransaction.Outputs = outputs.map((e) { - /* - if (e.scriptPubKey == null) { - // TODO calculate scriptPubKey if it is null. - } - */ - - fusion_address.DerivationPath? derivationPath; - List<int>? pubKey; - - // Validate that we have all the required data. - if (address.value == null) { - // TODO calculate address if it is null. - throw Exception( - "address value is null for input: ${e.scriptPubKeyAddress}"); - } else { - if (address.value!.publicKey.isEmpty || e.scriptPubKey != null) { - pubKey = utf8.encode(e.scriptPubKey!); - // TODO is this valid? - } else { - pubKey = address.value!.publicKey; - } - if (address.value!.derivationPath != null) { - derivationPath = fusion_address.DerivationPath( - address.value!.derivationPath!.toString()); - } else { - // TODO calculate derivation path if it is null. - /* - throw Exception( - "derivationPath is null for input: ${e.scriptPubKeyAddress}"); - */ - } - } - - // TODO handle case where address.value.publicKey is empty and e.scriptPubKey is null - - return fusion_output.Output( - addr: fusion_address.Address( - addr: e.scriptPubKeyAddress, - publicKey: pubKey, - derivationPath: derivationPath, - ), - value: e.value, - ); - }).toList(); - - return fusionTransaction; - } } // Used in Isar db and stored there as int indexes so adding/removing values diff --git a/lib/models/isar/models/blockchain_data/utxo.dart b/lib/models/isar/models/blockchain_data/utxo.dart index 4c5f5718f..3a87957f0 100644 --- a/lib/models/isar/models/blockchain_data/utxo.dart +++ b/lib/models/isar/models/blockchain_data/utxo.dart @@ -8,10 +8,8 @@ * */ -import 'dart:convert'; import 'dart:math'; -import 'package:fusiondart/src/models/input.dart' as FusionInput; import 'package:isar/isar.dart'; part 'utxo.g.dart'; @@ -147,14 +145,3 @@ class UTXO { @ignore int get hashCode => Object.hashAll([walletId, txid, vout]); } - -extension ToFusionInput on UTXO { - FusionInput.Input toFusionInput({required List<int> pubKey}) { - return FusionInput.Input( - prevTxid: utf8.encode(txid), - prevIndex: vout, - pubKey: pubKey, - amount: value, - ); - } -} diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 0615f0435..c81824fd9 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -2,16 +2,18 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'package:decimal/decimal.dart'; import 'package:fusiondart/fusiondart.dart'; import 'package:fusiondart/src/models/address.dart' as fusion_address; import 'package:fusiondart/src/models/input.dart' as fusion_input; +import 'package:fusiondart/src/models/output.dart' as fusion_output; import 'package:fusiondart/src/models/transaction.dart' as fusion_tx; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; -import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/tor_service.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; @@ -243,8 +245,10 @@ mixin FusionWalletInterface { // Find public key. print("1 getting tx ${e.txid}"); - Map<String, dynamic> tx = await _cachedElectrumX.getTransaction(coin: _coin, - txHash: e.txid, verbose: true); // TODO is verbose needed? + Map<String, dynamic> tx = await _cachedElectrumX.getTransaction( + coin: _coin, + txHash: e.txid, + verbose: true); // TODO is verbose needed? // Check if scriptPubKey is available. if (tx["vout"] == null) { @@ -380,3 +384,127 @@ mixin FusionWalletInterface { "TODO refreshFusion eg look up number of fusion participants connected/coordinating"); } } + +/// An extension of Stack Wallet's Transaction class that adds CashFusion functionality. +extension FusionTransaction on Transaction { + // WIP. + Future<fusion_tx.Transaction> toFusionTransaction( + CachedElectrumX cachedElectrumX) async { + // Initialize Fusion Dart's Transaction object. + fusion_tx.Transaction fusionTransaction = fusion_tx.Transaction(); + + // WIP. + fusionTransaction.Inputs = await Future.wait(inputs.map((e) async { + // Find input amount. + Map<String, dynamic> _tx = await cachedElectrumX.getTransaction( + coin: Coin.bitcoincash, + txHash: e.txid, + verbose: true); // TODO is verbose needed? + + // Check if output amount is available. + if (_tx.isEmpty) { + throw Exception("Transaction not found for input: ${e.txid}"); + } + if (_tx["vout"] == null) { + throw Exception("Vout in transaction ${e.txid} is null"); + } + if (_tx["vout"][e.vout] == null) { + throw Exception("Vout index ${e.vout} in transaction is null"); + } + if (_tx["vout"][e.vout]["value"] == null) { + throw Exception("Value of vout index ${e.vout} in transaction is null"); + } + // TODO replace with conditional chaining? + + // Assign vout value to amount. + final value = Amount.fromDecimal( + Decimal.parse(_tx["vout"][e.vout]["value"].toString()), + fractionDigits: Coin.bitcoincash.decimals, + ); + + return fusion_input.Input( + prevTxid: utf8.encode(e.txid), // TODO verify this is what we want. + prevIndex: e.vout, // TODO verify this is what we want. + pubKey: utf8.encode(address.value.toString()), // TODO fix public key. + amount: value.raw.toInt(), + ); + }).toList()); + + fusionTransaction.Outputs = outputs.map((e) { + /* + if (e.scriptPubKey == null) { + // TODO calculate scriptPubKey if it is null. + } + */ + + fusion_address.DerivationPath? derivationPath; + List<int>? pubKey; + + // Validate that we have all the required data. + if (address.value == null) { + // TODO calculate address if it is null. + throw Exception( + "address value is null for input: ${e.scriptPubKeyAddress}"); + } else { + if (address.value!.publicKey.isEmpty || e.scriptPubKey != null) { + pubKey = utf8.encode(e.scriptPubKey!); + // TODO is this valid? + } else { + pubKey = address.value! + .publicKey; // TODO IMPORTANT: this address may not be *the* address in question :) + } + if (address.value!.derivationPath != null) { + derivationPath = fusion_address.DerivationPath( + address.value!.derivationPath!.toString()); + } else { + // TODO calculate derivation path if it is null. + /* + throw Exception( + "derivationPath is null for input: ${e.scriptPubKeyAddress}"); + */ + } + } + + // TODO handle case where address.value.publicKey is empty and e.scriptPubKey is null + + return fusion_output.Output( + addr: fusion_address.Address( + addr: e.scriptPubKeyAddress, + publicKey: pubKey, + derivationPath: derivationPath, + ), + value: e.value, + ); + }).toList(); + + return fusionTransaction; + } +} + +/// An extension of Stack Wallet's UTXO class that adds CashFusion functionality. +/// +/// This class is used to convert Stack Wallet's UTXO class to FusionDart's +/// Input and Output classes. +extension FusionUTXO on UTXO { + /// Converts a Stack Wallet UTXO to a FusionDart Input. + fusion_input.Input toFusionInput({required List<int> pubKey}) { + return fusion_input.Input( + prevTxid: utf8.encode(txid), // TODO verify this is what we want. + prevIndex: vout, // TODO verify this is what we want. + pubKey: pubKey, // TODO fix public key. + amount: value, + ); + } + + /// Converts a Stack Wallet UTXO to a FusionDart Output. + fusion_output.Output toFusionOutput({required String address}) { + return fusion_output.Output( + addr: fusion_address.Address( + addr: address, + publicKey: utf8.encode(address.toString()), // TODO fix public key. + derivationPath: null, // TODO fix derivation path. + ), + value: value, + ); + } +} From 6b0dd30dee3200f63adf551818ba14cf9e3564ef Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 20 Sep 2023 10:17:52 -0500 Subject: [PATCH 079/379] refactor address model changes back into fusion interface --- .../isar/models/blockchain_data/address.dart | 11 --- .../mixins/fusion_wallet_interface.dart | 68 +++++++++++-------- 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/address.dart b/lib/models/isar/models/blockchain_data/address.dart index 3200058b1..75a0d34a6 100644 --- a/lib/models/isar/models/blockchain_data/address.dart +++ b/lib/models/isar/models/blockchain_data/address.dart @@ -236,14 +236,3 @@ class DerivationPath { @override int get hashCode => value.hashCode; } - -extension ToFusionAddress on Address { - FusionAddress.Address toFusionAddress() { - return FusionAddress.Address( - addr: value, - publicKey: - publicKey, // Assuming List<byte> and List<int> are compatible - derivationPath: - FusionAddress.DerivationPath(derivationPath?.value ?? "")); - } -} diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index c81824fd9..a687e8505 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -385,6 +385,46 @@ mixin FusionWalletInterface { } } +/// An extension of Stack Wallet's Address class that adds CashFusion functionality. +extension FusionAddress on Address { + fusion_address.Address toFusionAddress() { + return fusion_address.Address( + addr: value, + publicKey: + publicKey, // Assuming List<byte> and List<int> are compatible + derivationPath: + fusion_address.DerivationPath(derivationPath?.value ?? "")); + } +} + +/// An extension of Stack Wallet's UTXO class that adds CashFusion functionality. +/// +/// This class is used to convert Stack Wallet's UTXO class to FusionDart's +/// Input and Output classes. +extension FusionUTXO on UTXO { + /// Converts a Stack Wallet UTXO to a FusionDart Input. + fusion_input.Input toFusionInput({required List<int> pubKey}) { + return fusion_input.Input( + prevTxid: utf8.encode(txid), // TODO verify this is what we want. + prevIndex: vout, // TODO verify this is what we want. + pubKey: pubKey, // TODO fix public key. + amount: value, + ); + } + + /// Converts a Stack Wallet UTXO to a FusionDart Output. + fusion_output.Output toFusionOutput({required String address}) { + return fusion_output.Output( + addr: fusion_address.Address( + addr: address, + publicKey: utf8.encode(address.toString()), // TODO fix public key. + derivationPath: null, // TODO fix derivation path. + ), + value: value, + ); + } +} + /// An extension of Stack Wallet's Transaction class that adds CashFusion functionality. extension FusionTransaction on Transaction { // WIP. @@ -480,31 +520,3 @@ extension FusionTransaction on Transaction { return fusionTransaction; } } - -/// An extension of Stack Wallet's UTXO class that adds CashFusion functionality. -/// -/// This class is used to convert Stack Wallet's UTXO class to FusionDart's -/// Input and Output classes. -extension FusionUTXO on UTXO { - /// Converts a Stack Wallet UTXO to a FusionDart Input. - fusion_input.Input toFusionInput({required List<int> pubKey}) { - return fusion_input.Input( - prevTxid: utf8.encode(txid), // TODO verify this is what we want. - prevIndex: vout, // TODO verify this is what we want. - pubKey: pubKey, // TODO fix public key. - amount: value, - ); - } - - /// Converts a Stack Wallet UTXO to a FusionDart Output. - fusion_output.Output toFusionOutput({required String address}) { - return fusion_output.Output( - addr: fusion_address.Address( - addr: address, - publicKey: utf8.encode(address.toString()), // TODO fix public key. - derivationPath: null, // TODO fix derivation path. - ), - value: value, - ); - } -} From 0597e317ba029cb90f5e50a2745d62315f9c0b71 Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Wed, 20 Sep 2023 16:14:34 -0600 Subject: [PATCH 080/379] WIP: fusion progress provider --- lib/models/fusion_progress_ui_state.dart | 59 +++++++++++++++++++ .../fusion_progress_ui_state_provider.dart | 16 +++++ 2 files changed, 75 insertions(+) create mode 100644 lib/models/fusion_progress_ui_state.dart create mode 100644 lib/providers/cash_fusion/fusion_progress_ui_state_provider.dart diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart new file mode 100644 index 000000000..86bb558e1 --- /dev/null +++ b/lib/models/fusion_progress_ui_state.dart @@ -0,0 +1,59 @@ +import 'package:flutter/cupertino.dart'; +import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; + +class FusionProgressUIState extends ChangeNotifier { + bool _ableToConnect = false; + + bool get done { + if (!_ableToConnect) { + return false; + } + + bool _done = (_connecting == CashFusionStatus.success) || + (_connecting == CashFusionStatus.failed); + _done &= (_outputs == CashFusionStatus.success) || + (_outputs == CashFusionStatus.failed); + _done &= (_peers == CashFusionStatus.success) || + (_peers == CashFusionStatus.failed); + _done &= (_fusing == CashFusionStatus.success) || + (_fusing == CashFusionStatus.failed); + _done &= (_complete == CashFusionStatus.success) || + (_complete == CashFusionStatus.failed); + return _done; + } + + CashFusionStatus _connecting = CashFusionStatus.waiting; + CashFusionStatus get connecting => _connecting; + set connecting(CashFusionStatus state) { + _connecting = state; + notifyListeners(); + } + + CashFusionStatus _outputs = CashFusionStatus.waiting; + CashFusionStatus get outputs => _outputs; + set outputs(CashFusionStatus state) { + _outputs = state; + notifyListeners(); + } + + CashFusionStatus _peers = CashFusionStatus.waiting; + CashFusionStatus get peers => _peers; + set peers(CashFusionStatus state) { + _peers = state; + notifyListeners(); + } + + CashFusionStatus _fusing = CashFusionStatus.waiting; + CashFusionStatus get fusing => _fusing; + set fusing(CashFusionStatus state) { + _fusing = state; + notifyListeners(); + } + + CashFusionStatus _complete = CashFusionStatus.waiting; + CashFusionStatus get complete => _complete; + set complete(CashFusionStatus state) { + _complete = state; + notifyListeners(); + } +} diff --git a/lib/providers/cash_fusion/fusion_progress_ui_state_provider.dart b/lib/providers/cash_fusion/fusion_progress_ui_state_provider.dart new file mode 100644 index 000000000..2fb74b1f6 --- /dev/null +++ b/lib/providers/cash_fusion/fusion_progress_ui_state_provider.dart @@ -0,0 +1,16 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by Cypher Stack on 2023-05-26 + * + */ + +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:stackwallet/models/fusion_progress_ui_state.dart'; + +final fusionProgressUIStateProvider = + ChangeNotifierProvider<FusionProgressUIState>( + (ref) => FusionProgressUIState()); From 77e638af1669ab9c1b3efe2dbd47573963d2866c Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Wed, 20 Sep 2023 16:15:07 -0600 Subject: [PATCH 081/379] add fusion progress provider to dialog + custom fusion --- .../cashfusion/desktop_cashfusion_view.dart | 55 ++- .../cashfusion/sub_widgets/fusion_dialog.dart | 314 ++++++++++-------- 2 files changed, 221 insertions(+), 148 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 82870da5f..7b63b6f3f 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -62,9 +62,12 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { late final FocusNode serverFocusNode; late final TextEditingController portController; late final FocusNode portFocusNode; + late final TextEditingController fusionRoundController; + late final FocusNode fusionRoundFocusNode; String _serverTerm = ""; String _portTerm = ""; + String _fusionRoundTerm = ""; bool _useSSL = false; bool _trusted = false; @@ -139,9 +142,11 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { void initState() { serverController = TextEditingController(); portController = TextEditingController(); + fusionRoundController = TextEditingController(); serverFocusNode = FocusNode(); portFocusNode = FocusNode(); + fusionRoundFocusNode = FocusNode(); enableSSLCheckbox = true; @@ -169,9 +174,11 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { void dispose() { serverController.dispose(); portController.dispose(); + fusionRoundController.dispose(); serverFocusNode.dispose(); portFocusNode.dispose(); + fusionRoundFocusNode.dispose(); super.dispose(); } @@ -478,8 +485,12 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { value: e, child: Text( e.name, - style: - STextStyles.desktopTextMedium(context), + style: STextStyles.smallMed14(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark, + ), ), ), ), @@ -522,6 +533,46 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { ), ), ), + if (_roundType == FusionRounds.Custom) + const SizedBox( + height: 10, + ), + if (_roundType == FusionRounds.Custom) + SizedBox( + width: 460, + child: RoundedWhiteContainer( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: false, + enableSuggestions: false, + controller: fusionRoundController, + focusNode: fusionRoundFocusNode, + onChanged: (value) { + setState(() { + _fusionRoundTerm = value; + }); + }, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "", + fusionRoundFocusNode, + context, + desktopMed: true, + ).copyWith( + labelText: + "Enter number of fusions.."), + ), + ), + ], + ), + ), + ), const SizedBox( height: 20, ), diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 20b20d494..5d2f50744 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_item_card.dart'; +import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/text_styles.dart'; @@ -9,7 +11,7 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; -enum CashFusionStatus { waiting, restoring, success, failed } +enum CashFusionStatus { waiting, fusing, success, failed } class FusionDialog extends StatelessWidget { const FusionDialog({ @@ -26,7 +28,7 @@ class FusionDialog extends StatelessWidget { color: Theme.of(context).extension<StackColors>()!.buttonBackSecondary, ); - case CashFusionStatus.restoring: + case CashFusionStatus.fusing: return SvgPicture.asset( Assets.svg.loader, color: Theme.of(context).extension<StackColors>()!.accentColorGreen, @@ -100,182 +102,202 @@ class FusionDialog extends StatelessWidget { const SizedBox( height: 20, ), - RoundedContainer( - padding: EdgeInsets.zero, - color: - Theme.of(context).extension<StackColors>()!.popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.node, - width: 16, - height: 16, + Consumer(builder: (_, ref, __) { + final state = ref.watch(fusionProgressUIStateProvider + .select((value) => value.connecting)); + return RoundedContainer( + padding: EdgeInsets.zero, + color: + Theme.of(context).extension<StackColors>()!.popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.node, + width: 16, + height: 16, + ), ), ), ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Connecting to server", ), - right: SizedBox( - width: 20, - height: 20, - child: SvgPicture.asset(Assets.svg.circleQuestion), - ), - title: "Connecting to server", - ), - ), + ); + }), const SizedBox( height: 12, ), - RoundedContainer( - padding: EdgeInsets.zero, - color: - Theme.of(context).extension<StackColors>()!.popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.upFromLine, - width: 30, - height: 30, + Consumer(builder: (_, ref, __) { + final state = ref.watch(fusionProgressUIStateProvider + .select((value) => value.outputs)); + return RoundedContainer( + padding: EdgeInsets.zero, + color: + Theme.of(context).extension<StackColors>()!.popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.upFromLine, + width: 30, + height: 30, + ), ), ), ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Allocating outputs", ), - right: SizedBox( - width: 20, - height: 20, - child: SvgPicture.asset(Assets.svg.circleQuestion), - ), - title: "Allocating outputs", - ), - ), + ); + }), const SizedBox( height: 12, ), - RoundedContainer( - padding: EdgeInsets.zero, - color: - Theme.of(context).extension<StackColors>()!.popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.peers, - width: 30, - height: 30, + Consumer(builder: (_, ref, __) { + final state = ref.watch(fusionProgressUIStateProvider + .select((value) => value.peers)); + return RoundedContainer( + padding: EdgeInsets.zero, + color: + Theme.of(context).extension<StackColors>()!.popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.peers, + width: 30, + height: 30, + ), ), ), ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Waiting for peers", ), - right: SizedBox( - width: 20, - height: 20, - child: SvgPicture.asset(Assets.svg.circleQuestion), - ), - title: "Waiting for peers", - ), - ), + ); + }), const SizedBox( height: 12, ), - RoundedContainer( - padding: EdgeInsets.zero, - color: - Theme.of(context).extension<StackColors>()!.popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.fusing, - width: 30, - height: 30, + Consumer(builder: (_, ref, __) { + final state = ref.watch(fusionProgressUIStateProvider + .select((value) => value.fusing)); + return RoundedContainer( + padding: EdgeInsets.zero, + color: + Theme.of(context).extension<StackColors>()!.popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.fusing, + width: 30, + height: 30, + ), ), ), ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Fusing", ), - right: SizedBox( - width: 20, - height: 20, - child: SvgPicture.asset(Assets.svg.circleQuestion), - ), - title: "Fusing", - ), - ), + ); + }), const SizedBox( height: 12, ), - RoundedContainer( - padding: EdgeInsets.zero, - color: - Theme.of(context).extension<StackColors>()!.popupBG, - borderColor: - Theme.of(context).extension<StackColors>()!.shadow, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.checkCircle, - width: 16, - height: 16, + Consumer(builder: (_, ref, __) { + final state = ref.watch(fusionProgressUIStateProvider + .select((value) => value.complete)); + return RoundedContainer( + padding: EdgeInsets.zero, + color: + Theme.of(context).extension<StackColors>()!.popupBG, + borderColor: + Theme.of(context).extension<StackColors>()!.shadow, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.checkCircle, + width: 16, + height: 16, + ), ), ), ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Complete", ), - right: SizedBox( - width: 20, - height: 20, - child: SvgPicture.asset(Assets.svg.circleQuestion), - ), - title: "Complete", - ), - ), + ); + }), const SizedBox( height: 12, ), From 386fcdc1d849713df9c78f91f1a0b91300cb3c21 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 14:57:49 -0500 Subject: [PATCH 082/379] formatting remove unused import --- lib/models/isar/models/blockchain_data/address.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/address.dart b/lib/models/isar/models/blockchain_data/address.dart index 75a0d34a6..b5c86fe59 100644 --- a/lib/models/isar/models/blockchain_data/address.dart +++ b/lib/models/isar/models/blockchain_data/address.dart @@ -10,7 +10,6 @@ import 'dart:convert'; -import 'package:fusiondart/src/models/address.dart' as FusionAddress; import 'package:isar/isar.dart'; import 'package:stackwallet/exceptions/address/address_exception.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/crypto_currency_address.dart'; @@ -93,7 +92,6 @@ class Address extends CryptoCurrencyAddress { ); } - @override String toString() => "{ " "id: $id, " From 7788ec7aceb727d399f712fb4aa91743ca31b0db Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 16:57:21 -0500 Subject: [PATCH 083/379] implement getAddressFromOutputScript in fusiondart and update comments --- fusiondart | 2 +- .../coins/bitcoincash/bitcoincash_wallet.dart | 9 +++++---- .../mixins/fusion_wallet_interface.dart | 19 ++++++++++++------- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/fusiondart b/fusiondart index 465df4196..94e2c3140 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 465df4196798b35ac85937df7dd73a861105472c +Subproject commit 94e2c31404bd5ca75a4798c430d9c2ae09bc9143 diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 6dbafcce8..f96c1b54a 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -200,8 +200,9 @@ class BitcoinCashWallet extends CoinServiceAPI .findFirst()) ?? await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); - Future<String> get currentChangeAddress async => (await _currentChangeAddress) - .value; // could return Address to cast Stack's Address to Fusiondart's Address like `(await _currentChangeAddress).toFusionAddress();` + Future<String> get currentChangeAddress async => + (await _currentChangeAddress).value; + // TODO return Address instead of String. Future<String> get nextChangeAddress async { // get change <Address> @@ -216,8 +217,8 @@ class BitcoinCashWallet extends CoinServiceAPI DerivePathTypeExt.primaryFor( coin)); // may need to pick other derive path type, eg 44, 49, 84 - return newChangeAddress - .value; // could return Address to cast Stack's Address to Fusiondart's Address like `newChangeAddress.toFusionAddress();` + return newChangeAddress.value; + // TODO return Address instead of String. } Future<isar_models.Address> get _currentChangeAddress async => diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index a687e8505..70abbd1a2 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -390,10 +390,10 @@ extension FusionAddress on Address { fusion_address.Address toFusionAddress() { return fusion_address.Address( addr: value, - publicKey: - publicKey, // Assuming List<byte> and List<int> are compatible + publicKey: publicKey, derivationPath: fusion_address.DerivationPath(derivationPath?.value ?? "")); + // TODO fix default derivation path. } } @@ -404,9 +404,14 @@ extension FusionAddress on Address { extension FusionUTXO on UTXO { /// Converts a Stack Wallet UTXO to a FusionDart Input. fusion_input.Input toFusionInput({required List<int> pubKey}) { + if (address != null) { + // Search isar for address. + // TODO + } + return fusion_input.Input( - prevTxid: utf8.encode(txid), // TODO verify this is what we want. - prevIndex: vout, // TODO verify this is what we want. + txid: utf8.encode(txid), // TODO verify this is what we want. + index: vout, // TODO verify this is what we want. pubKey: pubKey, // TODO fix public key. amount: value, ); @@ -463,9 +468,9 @@ extension FusionTransaction on Transaction { ); return fusion_input.Input( - prevTxid: utf8.encode(e.txid), // TODO verify this is what we want. - prevIndex: e.vout, // TODO verify this is what we want. - pubKey: utf8.encode(address.value.toString()), // TODO fix public key. + txid: utf8.encode(e.txid), // TODO verify this is what we want. + index: e.vout, // TODO verify this is what we want. + pubKey: utf8.encode('0000'), // TODO fix public key. amount: value.raw.toInt(), ); }).toList()); From c12566cea90d8498e7e1024fa7f13de3506b792b Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 17:03:29 -0500 Subject: [PATCH 084/379] implement fromScriptPubKey --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 94e2c3140..b2f7ee5e4 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 94e2c31404bd5ca75a4798c430d9c2ae09bc9143 +Subproject commit b2f7ee5e4774529f74a815d7edaa4e68acef0adf From 1df72ab06a1809e4d363fd247e77d385e4ba7838 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 17:29:12 -0500 Subject: [PATCH 085/379] implement pubkeysFromPrivkey and fix toScript --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index b2f7ee5e4..14c6bf15d 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit b2f7ee5e4774529f74a815d7edaa4e68acef0adf +Subproject commit 14c6bf15db7343e7c907d6fe2f620596fd70b727 From bc9cdccf3226d302ad845f0f219851d2a38ba013 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 22:21:29 -0500 Subject: [PATCH 086/379] add missing up from line svg --- assets/svg/up-from-line.svg | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 assets/svg/up-from-line.svg diff --git a/assets/svg/up-from-line.svg b/assets/svg/up-from-line.svg new file mode 100644 index 000000000..4e1c8f6bf --- /dev/null +++ b/assets/svg/up-from-line.svg @@ -0,0 +1,3 @@ +<svg width="18" height="20" viewBox="0 0 18 20" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M15.875 16.8755H2.08633C1.36574 16.8755 0.75 17.4899 0.75 18.2118C0.75 18.9337 1.36574 19.6255 2.08633 19.6255H15.875C16.6355 19.6255 17.25 19.011 17.25 18.2505C17.25 17.4899 16.6355 16.8755 15.875 16.8755ZM3.15625 8.61687H6.25V14.1212C6.25 14.8813 6.86574 15.4979 7.625 15.4979H10.375C11.1343 15.4979 11.75 14.8813 11.75 14.1212V8.61687H14.8438C15.2553 8.61687 15.6279 8.3716 15.7912 7.99339C15.9537 7.61514 15.8765 7.1757 15.5938 6.8762L9.75006 0.684407C9.36068 0.271864 8.63975 0.271864 8.25002 0.684407L2.40627 6.8762C2.12363 7.17587 2.04641 7.61527 2.20887 7.99339C2.37207 8.37195 2.74461 8.61687 3.15625 8.61687Z" fill="black"/> +</svg> From 138df153d40c3ffaf806e95f3d9a5f0cc0f70173 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 22:21:35 -0500 Subject: [PATCH 087/379] add missing peers svg --- assets/svg/peers.svg | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 assets/svg/peers.svg diff --git a/assets/svg/peers.svg b/assets/svg/peers.svg new file mode 100644 index 000000000..26bc3a2a0 --- /dev/null +++ b/assets/svg/peers.svg @@ -0,0 +1,3 @@ +<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M8.7 12.0002C11.1303 12.0002 13.1 10.0302 13.1 7.6002C13.1 5.17023 11.1303 3.2002 8.7 3.2002C6.26969 3.2002 4.3 5.17023 4.3 7.6002C4.3 10.0302 6.26969 12.0002 8.7 12.0002ZM10.4428 13.6502H6.95719C3.66647 13.6502 1 16.3177 1 19.6074C1 20.2674 1.5335 20.8002 2.19144 20.8002H15.2072C15.8672 20.8002 16.4 20.2674 16.4 19.6074C16.4 16.3177 13.7325 13.6502 10.4428 13.6502ZM17.4691 14.2002H14.9305C16.51 15.4961 17.5 17.4349 17.5 19.6074C17.5 20.0474 17.3694 20.453 17.1562 20.8002H21.9C22.5084 20.8002 23 20.3052 23 19.6693C23 16.6614 20.5387 14.2002 17.4691 14.2002ZM15.85 12.0002C17.9778 12.0002 19.7 10.278 19.7 8.1502C19.7 6.02238 17.9778 4.3002 15.85 4.3002C14.9868 4.3002 14.1986 4.59427 13.5565 5.07398C13.9525 5.83435 14.2 6.68582 14.2 7.6002C14.2 8.8212 13.7899 9.94251 13.1141 10.8559C13.8116 11.5602 14.7775 12.0002 15.85 12.0002Z" fill="black"/> +</svg> From 7ed17cfa91c73693952bc923e8ab61f01fd8d1dd Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 22:21:41 -0500 Subject: [PATCH 088/379] add missing fusing svg --- assets/svg/fusing.svg | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 assets/svg/fusing.svg diff --git a/assets/svg/fusing.svg b/assets/svg/fusing.svg new file mode 100644 index 000000000..1b04f882a --- /dev/null +++ b/assets/svg/fusing.svg @@ -0,0 +1,3 @@ +<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M22.768 12.7778C22.0427 9.72145 19.529 7.28212 16.4516 6.67196C14.9906 6.37118 13.4811 6.47323 12.0731 6.95663C12.3953 4.84042 13.7811 3.04089 15.7469 2.19569C16.3218 1.94862 16.1929 1.09999 15.575 1.04069C14.6349 0.944011 13.6895 1.01383 12.7765 1.22868C9.68399 1.95571 7.28204 4.46938 6.63321 7.54852C6.33243 9.00946 6.47423 10.5177 6.95548 11.9227C4.84012 11.6005 3.04059 10.2169 2.19755 8.24891C1.95048 7.67743 1.10176 7.80633 1.04265 8.42079C0.945952 9.3618 1.01579 10.3071 1.23066 11.2224C1.95598 14.2787 4.46965 16.7181 7.54707 17.3282C9.00801 17.629 10.5175 17.5269 11.9256 17.0435C11.6033 19.1598 10.2176 20.9593 8.25176 21.8045C7.67684 22.0515 7.80574 22.9002 8.42363 22.9595C9.36379 23.0562 10.3091 22.9863 11.2222 22.7715C14.2786 22.0462 16.7179 19.5325 17.328 16.4551C17.6288 14.9941 17.5268 13.4847 17.0434 12.0766C19.1596 12.3988 20.9591 13.7846 21.8043 15.7504C22.0514 16.3253 22.9 16.1964 22.9593 15.5785C23.0559 14.6384 22.9828 13.6931 22.768 12.7778ZM11.9613 14.0626C10.8613 14.0626 9.89884 13.1388 9.89884 12.0001C9.89884 10.8614 10.8227 9.93758 11.9613 9.93758C13.1 9.93758 14.0625 10.8614 14.0625 12.0001C14.0625 13.1388 13.1387 14.0626 11.9613 14.0626Z" fill="black"/> +</svg> From 230a2edea4a787c3ad1c9ee10f6d2066d3d43853 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 22:30:48 -0500 Subject: [PATCH 089/379] implement input-signing --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 14c6bf15d..b0a0339a8 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 14c6bf15db7343e7c907d6fe2f620596fd70b727 +Subproject commit b0a0339a8b8dec2aea157fd3d059bc7dc9d0321b From 3c092946c38c31f10baa25a502491ad5cc9ea586 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 22:31:14 -0500 Subject: [PATCH 090/379] fuse on click --- .../cashfusion/desktop_cashfusion_view.dart | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 7b63b6f3f..5140ddc1f 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -21,9 +21,11 @@ import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion import 'package:stackwallet/pages_desktop_specific/desktop_menu.dart'; import 'package:stackwallet/pages_desktop_specific/settings/settings_menu.dart'; import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/ui/check_box_state_provider.dart'; import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; @@ -628,11 +630,11 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { PrimaryButton( label: "Start", onPressed: () async { - // await (ref - // .read(walletsChangeNotifierProvider) - // .getManager(widget.walletId) - // .wallet as FusionWalletInterface) - // .fuse(); + await (ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface) + .fuse(); await showDialog( context: context, From f235fe220bc46b4acf8eb303c3636d359edd2503 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 22:31:14 -0500 Subject: [PATCH 091/379] Revert "fuse on click" This reverts commit 3c092946c38c31f10baa25a502491ad5cc9ea586. --- .../cashfusion/desktop_cashfusion_view.dart | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 5140ddc1f..7b63b6f3f 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -21,11 +21,9 @@ import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion import 'package:stackwallet/pages_desktop_specific/desktop_menu.dart'; import 'package:stackwallet/pages_desktop_specific/settings/settings_menu.dart'; import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart'; -import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/ui/check_box_state_provider.dart'; import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; -import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; @@ -630,11 +628,11 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { PrimaryButton( label: "Start", onPressed: () async { - await (ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface) - .fuse(); + // await (ref + // .read(walletsChangeNotifierProvider) + // .getManager(widget.walletId) + // .wallet as FusionWalletInterface) + // .fuse(); await showDialog( context: context, From cb219d9459e89d03aa2784dee0fba9dcaa12cd66 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 22:40:08 -0500 Subject: [PATCH 092/379] comments --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index b0a0339a8..86faed63a 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit b0a0339a8b8dec2aea157fd3d059bc7dc9d0321b +Subproject commit 86faed63a7bb553087ceb1b44b38ff0b6d68932d From a2e3a2aafa597d46cbb589350284d200f6deddd9 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 23:12:08 -0500 Subject: [PATCH 093/379] implement schnorrVerify, documentation, comments, etc --- fusiondart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fusiondart b/fusiondart index 86faed63a..3aa2c5a2a 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 86faed63a7bb553087ceb1b44b38ff0b6d68932d +Subproject commit 3aa2c5a2ab4cd22de8e80a2029276689ab94006e diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 70abbd1a2..fa9f0efb2 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -410,8 +410,8 @@ extension FusionUTXO on UTXO { } return fusion_input.Input( - txid: utf8.encode(txid), // TODO verify this is what we want. - index: vout, // TODO verify this is what we want. + prevTxid: utf8.encode(txid), // TODO verify this is what we want. + prevIndex: vout, // TODO verify this is what we want. pubKey: pubKey, // TODO fix public key. amount: value, ); @@ -468,8 +468,8 @@ extension FusionTransaction on Transaction { ); return fusion_input.Input( - txid: utf8.encode(e.txid), // TODO verify this is what we want. - index: e.vout, // TODO verify this is what we want. + prevTxid: utf8.encode(e.txid), // TODO verify this is what we want. + prevIndex: e.vout, // TODO verify this is what we want. pubKey: utf8.encode('0000'), // TODO fix public key. amount: value.raw.toInt(), ); From 83f7a2d1c2ae583145618ba7ba06c8470025f568 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 23:17:28 -0500 Subject: [PATCH 094/379] refactor (use getRandomBytes) --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 3aa2c5a2a..cae0e8884 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 3aa2c5a2ab4cd22de8e80a2029276689ab94006e +Subproject commit cae0e88841ba4f221855b15f052b3cb496d032e1 From 4072c1929a3f27d98cadf2d7892172f7574bead0 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 21 Sep 2023 23:31:53 -0500 Subject: [PATCH 095/379] implement dustLimit --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index cae0e8884..2b77bb9c6 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit cae0e88841ba4f221855b15f052b3cb496d032e1 +Subproject commit 2b77bb9c6d7c60b9be6b05e78e856a42c2b70ff8 From 504fdaa2392f956681e175eed6f1aca3a396f089 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 22 Sep 2023 00:38:32 -0500 Subject: [PATCH 096/379] query isar for pubkey of address --- fusiondart | 2 +- .../mixins/fusion_wallet_interface.dart | 54 +++++++++++++------ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/fusiondart b/fusiondart index 2b77bb9c6..1cd747f24 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 2b77bb9c6d7c60b9be6b05e78e856a42c2b70ff8 +Subproject commit 1cd747f248e3eb9d6b09ddf8944c76931ad4f3c7 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index fa9f0efb2..ef312f6b3 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -23,9 +23,9 @@ const String kReservedFusionAddress = "reserved_fusion_address"; /// A mixin for the BitcoinCashWallet class that adds CashFusion functionality. mixin FusionWalletInterface { // Passed in wallet data. - late final String _walletId; + static late final String _walletId; late final Coin _coin; - late final MainDB _db; + static late final MainDB _db; late final CachedElectrumX _cachedElectrumX; late final TorService _torService; @@ -100,10 +100,10 @@ mixin FusionWalletInterface { Future<List<fusion_input.Input>> getInputsByAddress(String address) async { var _utxos = await _db.getUTXOsByAddress(_walletId, address).findAll(); - return _utxos - .map((utxo) => utxo.toFusionInput( - pubKey: utf8.encode(address.toString()))) // TODO fix public key. - .toList(); + List<Future<fusion_input.Input>> futureInputs = + _utxos.map((utxo) => utxo.toFusionInput()).toList(); + + return await Future.wait(futureInputs); } /// Creates a new reserved change address. @@ -185,6 +185,17 @@ mixin FusionWalletInterface { return unusedAddresses; } + /// Get an address. + static Future<Address> getAddress(String addr) async { + Address? address = await _db.getAddress(_walletId, addr); + + if (address == null) { + throw Exception("Address not found"); + } + + return address; + } + /// Returns the current Tor proxy address. Future<({InternetAddress host, int port})> getSocksProxyAddress() async { /* @@ -403,26 +414,35 @@ extension FusionAddress on Address { /// Input and Output classes. extension FusionUTXO on UTXO { /// Converts a Stack Wallet UTXO to a FusionDart Input. - fusion_input.Input toFusionInput({required List<int> pubKey}) { - if (address != null) { - // Search isar for address. - // TODO + Future<fusion_input.Input> toFusionInput() async { + if (address == null) { + throw Exception("toFutionInput Address is null"); } + // Search isar for address to get pubKey. + Address addr = await FusionWalletInterface.getAddress(address!); + return fusion_input.Input( - prevTxid: utf8.encode(txid), // TODO verify this is what we want. - prevIndex: vout, // TODO verify this is what we want. - pubKey: pubKey, // TODO fix public key. + prevTxid: utf8.encode(txid), + prevIndex: vout, + pubKey: addr.publicKey, amount: value, ); } - /// Converts a Stack Wallet UTXO to a FusionDart Output. - fusion_output.Output toFusionOutput({required String address}) { + /// Converts a Stack Wallet UTXO to a FusionDart Output... eventually. + Future<fusion_output.Output> toFusionOutput() async { + if (address == null) { + throw Exception("toFutionOutput Address is null"); + } + + // Search isar for address to get pubKey. + Address addr = await FusionWalletInterface.getAddress(address!); + return fusion_output.Output( addr: fusion_address.Address( - addr: address, - publicKey: utf8.encode(address.toString()), // TODO fix public key. + addr: address!, + publicKey: addr.publicKey, // TODO fix public key. derivationPath: null, // TODO fix derivation path. ), value: value, From b0f0ea48e1b4adad011d4058b82ad23229e7adca Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 09:38:05 -0600 Subject: [PATCH 097/379] add comment --- lib/models/isar/models/blockchain_data/address.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/models/isar/models/blockchain_data/address.dart b/lib/models/isar/models/blockchain_data/address.dart index b5c86fe59..a26ef94b6 100644 --- a/lib/models/isar/models/blockchain_data/address.dart +++ b/lib/models/isar/models/blockchain_data/address.dart @@ -70,6 +70,8 @@ class Address extends CryptoCurrencyAddress { subType == AddressSubType.paynymSend || subType == AddressSubType.paynymReceive; + /// If called on an [Address] already stored in the DB be sure to update the + /// [transactions] Isar Links if required Address copyWith({ String? walletId, String? value, From ecdb49d84c99fe39da95f3a56553a096c3465e44 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 22 Sep 2023 11:45:16 -0500 Subject: [PATCH 098/379] add derivationPath in toFusionOutput --- lib/services/mixins/fusion_wallet_interface.dart | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index ef312f6b3..e22726138 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -430,7 +430,7 @@ extension FusionUTXO on UTXO { ); } - /// Converts a Stack Wallet UTXO to a FusionDart Output... eventually. + /// Converts a Stack Wallet UTXO to a FusionDart Output. Future<fusion_output.Output> toFusionOutput() async { if (address == null) { throw Exception("toFutionOutput Address is null"); @@ -442,8 +442,9 @@ extension FusionUTXO on UTXO { return fusion_output.Output( addr: fusion_address.Address( addr: address!, - publicKey: addr.publicKey, // TODO fix public key. - derivationPath: null, // TODO fix derivation path. + publicKey: addr.publicKey, + derivationPath: + fusion_address.DerivationPath(addr.derivationPath?.value ?? ""), ), value: value, ); From 4b964f611c90c2a8df680eb937a16e4ad617c759 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 10:48:14 -0600 Subject: [PATCH 099/379] fix static variable usage --- .../mixins/fusion_wallet_interface.dart | 128 ++++++++++++------ 1 file changed, 87 insertions(+), 41 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index ef312f6b3..6183ae0ce 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -23,9 +23,9 @@ const String kReservedFusionAddress = "reserved_fusion_address"; /// A mixin for the BitcoinCashWallet class that adds CashFusion functionality. mixin FusionWalletInterface { // Passed in wallet data. - static late final String _walletId; + late final String _walletId; late final Coin _coin; - static late final MainDB _db; + late final MainDB _db; late final CachedElectrumX _cachedElectrumX; late final TorService _torService; @@ -85,23 +85,29 @@ mixin FusionWalletInterface { } /// Returns a list of all transactions in the wallet for the given address. - Future<Set<fusion_tx.Transaction>> getTransactionsByAddress( + Future<List<fusion_tx.Transaction>> getTransactionsByAddress( String address) async { - var _txs = await _db.getTransactions(_walletId).findAll(); + final _txs = await _db.getTransactions(_walletId).findAll(); // Use Future.wait to await all the futures in the set and then convert it to a set. - var resultSet = await Future.wait( + final resultSet = await Future.wait( _txs.map((tx) => tx.toFusionTransaction(_cachedElectrumX))); - return resultSet.toSet(); + return resultSet; } /// Returns a list of all UTXOs in the wallet for the given address. Future<List<fusion_input.Input>> getInputsByAddress(String address) async { - var _utxos = await _db.getUTXOsByAddress(_walletId, address).findAll(); + final _utxos = await _db.getUTXOsByAddress(_walletId, address).findAll(); - List<Future<fusion_input.Input>> futureInputs = - _utxos.map((utxo) => utxo.toFusionInput()).toList(); + List<Future<fusion_input.Input>> futureInputs = _utxos + .map( + (utxo) => utxo.toFusionInput( + walletId: _walletId, + dbInstance: _db, + ), + ) + .toList(); return await Future.wait(futureInputs); } @@ -185,17 +191,6 @@ mixin FusionWalletInterface { return unusedAddresses; } - /// Get an address. - static Future<Address> getAddress(String addr) async { - Address? address = await _db.getAddress(_walletId, addr); - - if (address == null) { - throw Exception("Address not found"); - } - - return address; - } - /// Returns the current Tor proxy address. Future<({InternetAddress host, int port})> getSocksProxyAddress() async { /* @@ -399,12 +394,17 @@ mixin FusionWalletInterface { /// An extension of Stack Wallet's Address class that adds CashFusion functionality. extension FusionAddress on Address { fusion_address.Address toFusionAddress() { + if (derivationPath == null) { + throw Exception("Fusion Addresses require a derivation path"); + } + return fusion_address.Address( - addr: value, - publicKey: publicKey, - derivationPath: - fusion_address.DerivationPath(derivationPath?.value ?? "")); - // TODO fix default derivation path. + addr: value, + publicKey: publicKey, + derivationPath: fusion_address.DerivationPath( + derivationPath!.value, + ), + ); } } @@ -413,37 +413,83 @@ extension FusionAddress on Address { /// This class is used to convert Stack Wallet's UTXO class to FusionDart's /// Input and Output classes. extension FusionUTXO on UTXO { - /// Converts a Stack Wallet UTXO to a FusionDart Input. - Future<fusion_input.Input> toFusionInput() async { - if (address == null) { - throw Exception("toFutionInput Address is null"); + /// Fetch the public key of an address stored in the database. + Future<Address> _getAddressPubkey({ + required String address, + required String walletId, + required MainDB dbInstance, + }) async { + final Address? addr = await dbInstance.getAddress(walletId, address); + + if (addr == null) { + throw Exception("Address not found"); } - // Search isar for address to get pubKey. - Address addr = await FusionWalletInterface.getAddress(address!); + return addr; + } - return fusion_input.Input( - prevTxid: utf8.encode(txid), - prevIndex: vout, - pubKey: addr.publicKey, - amount: value, - ); + /// Converts a Stack Wallet UTXO to a FusionDart Input. + Future<fusion_input.Input> toFusionInput({ + required String walletId, + required MainDB dbInstance, + }) async { + if (address == null) { + throw Exception("toFusionInput Address is null"); + } + + try { + final Address addr = await _getAddressPubkey( + address: address!, + walletId: walletId, + dbInstance: dbInstance, + ); + + if (addr.publicKey.isEmpty) { + throw Exception("Public key for fetched address is empty"); + } + + return fusion_input.Input( + prevTxid: utf8.encode(txid), + prevIndex: vout, + pubKey: addr.publicKey, + amount: value, + ); + } catch (e) { + rethrow; + } } /// Converts a Stack Wallet UTXO to a FusionDart Output... eventually. - Future<fusion_output.Output> toFusionOutput() async { + Future<fusion_output.Output> toFusionOutput({ + required String walletId, + required MainDB dbInstance, + }) async { if (address == null) { throw Exception("toFutionOutput Address is null"); } // Search isar for address to get pubKey. - Address addr = await FusionWalletInterface.getAddress(address!); + final Address addr = await _getAddressPubkey( + address: address!, + walletId: walletId, + dbInstance: dbInstance, + ); + + if (addr.publicKey.isEmpty) { + throw Exception("Public key for fetched address is empty"); + } + + if (addr.derivationPath == null) { + throw Exception("Derivation path for fetched address is empty"); + } return fusion_output.Output( addr: fusion_address.Address( addr: address!, - publicKey: addr.publicKey, // TODO fix public key. - derivationPath: null, // TODO fix derivation path. + publicKey: addr.publicKey, + derivationPath: fusion_address.DerivationPath( + addr.derivationPath!.value, + ), ), value: value, ); From 0a1523f2ce2f452b3d2d16e1b688b9ad6ba7ccc9 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 10:51:47 -0600 Subject: [PATCH 100/379] update fusiondart ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 1cd747f24..75aa93ba2 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 1cd747f248e3eb9d6b09ddf8944c76931ad4f3c7 +Subproject commit 75aa93ba25e59f19c90825ac2e9114b20ac3e538 From d1603d5f72e57453c12a62bf9e1f8b12e19273dc Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 22 Sep 2023 12:18:43 -0500 Subject: [PATCH 101/379] add pubKey to fusion inputs --- .../mixins/fusion_wallet_interface.dart | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 6a4fc3227..3bc8bd4a1 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'package:convert/convert.dart'; import 'package:decimal/decimal.dart'; import 'package:fusiondart/fusiondart.dart'; import 'package:fusiondart/src/models/address.dart' as fusion_address; @@ -250,7 +251,6 @@ mixin FusionWalletInterface { } // Find public key. - print("1 getting tx ${e.txid}"); Map<String, dynamic> tx = await _cachedElectrumX.getTransaction( coin: _coin, txHash: e.txid, @@ -395,14 +395,15 @@ mixin FusionWalletInterface { extension FusionAddress on Address { fusion_address.Address toFusionAddress() { if (derivationPath == null) { - throw Exception("Fusion Addresses require a derivation path"); + // throw Exception("Fusion Addresses require a derivation path"); + // TODO calculate a derivation path if it is null. } return fusion_address.Address( addr: value, publicKey: publicKey, derivationPath: fusion_address.DerivationPath( - derivationPath!.value, + derivationPath?.value ?? "", // TODO fix null derivation path. ), ); } @@ -525,6 +526,10 @@ extension FusionTransaction on Transaction { if (_tx["vout"][e.vout]["value"] == null) { throw Exception("Value of vout index ${e.vout} in transaction is null"); } + if (_tx["vout"][e.vout]["scriptPubKey"] == null) { + throw Exception( + "scriptPubKey of vout index ${e.vout} in transaction is null"); + } // TODO replace with conditional chaining? // Assign vout value to amount. @@ -534,9 +539,9 @@ extension FusionTransaction on Transaction { ); return fusion_input.Input( - prevTxid: utf8.encode(e.txid), // TODO verify this is what we want. - prevIndex: e.vout, // TODO verify this is what we want. - pubKey: utf8.encode('0000'), // TODO fix public key. + prevTxid: utf8.encode(e.txid), + prevIndex: e.vout, + pubKey: hex.decode("${_tx["vout"][e.vout]["scriptPubKey"]}"), amount: value.raw.toInt(), ); }).toList()); @@ -565,8 +570,9 @@ extension FusionTransaction on Transaction { .publicKey; // TODO IMPORTANT: this address may not be *the* address in question :) } if (address.value!.derivationPath != null) { - derivationPath = fusion_address.DerivationPath( - address.value!.derivationPath!.toString()); + derivationPath = fusion_address.DerivationPath(address + .value!.derivationPath! + .toString()); // TODO IMPORTANT: this address may not be *the* address in question :) } else { // TODO calculate derivation path if it is null. /* From af40bf366796469027f8adb86893772f296e826a Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 12:50:59 -0600 Subject: [PATCH 102/379] some FusionTransaction extension TODO cleanup --- .../mixins/fusion_wallet_interface.dart | 142 ++++++++++-------- 1 file changed, 79 insertions(+), 63 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 3bc8bd4a1..190bcd4c9 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:convert/convert.dart'; import 'package:decimal/decimal.dart'; import 'package:fusiondart/fusiondart.dart'; import 'package:fusiondart/src/models/address.dart' as fusion_address; @@ -17,6 +16,7 @@ import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; +import 'package:stackwallet/utilities/extensions/impl/string.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; const String kReservedFusionAddress = "reserved_fusion_address"; @@ -92,7 +92,13 @@ mixin FusionWalletInterface { // Use Future.wait to await all the futures in the set and then convert it to a set. final resultSet = await Future.wait( - _txs.map((tx) => tx.toFusionTransaction(_cachedElectrumX))); + _txs.map( + (tx) => tx.toFusionTransaction( + dbInstance: _db, + cachedElectrumX: _cachedElectrumX, + ), + ), + ); return resultSet; } @@ -499,100 +505,110 @@ extension FusionUTXO on UTXO { /// An extension of Stack Wallet's Transaction class that adds CashFusion functionality. extension FusionTransaction on Transaction { + /// Fetch the public key of an address stored in the database. + Future<String?> _getAddressDerivationPathString({ + required String address, + required MainDB dbInstance, + }) async { + final Address? addr = await dbInstance.getAddress(walletId, address); + + return addr?.derivationPath?.value; + } + // WIP. - Future<fusion_tx.Transaction> toFusionTransaction( - CachedElectrumX cachedElectrumX) async { + Future<fusion_tx.Transaction> toFusionTransaction({ + required CachedElectrumX cachedElectrumX, + required MainDB dbInstance, + }) async { // Initialize Fusion Dart's Transaction object. fusion_tx.Transaction fusionTransaction = fusion_tx.Transaction(); // WIP. - fusionTransaction.Inputs = await Future.wait(inputs.map((e) async { + fusionTransaction.Inputs = await Future.wait(inputs.map((input) async { // Find input amount. Map<String, dynamic> _tx = await cachedElectrumX.getTransaction( - coin: Coin.bitcoincash, - txHash: e.txid, - verbose: true); // TODO is verbose needed? + coin: Coin.bitcoincash, + txHash: input.txid, + verbose: true, + ); + + if (_tx.isEmpty) { + throw Exception("Transaction not found for input: ${input.txid}"); + } // Check if output amount is available. - if (_tx.isEmpty) { - throw Exception("Transaction not found for input: ${e.txid}"); - } - if (_tx["vout"] == null) { - throw Exception("Vout in transaction ${e.txid} is null"); - } - if (_tx["vout"][e.vout] == null) { - throw Exception("Vout index ${e.vout} in transaction is null"); - } - if (_tx["vout"][e.vout]["value"] == null) { - throw Exception("Value of vout index ${e.vout} in transaction is null"); - } - if (_tx["vout"][e.vout]["scriptPubKey"] == null) { + final txVoutAmount = Decimal.tryParse( + _tx["vout"]?[input.vout]?["value"].toString() ?? "", + ); + if (txVoutAmount == null) { throw Exception( - "scriptPubKey of vout index ${e.vout} in transaction is null"); + "Output value at index ${input.vout} in transaction ${input.txid} not found", + ); + } + + final scriptPubKeyHex = + _tx["vout"]?[input.vout]?["scriptPubKey"] as String?; + if (scriptPubKeyHex == null) { + throw Exception( + "scriptPubKey of vout index ${input.vout} in transaction is null", + ); } - // TODO replace with conditional chaining? // Assign vout value to amount. final value = Amount.fromDecimal( - Decimal.parse(_tx["vout"][e.vout]["value"].toString()), + txVoutAmount, fractionDigits: Coin.bitcoincash.decimals, ); return fusion_input.Input( - prevTxid: utf8.encode(e.txid), - prevIndex: e.vout, - pubKey: hex.decode("${_tx["vout"][e.vout]["scriptPubKey"]}"), + prevTxid: utf8.encode(input.txid), + prevIndex: input.vout, + pubKey: scriptPubKeyHex.toUint8ListFromHex, amount: value.raw.toInt(), ); }).toList()); - fusionTransaction.Outputs = outputs.map((e) { - /* - if (e.scriptPubKey == null) { - // TODO calculate scriptPubKey if it is null. + fusionTransaction.Outputs = await Future.wait(outputs.map((output) async { + // TODO: maybe only need one of these but IIRC scriptPubKeyAddress is required for bitcoincash transactions? + if (output.scriptPubKeyAddress.isEmpty) { + throw Exception("isar model output.scriptPubKeyAddress is empty!"); + } + if (output.scriptPubKey == null || output.scriptPubKey!.isEmpty) { + throw Exception("isar model output.scriptPubKey is null or empty!"); } - */ - fusion_address.DerivationPath? derivationPath; - List<int>? pubKey; + final outputAddress = output.scriptPubKeyAddress; + final outputAddressScriptPubKey = output.scriptPubKey!.toUint8ListFromHex; - // Validate that we have all the required data. - if (address.value == null) { - // TODO calculate address if it is null. - throw Exception( - "address value is null for input: ${e.scriptPubKeyAddress}"); + // fetch address derivation path + final derivationPathString = await _getAddressDerivationPathString( + address: outputAddress, + dbInstance: dbInstance, + ); + fusion_address.DerivationPath derivationPath; + if (derivationPathString == null) { + // TODO: check on this: + // Either the address is not an address of this wallet + // or we need to find out what it is. + // If the former, then the issue cannot be easily solved as we will + // have no way of finding out what the derivation path is. + // Throw exception for now. + throw Exception("derivationPathString is null"); } else { - if (address.value!.publicKey.isEmpty || e.scriptPubKey != null) { - pubKey = utf8.encode(e.scriptPubKey!); - // TODO is this valid? - } else { - pubKey = address.value! - .publicKey; // TODO IMPORTANT: this address may not be *the* address in question :) - } - if (address.value!.derivationPath != null) { - derivationPath = fusion_address.DerivationPath(address - .value!.derivationPath! - .toString()); // TODO IMPORTANT: this address may not be *the* address in question :) - } else { - // TODO calculate derivation path if it is null. - /* - throw Exception( - "derivationPath is null for input: ${e.scriptPubKeyAddress}"); - */ - } + derivationPath = fusion_address.DerivationPath( + derivationPathString, + ); } - // TODO handle case where address.value.publicKey is empty and e.scriptPubKey is null - return fusion_output.Output( addr: fusion_address.Address( - addr: e.scriptPubKeyAddress, - publicKey: pubKey, + addr: output.scriptPubKeyAddress, + publicKey: outputAddressScriptPubKey, derivationPath: derivationPath, ), - value: e.value, + value: output.value, ); - }).toList(); + }).toList()); return fusionTransaction; } From 40b029351ddb0f6fd706e30a8cb68b5ec2a414de Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 13:01:02 -0600 Subject: [PATCH 103/379] slight change to output mapping --- lib/services/mixins/fusion_wallet_interface.dart | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 190bcd4c9..83e273f1b 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -585,15 +585,13 @@ extension FusionTransaction on Transaction { address: outputAddress, dbInstance: dbInstance, ); - fusion_address.DerivationPath derivationPath; + + final fusion_address.DerivationPath? derivationPath; if (derivationPathString == null) { // TODO: check on this: - // Either the address is not an address of this wallet - // or we need to find out what it is. - // If the former, then the issue cannot be easily solved as we will - // have no way of finding out what the derivation path is. - // Throw exception for now. - throw Exception("derivationPathString is null"); + // The address is not an address of this wallet and in that case we + // cannot know the derivation path + derivationPath = null; } else { derivationPath = fusion_address.DerivationPath( derivationPathString, From 55e6e56a2dc6a723010f97f738ea1a846c73dbde Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 22 Sep 2023 14:20:19 -0500 Subject: [PATCH 104/379] replace bitcoindart with coinlib --- fusiondart | 2 +- .../mixins/fusion_wallet_interface.dart | 32 +++++++++++-------- pubspec.lock | 18 ++++++++++- pubspec.yaml | 2 ++ 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/fusiondart b/fusiondart index 75aa93ba2..2ad674946 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 75aa93ba25e59f19c90825ac2e9114b20ac3e538 +Subproject commit 2ad67494611097d2471ff1f3a1f57c88e8f38ce8 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 190bcd4c9..1a2301b3f 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'package:convert/convert.dart'; import 'package:decimal/decimal.dart'; import 'package:fusiondart/fusiondart.dart'; import 'package:fusiondart/src/models/address.dart' as fusion_address; @@ -527,10 +528,7 @@ extension FusionTransaction on Transaction { fusionTransaction.Inputs = await Future.wait(inputs.map((input) async { // Find input amount. Map<String, dynamic> _tx = await cachedElectrumX.getTransaction( - coin: Coin.bitcoincash, - txHash: input.txid, - verbose: true, - ); + coin: Coin.bitcoincash, txHash: input.txid, verbose: true); if (_tx.isEmpty) { throw Exception("Transaction not found for input: ${input.txid}"); @@ -545,14 +543,20 @@ extension FusionTransaction on Transaction { "Output value at index ${input.vout} in transaction ${input.txid} not found", ); } - - final scriptPubKeyHex = - _tx["vout"]?[input.vout]?["scriptPubKey"] as String?; - if (scriptPubKeyHex == null) { - throw Exception( - "scriptPubKey of vout index ${input.vout} in transaction is null", - ); + if (_tx["vout"] == null) { + throw Exception("Vout in transaction ${input.txid} is null"); } + if (_tx["vout"][input.vout] == null) { + throw Exception("Vout index ${input.vout} in transaction is null"); + } + if (_tx["vout"][input.vout]["scriptPubKey"] == null) { + throw Exception("scriptPubKey at vout index ${input.vout} is null"); + } + if (_tx["vout"][input.vout]["scriptPubKey"]["hex"] == null) { + throw Exception( + "scriptPubKey hex of vout index ${input.vout} in transaction is null"); + } + // TODO replace with conditional chaining? // Assign vout value to amount. final value = Amount.fromDecimal( @@ -563,7 +567,7 @@ extension FusionTransaction on Transaction { return fusion_input.Input( prevTxid: utf8.encode(input.txid), prevIndex: input.vout, - pubKey: scriptPubKeyHex.toUint8ListFromHex, + pubKey: hex.decode("${_tx["vout"][input.vout]["scriptPubKey"]["hex"]}"), amount: value.raw.toInt(), ); }).toList()); @@ -585,7 +589,7 @@ extension FusionTransaction on Transaction { address: outputAddress, dbInstance: dbInstance, ); - fusion_address.DerivationPath derivationPath; + fusion_address.DerivationPath? derivationPath; if (derivationPathString == null) { // TODO: check on this: // Either the address is not an address of this wallet @@ -593,7 +597,7 @@ extension FusionTransaction on Transaction { // If the former, then the issue cannot be easily solved as we will // have no way of finding out what the derivation path is. // Throw exception for now. - throw Exception("derivationPathString is null"); + // throw Exception("derivationPathString is null"); } else { derivationPath = fusion_address.DerivationPath( derivationPathString, diff --git a/pubspec.lock b/pubspec.lock index 9a487f834..e7599a701 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -262,6 +262,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.6.0" + coinlib: + dependency: "direct main" + description: + name: coinlib + sha256: "410993f49aef30e48b76bbad8a33fef33f6b90e103b15b6be0277683ffe15399" + url: "https://pub.dev" + source: hosted + version: "1.0.0" collection: dependency: transitive description: @@ -287,7 +295,7 @@ packages: source: hosted version: "1.2.4" convert: - dependency: transitive + dependency: "direct main" description: name: convert sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" @@ -1861,6 +1869,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.12+1" + wasm_interop: + dependency: transitive + description: + name: wasm_interop + sha256: b1b378f07a4cf0103c25faf34d9a64d2c3312135b9efb47e0ec116ec3b14e48f + url: "https://pub.dev" + source: hosted + version: "2.0.1" watcher: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c8c975885..00890539c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -149,6 +149,8 @@ dependencies: bip340: ^0.2.0 tezart: ^2.0.5 socks5_proxy: ^1.0.3+dev.3 + coinlib: ^1.0.0 + convert: ^3.1.1 dev_dependencies: flutter_test: From 7d2aaa28aa02f94ac1855bc632279c5586ed4aae Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 13:33:36 -0600 Subject: [PATCH 105/379] fix merge issue --- .../mixins/fusion_wallet_interface.dart | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index ad2a13094..83e273f1b 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:convert/convert.dart'; import 'package:decimal/decimal.dart'; import 'package:fusiondart/fusiondart.dart'; import 'package:fusiondart/src/models/address.dart' as fusion_address; @@ -528,7 +527,10 @@ extension FusionTransaction on Transaction { fusionTransaction.Inputs = await Future.wait(inputs.map((input) async { // Find input amount. Map<String, dynamic> _tx = await cachedElectrumX.getTransaction( - coin: Coin.bitcoincash, txHash: input.txid, verbose: true); + coin: Coin.bitcoincash, + txHash: input.txid, + verbose: true, + ); if (_tx.isEmpty) { throw Exception("Transaction not found for input: ${input.txid}"); @@ -543,20 +545,14 @@ extension FusionTransaction on Transaction { "Output value at index ${input.vout} in transaction ${input.txid} not found", ); } - if (_tx["vout"] == null) { - throw Exception("Vout in transaction ${input.txid} is null"); - } - if (_tx["vout"][input.vout] == null) { - throw Exception("Vout index ${input.vout} in transaction is null"); - } - if (_tx["vout"][input.vout]["scriptPubKey"] == null) { - throw Exception("scriptPubKey at vout index ${input.vout} is null"); - } - if (_tx["vout"][input.vout]["scriptPubKey"]["hex"] == null) { + + final scriptPubKeyHex = + _tx["vout"]?[input.vout]?["scriptPubKey"] as String?; + if (scriptPubKeyHex == null) { throw Exception( - "scriptPubKey hex of vout index ${input.vout} in transaction is null"); + "scriptPubKey of vout index ${input.vout} in transaction is null", + ); } - // TODO replace with conditional chaining? // Assign vout value to amount. final value = Amount.fromDecimal( @@ -567,7 +563,7 @@ extension FusionTransaction on Transaction { return fusion_input.Input( prevTxid: utf8.encode(input.txid), prevIndex: input.vout, - pubKey: hex.decode("${_tx["vout"][input.vout]["scriptPubKey"]["hex"]}"), + pubKey: scriptPubKeyHex.toUint8ListFromHex, amount: value.raw.toInt(), ); }).toList()); From f2854c0bc6d48d86660f66fa5e847e6f8a35fc0b Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 22 Sep 2023 14:49:08 -0500 Subject: [PATCH 106/379] fix scriptPubKeyHex --- lib/services/mixins/fusion_wallet_interface.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 83e273f1b..5a9cb6cbe 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -547,7 +547,7 @@ extension FusionTransaction on Transaction { } final scriptPubKeyHex = - _tx["vout"]?[input.vout]?["scriptPubKey"] as String?; + _tx["vout"]?[input.vout]?["scriptPubKey"]?["hex"] as String?; if (scriptPubKeyHex == null) { throw Exception( "scriptPubKey of vout index ${input.vout} in transaction is null", From 04403d5e1eccc6dea1d88be95a94d9150b9cff51 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 22 Sep 2023 15:07:41 -0500 Subject: [PATCH 107/379] fix numBlanks calculation in fusiondart --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 2ad674946..929aedac5 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 2ad67494611097d2471ff1f3a1f57c88e8f38ce8 +Subproject commit 929aedac530048ec23efcf23707506fcb0c79057 From 59ac1563bc60c0b8875a9960e1e0fc6afe5f4b44 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 14:25:38 -0600 Subject: [PATCH 108/379] decode hex --- .../mixins/fusion_wallet_interface.dart | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 5a9cb6cbe..15e014dbe 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -258,27 +258,22 @@ mixin FusionWalletInterface { // Find public key. Map<String, dynamic> tx = await _cachedElectrumX.getTransaction( - coin: _coin, - txHash: e.txid, - verbose: true); // TODO is verbose needed? + coin: _coin, + txHash: e.txid, + verbose: true, + ); // Check if scriptPubKey is available. - if (tx["vout"] == null) { - throw Exception("Vout in transaction ${e.txid} is null"); - } - if (tx["vout"][e.vout] == null) { - throw Exception("Vout index ${e.vout} in transaction is null"); - } - if (tx["vout"][e.vout]["scriptPubKey"] == null) { - throw Exception("scriptPubKey at vout index ${e.vout} is null"); - } - if (tx["vout"][e.vout]["scriptPubKey"]["hex"] == null) { - throw Exception("hex in scriptPubKey at vout index ${e.vout} is null"); + final scriptPubKeyHex = + tx["vout"]?[e.vout]?["scriptPubKey"]?["hex"] as String?; + if (scriptPubKeyHex == null) { + throw Exception( + "hex in scriptPubKey of vout index ${e.vout} in transaction is null", + ); } // Assign scriptPubKey to pubKey. TODO verify this is correct. - List<int> pubKey = - utf8.encode("${tx["vout"][e.vout]["scriptPubKey"]["hex"]}"); + List<int> pubKey = scriptPubKeyHex.toUint8ListFromHex; // Add UTXO to coinList. coinList.add((e.txid, e.vout, e.value, pubKey)); From 5527678b94803c2fed794dddd7a7017e9ad1436e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 15:44:40 -0600 Subject: [PATCH 109/379] tor fusion service --- lib/services/fusion_tor_service.dart | 71 +++++++++++++++++++ .../mixins/fusion_wallet_interface.dart | 59 +++++++-------- 2 files changed, 101 insertions(+), 29 deletions(-) create mode 100644 lib/services/fusion_tor_service.dart diff --git a/lib/services/fusion_tor_service.dart b/lib/services/fusion_tor_service.dart new file mode 100644 index 000000000..eb8914e30 --- /dev/null +++ b/lib/services/fusion_tor_service.dart @@ -0,0 +1,71 @@ +import 'dart:io'; + +import 'package:stackwallet/utilities/logger.dart'; +import 'package:tor_ffi_plugin/tor_ffi_plugin.dart'; + +class FusionTorService { + Tor? _tor; + String? _torDataDirPath; + + TorStatus get status => _tor!.status; + + /// Singleton instance of the TorService. + /// + /// Use this to access the TorService and its properties. + static final sharedInstance = FusionTorService._(); + + // private constructor for singleton + FusionTorService._(); + + /// Getter for the proxyInfo. + /// + /// Throws if Tor is not connected. + ({ + InternetAddress host, + int port, + }) getProxyInfo() { + try { + return ( + host: InternetAddress.loopbackIPv4, + port: _tor!.port, + ); + } catch (_) { + throw Exception("Tor proxy info fetched while not connected!"); + } + } + + /// Initialize the tor ffi lib instance if it hasn't already been set. Nothing + /// changes if _tor is already been set. + void init({ + required String torDataDirPath, + Tor? mockableOverride, + }) { + _tor ??= mockableOverride ?? Tor.instance; + _torDataDirPath ??= torDataDirPath; + } + + /// Start the Tor service. + /// + /// This will start the Tor service and establish a Tor circuit. + /// + /// Throws an exception if the Tor library was not inited or if the Tor + /// service fails to start. + /// + /// Returns a Future that completes when the Tor service has started. + Future<void> start() async { + if (_tor == null || _torDataDirPath == null) { + throw Exception("FusionTorService.init has not been called!"); + } + + // Start the Tor service. + try { + await _tor!.start(torDataDirPath: _torDataDirPath!); + } catch (e, s) { + Logging.instance.log( + "FusionTorService.start failed: $e\n$s", + level: LogLevel.Warning, + ); + rethrow; + } + } +} diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 15e014dbe..73d771845 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -12,7 +12,7 @@ import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; -import 'package:stackwallet/services/tor_service.dart'; +import 'package:stackwallet/services/fusion_tor_service.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; @@ -28,7 +28,7 @@ mixin FusionWalletInterface { late final Coin _coin; late final MainDB _db; late final CachedElectrumX _cachedElectrumX; - late final TorService _torService; + late final FusionTorService _torService; // Passed in wallet functions. late final Future<Address> Function( @@ -58,25 +58,8 @@ mixin FusionWalletInterface { _coin = coin; _db = db; _generateAddressForChain = generateAddressForChain; - _torService = TorService.sharedInstance; + _torService = FusionTorService.sharedInstance; _cachedElectrumX = cachedElectrumX; - - // Try getting the proxy info. - // - // Start the Tor service if it's not already running. Returns if Tor is already - // connected or else after Tor returns from start(). - try { - _torService.getProxyInfo(); - // Proxy info successfully retrieved, Tor is connected. - return; - } catch (e) { - // Init the Tor service if it hasn't already been. - final torDir = await StackFileSystem.applicationTorDirectory(); - _torService.init(torDataDirPath: torDir.path); - - // Start the Tor service. - return await _torService.start(); - } } /// Returns a list of all addresses in the wallet. @@ -198,20 +181,38 @@ mixin FusionWalletInterface { return unusedAddresses; } + int _torStartCount = 0; + /// Returns the current Tor proxy address. Future<({InternetAddress host, int port})> getSocksProxyAddress() async { - /* - // Start the Tor service if it's not already running. - if (_torService.proxyInfo.port == -1) { // -1 indicates that the proxy is not running. - await _torService.start(); // We already unawaited this in initFusionInterface... + if (_torStartCount > 5) { + // something is quite broken so stop trying to recursively fetch + // start up tor and fetch proxy info + throw Exception( + "Fusion interface attempted to start tor $_torStartCount times and failed!", + ); } - */ - // TODO make sure we've properly awaited the Tor service starting before - // returning the proxy address. + try { + final info = _torService.getProxyInfo(); - // Return the proxy address. - return _torService.getProxyInfo(); + // reset counter before return info; + _torStartCount = 0; + + return info; + } catch (_) { + // tor is probably not running so lets fix that + final torDir = await StackFileSystem.applicationTorDirectory(); + _torService.init(torDataDirPath: torDir.path); + + // increment start attempt count + _torStartCount++; + + await _torService.start(); + + // try again to fetch proxy info + return await getSocksProxyAddress(); + } } // Initial attempt for CashFusion integration goes here. From a4f8c52148e8003bb191c9f571399d88aa8d56a4 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 15:59:07 -0600 Subject: [PATCH 110/379] pass in getter function for electrumx instance instead of keeping an old reference if the node connection info has changed. This ensures the electrumx calls done from the fusion interface use the updated node info --- .../coins/bitcoincash/bitcoincash_wallet.dart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index f96c1b54a..b52614ed8 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -140,7 +140,7 @@ class BitcoinCashWallet extends CoinServiceAPI coin: coin, db: db, generateAddressForChain: _generateAddressForChain, - cachedElectrumX: cachedElectrumXClient, + getWalletCachedElectrumX: () => cachedElectrumXClient, ); initCoinControlInterface( walletId: walletId, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 73d771845..40aa8529d 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -27,7 +27,6 @@ mixin FusionWalletInterface { late final String _walletId; late final Coin _coin; late final MainDB _db; - late final CachedElectrumX _cachedElectrumX; late final FusionTorService _torService; // Passed in wallet functions. @@ -37,6 +36,8 @@ mixin FusionWalletInterface { DerivePathType derivePathType, ) _generateAddressForChain; + late final CachedElectrumX Function() _getWalletCachedElectrumX; + /// Initializes the FusionWalletInterface mixin. /// /// This function must be called before any other functions in this mixin. @@ -51,7 +52,7 @@ mixin FusionWalletInterface { int, DerivePathType, ) generateAddressForChain, - required CachedElectrumX cachedElectrumX, + required CachedElectrumX Function() getWalletCachedElectrumX, }) async { // Set passed in wallet data. _walletId = walletId; @@ -59,7 +60,7 @@ mixin FusionWalletInterface { _db = db; _generateAddressForChain = generateAddressForChain; _torService = FusionTorService.sharedInstance; - _cachedElectrumX = cachedElectrumX; + _getWalletCachedElectrumX = getWalletCachedElectrumX; } /// Returns a list of all addresses in the wallet. @@ -78,7 +79,7 @@ mixin FusionWalletInterface { _txs.map( (tx) => tx.toFusionTransaction( dbInstance: _db, - cachedElectrumX: _cachedElectrumX, + cachedElectrumX: _getWalletCachedElectrumX(), ), ), ); @@ -258,7 +259,8 @@ mixin FusionWalletInterface { } // Find public key. - Map<String, dynamic> tx = await _cachedElectrumX.getTransaction( + Map<String, dynamic> tx = + await _getWalletCachedElectrumX().getTransaction( coin: _coin, txHash: e.txid, verbose: true, From b0d0fec5e4ee4d3a276b9e359646d85e8dd4e978 Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Fri, 22 Sep 2023 16:20:48 -0600 Subject: [PATCH 111/379] WIP: fusion progress provider --- lib/models/fusion_progress_state.dart | 44 +++++++++++++++++++++++ lib/models/fusion_progress_ui_state.dart | 46 ++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 lib/models/fusion_progress_state.dart diff --git a/lib/models/fusion_progress_state.dart b/lib/models/fusion_progress_state.dart new file mode 100644 index 000000000..a382d71c4 --- /dev/null +++ b/lib/models/fusion_progress_state.dart @@ -0,0 +1,44 @@ +import 'package:flutter/cupertino.dart'; +import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; +import 'package:stackwallet/services/coins/manager.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; + +class FusionProgressState extends ChangeNotifier { + final String walletId; + final String walletName; + final Coin coin; + late CashFusionStatus _fusionStatus; + Manager? manager; + String? address; + + CashFusionStatus get fusionState => _fusionStatus; + set fusionState(CashFusionStatus fusionStatus) { + _fusionStatus = fusionStatus; + notifyListeners(); + } + + FusionProgressState({ + required this.walletId, + required this.walletName, + required this.coin, + required CashFusionStatus fusionStatus, + this.manager, + this.address, + }) { + _fusionStatus = fusionStatus; + } + + FusionProgressState copyWith({ + CashFusionStatus? fusionStatus, + String? address, + }) { + return FusionProgressState( + walletId: walletId, + walletName: walletName, + coin: coin, + fusionStatus: fusionStatus ?? _fusionStatus, + manager: manager, + address: this.address, + ); + } +} diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 86bb558e1..1fbf1f7fd 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -1,6 +1,8 @@ import 'package:flutter/cupertino.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; +import 'fusion_progress_state.dart'; + class FusionProgressUIState extends ChangeNotifier { bool _ableToConnect = false; @@ -19,9 +21,33 @@ class FusionProgressUIState extends ChangeNotifier { (_fusing == CashFusionStatus.failed); _done &= (_complete == CashFusionStatus.success) || (_complete == CashFusionStatus.failed); + + // for (final wallet in _walletStates.values) { + // _done &= (wallet.restoringState == CashFusionStatus.success) || + // (wallet.restoringState == CashFusionStatus.failed); + // } + return _done; } + bool get succeeded { + if (!_ableToConnect) { + return false; + } + + bool _succeeded = _connecting == CashFusionStatus.success; + _succeeded &= _outputs == CashFusionStatus.success; + _succeeded &= _peers == CashFusionStatus.success; + _succeeded &= _fusing == CashFusionStatus.success; + _succeeded &= _complete == CashFusionStatus.success; + + // for (final wallet in _walletStates.values) { + // _succeeded &= wallet.restoringState == StackRestoringStatus.success; + // } + + return _succeeded; + } + CashFusionStatus _connecting = CashFusionStatus.waiting; CashFusionStatus get connecting => _connecting; set connecting(CashFusionStatus state) { @@ -56,4 +82,24 @@ class FusionProgressUIState extends ChangeNotifier { _complete = state; notifyListeners(); } + + // List<Manager> get managers { + // List<Manager> _managers = []; + // for (final item in _walletStates.values) { + // if (item.manager != null) { + // _managers.add(item.manager!); + // } + // } + // return _managers; + // } + + Map<String, FusionProgressState> _fusionState = {}; + set fusionState(Map<String, FusionProgressState> state) { + _fusionState = state; + // _fusionStateProviders = {}; + // for (final wallet in _fusionState.values) { + // _fusionStateProviders[wallet.walletId] = + // ChangeNotifierProvider<FusionProgressState>((_) => wallet); + // } + } } From 55d8738acbbfaebc11afcec387236f1931d8fda3 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 16:39:59 -0600 Subject: [PATCH 112/379] check change addresses for transactions automatically in fusion interface change address getter function --- .../coins/bitcoincash/bitcoincash_wallet.dart | 14 +++--- .../mixins/fusion_wallet_interface.dart | 49 ++++++------------- 2 files changed, 23 insertions(+), 40 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index b52614ed8..814d19879 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -136,12 +136,14 @@ class BitcoinCashWallet extends CoinServiceAPI initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); initFusionInterface( - walletId: walletId, - coin: coin, - db: db, - generateAddressForChain: _generateAddressForChain, - getWalletCachedElectrumX: () => cachedElectrumXClient, - ); + walletId: walletId, + coin: coin, + db: db, + getWalletCachedElectrumX: () => cachedElectrumXClient, + getNextUnusedChangeAddress: () async { + await checkCurrentChangeAddressesForTransactions(); + return await _currentChangeAddress; + }); initCoinControlInterface( walletId: walletId, walletName: walletName, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 40aa8529d..76c4ddb91 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -15,7 +15,6 @@ import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/fusion_tor_service.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; -import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/extensions/impl/string.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; @@ -30,12 +29,7 @@ mixin FusionWalletInterface { late final FusionTorService _torService; // Passed in wallet functions. - late final Future<Address> Function( - int chain, - int index, - DerivePathType derivePathType, - ) _generateAddressForChain; - + late final Future<Address> Function() _getNextUnusedChangeAddress; late final CachedElectrumX Function() _getWalletCachedElectrumX; /// Initializes the FusionWalletInterface mixin. @@ -47,18 +41,14 @@ mixin FusionWalletInterface { required String walletId, required Coin coin, required MainDB db, - required Future<Address> Function( - int, - int, - DerivePathType, - ) generateAddressForChain, + required Future<Address> Function() getNextUnusedChangeAddress, required CachedElectrumX Function() getWalletCachedElectrumX, }) async { // Set passed in wallet data. _walletId = walletId; _coin = coin; _db = db; - _generateAddressForChain = generateAddressForChain; + _getNextUnusedChangeAddress = getNextUnusedChangeAddress; _torService = FusionTorService.sharedInstance; _getWalletCachedElectrumX = getWalletCachedElectrumX; } @@ -105,28 +95,14 @@ mixin FusionWalletInterface { /// Creates a new reserved change address. Future<fusion_address.Address> createNewReservedChangeAddress() async { - int? highestChangeIndex = await _db - .getAddresses(_walletId) - .filter() - .typeEqualTo(AddressType.p2pkh) - .subTypeEqualTo(AddressSubType.change) - .derivationPath((q) => q.not().valueStartsWith("m/44'/0'")) - .sortByDerivationIndexDesc() - .derivationIndexProperty() - .findFirst(); + // _getNextUnusedChangeAddress() grabs the latest unused change address + // from the wallet. + // CopyWith to mark it as a fusion reserved change address + final address = (await _getNextUnusedChangeAddress()) + .copyWith(otherData: kReservedFusionAddress); - Address address = await _generateAddressForChain( - 1, // change chain - highestChangeIndex ?? 0, - DerivePathTypeExt.primaryFor(_coin), - ); - address = address.copyWith(otherData: kReservedFusionAddress); - - // TODO if we really want to be sure it's not used, call electrumx and check it - - Address? _address = await _db.getAddress(_walletId, address.value); + final _address = await _db.getAddress(_walletId, address.value); if (_address != null) { - // throw Exception("Address already exists"); await _db.updateAddress(_address, address); } else { await _db.putAddress(address); @@ -145,7 +121,10 @@ mixin FusionWalletInterface { final txns = await _db .getTransactions(_walletId) .filter() - .address((q) => q.otherDataEqualTo(kReservedFusionAddress)) + .address((q) => q + .otherDataEqualTo(kReservedFusionAddress) + .and() + .subTypeEqualTo(AddressSubType.change)) .findAll(); // Fetch all addresses that have been used in a transaction. @@ -159,6 +138,8 @@ mixin FusionWalletInterface { .getAddresses(_walletId) .filter() .otherDataEqualTo(kReservedFusionAddress) + .and() + .subTypeEqualTo(AddressSubType.change) .findAll(); // Initialize a list of unused reserved change addresses. From 593d2c7e7e4967fec0d1f9f7b64276d62a0ad17c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 17:00:32 -0600 Subject: [PATCH 113/379] named record params and clear variable names --- fusiondart | 2 +- .../mixins/fusion_wallet_interface.dart | 44 ++++++++++++------- pubspec.lock | 4 +- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/fusiondart b/fusiondart index 929aedac5..e4877ee7c 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 929aedac530048ec23efcf23707506fcb0c79057 +Subproject commit e4877ee7cad443623e1486e27cb27c8220a0f116 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 76c4ddb91..df5893f24 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -207,7 +207,7 @@ mixin FusionWalletInterface { /// A `Future<void>` that resolves when the fusion operation is finished. Future<void> fuse() async { // Initial attempt for CashFusion integration goes here. - Fusion mainFusionObject = Fusion( + final mainFusionObject = Fusion( getAddresses: () => getFusionAddresses(), getTransactionsByAddress: (String address) => getTransactionsByAddress(address), @@ -220,39 +220,46 @@ mixin FusionWalletInterface { // Pass wallet functions to the Fusion object mainFusionObject.initFusion( - getAddresses: getFusionAddresses, - getTransactionsByAddress: getTransactionsByAddress, - getInputsByAddress: getInputsByAddress, - /*createNewReservedChangeAddress: createNewReservedChangeAddress,*/ - getUnusedReservedChangeAddresses: getUnusedReservedChangeAddresses, - getSocksProxyAddress: getSocksProxyAddress); + getAddresses: getFusionAddresses, + getTransactionsByAddress: getTransactionsByAddress, + getInputsByAddress: getInputsByAddress, + /*createNewReservedChangeAddress: createNewReservedChangeAddress,*/ + getUnusedReservedChangeAddresses: getUnusedReservedChangeAddresses, + getSocksProxyAddress: getSocksProxyAddress, + ); // Add stack UTXOs. - List<UTXO> utxos = await _db.getUTXOs(_walletId).findAll(); - List<(String, int, int, List<int>)> coinList = []; + final List<UTXO> walletUtxos = await _db.getUTXOs(_walletId).findAll(); + final List< + ({ + String txid, + int vout, + int value, + List<int> pubKey, + })> coinList = []; // Loop through UTXOs, checking and adding valid ones. - for (var e in utxos) { + for (final utxo in walletUtxos) { // Check if address is available. - if (e.address == null) { + if (utxo.address == null) { // TODO we could continue here (and below during scriptPubKey validation) instead of throwing. - throw Exception("UTXO ${e.txid}:${e.vout} address is null"); + throw Exception("UTXO ${utxo.txid}:${utxo.vout} address is null"); } // Find public key. Map<String, dynamic> tx = await _getWalletCachedElectrumX().getTransaction( coin: _coin, - txHash: e.txid, + txHash: utxo.txid, verbose: true, ); // Check if scriptPubKey is available. final scriptPubKeyHex = - tx["vout"]?[e.vout]?["scriptPubKey"]?["hex"] as String?; + tx["vout"]?[utxo.vout]?["scriptPubKey"]?["hex"] as String?; if (scriptPubKeyHex == null) { throw Exception( - "hex in scriptPubKey of vout index ${e.vout} in transaction is null", + "hex in scriptPubKey of vout index ${utxo.vout} in transaction is null", ); } @@ -260,7 +267,12 @@ mixin FusionWalletInterface { List<int> pubKey = scriptPubKeyHex.toUint8ListFromHex; // Add UTXO to coinList. - coinList.add((e.txid, e.vout, e.value, pubKey)); + coinList.add(( + txid: utxo.txid, + vout: utxo.vout, + value: utxo.value, + pubKey: pubKey + )); } // Add Stack UTXOs. diff --git a/pubspec.lock b/pubspec.lock index e7599a701..8ac1525b0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1671,8 +1671,8 @@ packages: dependency: "direct main" description: path: "." - ref: c8b97bc118c7bbfe1027d0442cfadea44dc285aa - resolved-ref: c8b97bc118c7bbfe1027d0442cfadea44dc285aa + ref: "0a6888282f4e98401051a396e9d2293bd55ac2c2" + resolved-ref: "0a6888282f4e98401051a396e9d2293bd55ac2c2" url: "https://github.com/cypherstack/tor.git" source: git version: "0.0.1" From 154c72731684be43bfaa82070370538bfd87d6ad Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 22 Sep 2023 17:32:38 -0600 Subject: [PATCH 114/379] Refactor getUnusedReservedChangeAddresses so it doesn't depend on purely Isar links to Transaction objects which will not guarantee to catch all used addresses. --- .../coins/bitcoincash/bitcoincash_wallet.dart | 18 ++++--- .../mixins/fusion_wallet_interface.dart | 50 +++++++++---------- 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 814d19879..70b04c6b5 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -136,14 +136,16 @@ class BitcoinCashWallet extends CoinServiceAPI initCache(walletId, coin); initWalletDB(mockableOverride: mockableOverride); initFusionInterface( - walletId: walletId, - coin: coin, - db: db, - getWalletCachedElectrumX: () => cachedElectrumXClient, - getNextUnusedChangeAddress: () async { - await checkCurrentChangeAddressesForTransactions(); - return await _currentChangeAddress; - }); + walletId: walletId, + coin: coin, + db: db, + getWalletCachedElectrumX: () => cachedElectrumXClient, + getNextUnusedChangeAddress: () async { + await checkCurrentChangeAddressesForTransactions(); + return await _currentChangeAddress; + }, + getTxCountForAddress: getTxCount, + ); initCoinControlInterface( walletId: walletId, walletName: walletName, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index df5893f24..8a8d6d511 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -31,6 +31,9 @@ mixin FusionWalletInterface { // Passed in wallet functions. late final Future<Address> Function() _getNextUnusedChangeAddress; late final CachedElectrumX Function() _getWalletCachedElectrumX; + late final Future<int> Function({ + required String address, + }) _getTxCountForAddress; /// Initializes the FusionWalletInterface mixin. /// @@ -43,6 +46,9 @@ mixin FusionWalletInterface { required MainDB db, required Future<Address> Function() getNextUnusedChangeAddress, required CachedElectrumX Function() getWalletCachedElectrumX, + required Future<int> Function({ + required String address, + }) getTxCountForAddress, }) async { // Set passed in wallet data. _walletId = walletId; @@ -51,6 +57,7 @@ mixin FusionWalletInterface { _getNextUnusedChangeAddress = getNextUnusedChangeAddress; _torService = FusionTorService.sharedInstance; _getWalletCachedElectrumX = getWalletCachedElectrumX; + _getTxCountForAddress = getTxCountForAddress; } /// Returns a list of all addresses in the wallet. @@ -117,24 +124,8 @@ mixin FusionWalletInterface { Future<List<fusion_address.Address>> getUnusedReservedChangeAddresses( int numberOfAddresses, ) async { - // Fetch all transactions that have been sent to a reserved change address. - final txns = await _db - .getTransactions(_walletId) - .filter() - .address((q) => q - .otherDataEqualTo(kReservedFusionAddress) - .and() - .subTypeEqualTo(AddressSubType.change)) - .findAll(); - - // Fetch all addresses that have been used in a transaction. - final List<String> usedAddresses = txns - .where((e) => e.address.value != null) - .map((e) => e.address.value!.value) - .toList(growable: false); - // Fetch all reserved change addresses. - final List<Address> addresses = await _db + final List<Address> reservedChangeAddresses = await _db .getAddresses(_walletId) .filter() .otherDataEqualTo(kReservedFusionAddress) @@ -145,18 +136,27 @@ mixin FusionWalletInterface { // Initialize a list of unused reserved change addresses. final List<fusion_address.Address> unusedAddresses = []; - // Add any unused reserved change addresses to the list. - for (final address in addresses) { - if (!usedAddresses.contains(address.value)) { - unusedAddresses.add(address.toFusionAddress()); + // check addresses for tx history + for (final address in reservedChangeAddresses) { + // first check in db to avoid unnecessary network calls + final txCountInDB = await _db + .getTransactions(_walletId) + .filter() + .address((q) => q.valueEqualTo(address.value)) + .count(); + if (txCountInDB == 0) { + // double check via electrumx + // _getTxCountForAddress can throw! + final count = await _getTxCountForAddress(address: address.value); + if (count == 0) { + unusedAddresses.add(address.toFusionAddress()); + } } } // If there are not enough unused reserved change addresses, create new ones. - if (unusedAddresses.length < numberOfAddresses) { - for (int i = unusedAddresses.length; i < numberOfAddresses; i++) { - unusedAddresses.add(await createNewReservedChangeAddress()); - } + while (unusedAddresses.length < numberOfAddresses) { + unusedAddresses.add(await createNewReservedChangeAddress()); } // Return the list of unused reserved change addresses. From 7033e640b9b62450be03a16345546894988a968c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 25 Sep 2023 09:00:42 -0600 Subject: [PATCH 115/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index e4877ee7c..b01f3e78a 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit e4877ee7cad443623e1486e27cb27c8220a0f116 +Subproject commit b01f3e78ac18fb88724edc55580e1cd5d10c135c From 6b7b72ef4f7aab8ac53c12dafe19c5f9f773fdab Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 25 Sep 2023 09:26:46 -0600 Subject: [PATCH 116/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index b01f3e78a..7f6e4cc63 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit b01f3e78ac18fb88724edc55580e1cd5d10c135c +Subproject commit 7f6e4cc63e614b4b54fb3571c2b1ad65c5823e29 From 337de9fd11c7ec215359e3728684bf0c6b74e6cb Mon Sep 17 00:00:00 2001 From: ryleedavis <rylee@cypherstack.com> Date: Tue, 26 Sep 2023 09:30:31 -0600 Subject: [PATCH 117/379] WIP: fusion progress provider --- lib/models/fusion_progress_ui_state.dart | 76 ++++++++++++++----- .../cashfusion/desktop_cashfusion_view.dart | 4 + 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 1fbf1f7fd..79faeef36 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -1,5 +1,7 @@ import 'package:flutter/cupertino.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; +import 'package:stackwallet/services/coins/manager.dart'; import 'fusion_progress_state.dart'; @@ -22,10 +24,10 @@ class FusionProgressUIState extends ChangeNotifier { _done &= (_complete == CashFusionStatus.success) || (_complete == CashFusionStatus.failed); - // for (final wallet in _walletStates.values) { - // _done &= (wallet.restoringState == CashFusionStatus.success) || - // (wallet.restoringState == CashFusionStatus.failed); - // } + for (final wallet in _fusionState.values) { + _done &= (wallet.fusionState == CashFusionStatus.success) || + (wallet.fusionState == CashFusionStatus.failed); + } return _done; } @@ -41,9 +43,9 @@ class FusionProgressUIState extends ChangeNotifier { _succeeded &= _fusing == CashFusionStatus.success; _succeeded &= _complete == CashFusionStatus.success; - // for (final wallet in _walletStates.values) { - // _succeeded &= wallet.restoringState == StackRestoringStatus.success; - // } + for (final wallet in _fusionState.values) { + _succeeded &= wallet.fusionState == CashFusionStatus.success; + } return _succeeded; } @@ -83,23 +85,55 @@ class FusionProgressUIState extends ChangeNotifier { notifyListeners(); } - // List<Manager> get managers { - // List<Manager> _managers = []; - // for (final item in _walletStates.values) { - // if (item.manager != null) { - // _managers.add(item.manager!); - // } - // } - // return _managers; - // } + List<Manager> get managers { + List<Manager> _managers = []; + for (final item in _fusionState.values) { + if (item.manager != null) { + _managers.add(item.manager!); + } + } + return _managers; + } Map<String, FusionProgressState> _fusionState = {}; + Map<String, ChangeNotifierProvider<FusionProgressState>> + _fusionStateProviders = {}; + Map<String, ChangeNotifierProvider<FusionProgressState>> + get fusionStateProviders => _fusionStateProviders; + set fusionState(Map<String, FusionProgressState> state) { _fusionState = state; - // _fusionStateProviders = {}; - // for (final wallet in _fusionState.values) { - // _fusionStateProviders[wallet.walletId] = - // ChangeNotifierProvider<FusionProgressState>((_) => wallet); - // } + _fusionStateProviders = {}; + for (final wallet in _fusionState.values) { + _fusionStateProviders[wallet.walletId] = + ChangeNotifierProvider<FusionProgressState>((_) => wallet); + } + + /// todo: is this true + _ableToConnect = true; + notifyListeners(); + } + + FusionProgressState getFusionProgressState(String walletId) { + return _fusionState[walletId]!; + } + + ChangeNotifierProvider<FusionProgressState> getFusionProgressStateProvider( + String walletId) { + return _fusionStateProviders[walletId]!; + } + + void update({ + required String walletId, + required CashFusionStatus fusionStatus, + Manager? manager, + String? address, + }) { + _fusionState[walletId]!.fusionState = fusionStatus; + _fusionState[walletId]!.manager = + manager ?? _fusionState[walletId]!.manager; + _fusionState[walletId]!.address = + address ?? _fusionState[walletId]!.address; + notifyListeners(); } } diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 7b63b6f3f..8f93a2a70 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -634,6 +634,10 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { // .wallet as FusionWalletInterface) // .fuse(); + // have nullable of variable type that can be set or unset; of notifier + // when pressed, grab wallet as wallet id + // add to fusion wallet interface and connect to provider + await showDialog( context: context, builder: (context) { From 0a20cbeb200da2cda2f55fc2f662f20aacdc5cce Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 26 Sep 2023 16:14:42 -0500 Subject: [PATCH 118/379] git rm crypto_plugins/tor --- crypto_plugins/tor | 1 - 1 file changed, 1 deletion(-) delete mode 160000 crypto_plugins/tor diff --git a/crypto_plugins/tor b/crypto_plugins/tor deleted file mode 160000 index 038eee7f4..000000000 --- a/crypto_plugins/tor +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 038eee7f4b9b9dcf823f6f5be5e9097fbbaa8ea1 From d760599183b73b91139524140aaa29836bb3add8 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 26 Sep 2023 16:16:24 -0500 Subject: [PATCH 119/379] update fusiondart ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 7f6e4cc63..7e7c4f27b 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 7f6e4cc63e614b4b54fb3571c2b1ad65c5823e29 +Subproject commit 7e7c4f27ba8aececf813a6117eaba549edcb5f89 From 372f95af07a93aacaa349d0441f587ffa1ce4aed Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 27 Sep 2023 15:04:24 -0500 Subject: [PATCH 120/379] update fusiondart ref and integration --- fusiondart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 13 ++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/fusiondart b/fusiondart index 7e7c4f27b..22084e8a4 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 7e7c4f27ba8aececf813a6117eaba549edcb5f89 +Subproject commit 22084e8a4b39c282570645896a12332724f1cdbe diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 8a8d6d511..9303997c7 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -207,19 +207,10 @@ mixin FusionWalletInterface { /// A `Future<void>` that resolves when the fusion operation is finished. Future<void> fuse() async { // Initial attempt for CashFusion integration goes here. - final mainFusionObject = Fusion( - getAddresses: () => getFusionAddresses(), - getTransactionsByAddress: (String address) => - getTransactionsByAddress(address), - getInputsByAddress: (String address) => getInputsByAddress(address), - // createNewReservedChangeAddress: () => createNewReservedChangeAddress(), - getUnusedReservedChangeAddresses: (int numberOfAddresses) => - getUnusedReservedChangeAddresses(numberOfAddresses), - getSocksProxyAddress: () => getSocksProxyAddress(), - ); + final mainFusionObject = Fusion(FusionParams()); // Pass wallet functions to the Fusion object - mainFusionObject.initFusion( + await mainFusionObject.initFusion( getAddresses: getFusionAddresses, getTransactionsByAddress: getTransactionsByAddress, getInputsByAddress: getInputsByAddress, From 06760cff3df33d33c7acf38b017206abd7389670 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 27 Sep 2023 15:57:07 -0500 Subject: [PATCH 121/379] pedersenAmount patch WIP --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 22084e8a4..7683f610e 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 22084e8a4b39c282570645896a12332724f1cdbe +Subproject commit 7683f610e0a1ce3f4e68d2be609b667c80381379 From 6a2df4a76ece83c7c226755ae5e1ff282ac504b8 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 28 Sep 2023 11:05:06 -0500 Subject: [PATCH 122/379] feed in getChainHeight stub --- fusiondart | 2 +- .../mixins/fusion_wallet_interface.dart | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 7683f610e..3d89074c6 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 7683f610e0a1ce3f4e68d2be609b667c80381379 +Subproject commit 3d89074c6a4852d1b92dc837b23e571d9ca9698c diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 9303997c7..436755ca1 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -34,6 +34,7 @@ mixin FusionWalletInterface { late final Future<int> Function({ required String address, }) _getTxCountForAddress; + late final Future<int> Function() _getChainHeight; /// Initializes the FusionWalletInterface mixin. /// @@ -49,6 +50,7 @@ mixin FusionWalletInterface { required Future<int> Function({ required String address, }) getTxCountForAddress, + required Future<int> Function() getChainHeight, }) async { // Set passed in wallet data. _walletId = walletId; @@ -58,6 +60,7 @@ mixin FusionWalletInterface { _torService = FusionTorService.sharedInstance; _getWalletCachedElectrumX = getWalletCachedElectrumX; _getTxCountForAddress = getTxCountForAddress; + _getChainHeight = getChainHeight; } /// Returns a list of all addresses in the wallet. @@ -197,6 +200,21 @@ mixin FusionWalletInterface { } } + /// Returns the current chain height. + /// + /// This function is used by FusionDart to determine if a transaction is + /// confirmed or not. + /// + /// Returns: + /// A `Future<int>` that resolves to the current chain height. + /// + /// Throws: + /// An `Exception` if the chain height cannot be determined. + Future<int> getChainHeight() async { + throw UnimplementedError( + "TODO getChainHeight eg look up chain height from electrumx"); + } + // Initial attempt for CashFusion integration goes here. /// Fuse the wallet's UTXOs. @@ -217,6 +235,7 @@ mixin FusionWalletInterface { /*createNewReservedChangeAddress: createNewReservedChangeAddress,*/ getUnusedReservedChangeAddresses: getUnusedReservedChangeAddresses, getSocksProxyAddress: getSocksProxyAddress, + getChainHeight: getChainHeight, ); // Add stack UTXOs. From 485b4a137919647683f9da001fb851b8d082dcf2 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 28 Sep 2023 11:20:09 -0500 Subject: [PATCH 123/379] pass chainHeight, remove getChainHeight stub typofix --- .../coins/bitcoincash/bitcoincash_wallet.dart | 1 + .../mixins/fusion_wallet_interface.dart | 17 +---------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 70b04c6b5..31e5353d6 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -145,6 +145,7 @@ class BitcoinCashWallet extends CoinServiceAPI return await _currentChangeAddress; }, getTxCountForAddress: getTxCount, + getChainHeight: () async => chainHeight, ); initCoinControlInterface( walletId: walletId, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 436755ca1..f1ae8d4d3 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -200,21 +200,6 @@ mixin FusionWalletInterface { } } - /// Returns the current chain height. - /// - /// This function is used by FusionDart to determine if a transaction is - /// confirmed or not. - /// - /// Returns: - /// A `Future<int>` that resolves to the current chain height. - /// - /// Throws: - /// An `Exception` if the chain height cannot be determined. - Future<int> getChainHeight() async { - throw UnimplementedError( - "TODO getChainHeight eg look up chain height from electrumx"); - } - // Initial attempt for CashFusion integration goes here. /// Fuse the wallet's UTXOs. @@ -235,7 +220,7 @@ mixin FusionWalletInterface { /*createNewReservedChangeAddress: createNewReservedChangeAddress,*/ getUnusedReservedChangeAddresses: getUnusedReservedChangeAddresses, getSocksProxyAddress: getSocksProxyAddress, - getChainHeight: getChainHeight, + getChainHeight: _getChainHeight, ); // Add stack UTXOs. From fcd8b7dd1698ac02a7c099c8061b2ec81f8e645d Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 28 Sep 2023 11:18:49 -0500 Subject: [PATCH 124/379] pass chainHeight, remove getChainHeight stub --- lib/services/mixins/fusion_wallet_interface.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index f1ae8d4d3..add0e94e6 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -60,7 +60,7 @@ mixin FusionWalletInterface { _torService = FusionTorService.sharedInstance; _getWalletCachedElectrumX = getWalletCachedElectrumX; _getTxCountForAddress = getTxCountForAddress; - _getChainHeight = getChainHeight; + _getChainHeight = _getChainHeight; } /// Returns a list of all addresses in the wallet. From b9be8a3af45f6ae5d9e4680e859e9979ba71444c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 10:21:16 -0600 Subject: [PATCH 125/379] self assign fix --- lib/services/mixins/fusion_wallet_interface.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index add0e94e6..f1ae8d4d3 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -60,7 +60,7 @@ mixin FusionWalletInterface { _torService = FusionTorService.sharedInstance; _getWalletCachedElectrumX = getWalletCachedElectrumX; _getTxCountForAddress = getTxCountForAddress; - _getChainHeight = _getChainHeight; + _getChainHeight = getChainHeight; } /// Returns a list of all addresses in the wallet. From 0c07fb7635e4323748b0ce94aca3b3ad06208462 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 28 Sep 2023 11:22:56 -0500 Subject: [PATCH 126/379] fuse on click --- .../cashfusion/desktop_cashfusion_view.dart | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 8f93a2a70..67d6cdc36 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -21,9 +21,11 @@ import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion import 'package:stackwallet/pages_desktop_specific/desktop_menu.dart'; import 'package:stackwallet/pages_desktop_specific/settings/settings_menu.dart'; import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/ui/check_box_state_provider.dart'; import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; @@ -628,11 +630,11 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { PrimaryButton( label: "Start", onPressed: () async { - // await (ref - // .read(walletsChangeNotifierProvider) - // .getManager(widget.walletId) - // .wallet as FusionWalletInterface) - // .fuse(); + await (ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface) + .fuse(); // have nullable of variable type that can be set or unset; of notifier // when pressed, grab wallet as wallet id From 6f25a00e71a5f47aa0f6c3cdf93cb7e84b48875c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 10:31:03 -0600 Subject: [PATCH 127/379] remove unused functions --- .../coins/bitcoincash/bitcoincash_wallet.dart | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 31e5353d6..4d8d5a444 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -205,27 +205,6 @@ class BitcoinCashWallet extends CoinServiceAPI .findFirst()) ?? await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); - Future<String> get currentChangeAddress async => - (await _currentChangeAddress).value; - // TODO return Address instead of String. - - Future<String> get nextChangeAddress async { - // get change <Address> - final currentChange = await _currentChangeAddress; - // use <Address>.derivationmIndex + 1 to get next change address derivation path - final int nextChangeIndex = currentChange.derivationIndex + 1; - // generate next change address - final stack_address.Address newChangeAddress = - await _generateAddressForChain( - 1, - nextChangeIndex, - DerivePathTypeExt.primaryFor( - coin)); // may need to pick other derive path type, eg 44, 49, 84 - - return newChangeAddress.value; - // TODO return Address instead of String. - } - Future<isar_models.Address> get _currentChangeAddress async => (await db .getAddresses(walletId) From 52e05b983351f3ca2287289547f1abe17c447d1b Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 10:34:43 -0600 Subject: [PATCH 128/379] ensure numberOfAddresses are returned and not more --- lib/services/mixins/fusion_wallet_interface.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index f1ae8d4d3..a55f5353a 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -163,7 +163,7 @@ mixin FusionWalletInterface { } // Return the list of unused reserved change addresses. - return unusedAddresses; + return unusedAddresses.sublist(0, numberOfAddresses); } int _torStartCount = 0; From b0b49f922f5c88c8cb68e5f370e79f64023e63d3 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 10:41:39 -0600 Subject: [PATCH 129/379] add fusion models export --- fusiondart | 2 +- .../mixins/fusion_wallet_interface.dart | 54 +++++++++---------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/fusiondart b/fusiondart index 3d89074c6..6cd09fe76 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 3d89074c6a4852d1b92dc837b23e571d9ca9698c +Subproject commit 6cd09fe76af5e20c3bf36dcd11bf26d20140e510 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index a55f5353a..10f7511a1 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -3,11 +3,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:decimal/decimal.dart'; -import 'package:fusiondart/fusiondart.dart'; -import 'package:fusiondart/src/models/address.dart' as fusion_address; -import 'package:fusiondart/src/models/input.dart' as fusion_input; -import 'package:fusiondart/src/models/output.dart' as fusion_output; -import 'package:fusiondart/src/models/transaction.dart' as fusion_tx; +import 'package:fusiondart/fusiondart.dart' as fusion; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; @@ -64,13 +60,13 @@ mixin FusionWalletInterface { } /// Returns a list of all addresses in the wallet. - Future<List<fusion_address.Address>> getFusionAddresses() async { + Future<List<fusion.Address>> getFusionAddresses() async { List<Address> _addresses = await _db.getAddresses(_walletId).findAll(); return _addresses.map((address) => address.toFusionAddress()).toList(); } /// Returns a list of all transactions in the wallet for the given address. - Future<List<fusion_tx.Transaction>> getTransactionsByAddress( + Future<List<fusion.Transaction>> getTransactionsByAddress( String address) async { final _txs = await _db.getTransactions(_walletId).findAll(); @@ -88,10 +84,10 @@ mixin FusionWalletInterface { } /// Returns a list of all UTXOs in the wallet for the given address. - Future<List<fusion_input.Input>> getInputsByAddress(String address) async { + Future<List<fusion.Input>> getInputsByAddress(String address) async { final _utxos = await _db.getUTXOsByAddress(_walletId, address).findAll(); - List<Future<fusion_input.Input>> futureInputs = _utxos + List<Future<fusion.Input>> futureInputs = _utxos .map( (utxo) => utxo.toFusionInput( walletId: _walletId, @@ -104,7 +100,7 @@ mixin FusionWalletInterface { } /// Creates a new reserved change address. - Future<fusion_address.Address> createNewReservedChangeAddress() async { + Future<fusion.Address> createNewReservedChangeAddress() async { // _getNextUnusedChangeAddress() grabs the latest unused change address // from the wallet. // CopyWith to mark it as a fusion reserved change address @@ -124,7 +120,7 @@ mixin FusionWalletInterface { /// Returns a list of unused reserved change addresses. /// /// If there are not enough unused reserved change addresses, new ones are created. - Future<List<fusion_address.Address>> getUnusedReservedChangeAddresses( + Future<List<fusion.Address>> getUnusedReservedChangeAddresses( int numberOfAddresses, ) async { // Fetch all reserved change addresses. @@ -137,7 +133,7 @@ mixin FusionWalletInterface { .findAll(); // Initialize a list of unused reserved change addresses. - final List<fusion_address.Address> unusedAddresses = []; + final List<fusion.Address> unusedAddresses = []; // check addresses for tx history for (final address in reservedChangeAddresses) { @@ -210,7 +206,7 @@ mixin FusionWalletInterface { /// A `Future<void>` that resolves when the fusion operation is finished. Future<void> fuse() async { // Initial attempt for CashFusion integration goes here. - final mainFusionObject = Fusion(FusionParams()); + final mainFusionObject = fusion.Fusion(fusion.FusionParams()); // Pass wallet functions to the Fusion object await mainFusionObject.initFusion( @@ -385,16 +381,16 @@ mixin FusionWalletInterface { /// An extension of Stack Wallet's Address class that adds CashFusion functionality. extension FusionAddress on Address { - fusion_address.Address toFusionAddress() { + fusion.Address toFusionAddress() { if (derivationPath == null) { // throw Exception("Fusion Addresses require a derivation path"); // TODO calculate a derivation path if it is null. } - return fusion_address.Address( + return fusion.Address( addr: value, publicKey: publicKey, - derivationPath: fusion_address.DerivationPath( + derivationPath: fusion.DerivationPath( derivationPath?.value ?? "", // TODO fix null derivation path. ), ); @@ -422,7 +418,7 @@ extension FusionUTXO on UTXO { } /// Converts a Stack Wallet UTXO to a FusionDart Input. - Future<fusion_input.Input> toFusionInput({ + Future<fusion.Input> toFusionInput({ required String walletId, required MainDB dbInstance, }) async { @@ -441,7 +437,7 @@ extension FusionUTXO on UTXO { throw Exception("Public key for fetched address is empty"); } - return fusion_input.Input( + return fusion.Input( prevTxid: utf8.encode(txid), prevIndex: vout, pubKey: addr.publicKey, @@ -453,7 +449,7 @@ extension FusionUTXO on UTXO { } /// Converts a Stack Wallet UTXO to a FusionDart Output. - Future<fusion_output.Output> toFusionOutput({ + Future<fusion.Output> toFusionOutput({ required String walletId, required MainDB dbInstance, }) async { @@ -476,11 +472,11 @@ extension FusionUTXO on UTXO { throw Exception("Derivation path for fetched address is empty"); } - return fusion_output.Output( - addr: fusion_address.Address( + return fusion.Output( + addr: fusion.Address( addr: address!, publicKey: addr.publicKey, - derivationPath: fusion_address.DerivationPath( + derivationPath: fusion.DerivationPath( addr.derivationPath!.value, ), ), @@ -502,12 +498,12 @@ extension FusionTransaction on Transaction { } // WIP. - Future<fusion_tx.Transaction> toFusionTransaction({ + Future<fusion.Transaction> toFusionTransaction({ required CachedElectrumX cachedElectrumX, required MainDB dbInstance, }) async { // Initialize Fusion Dart's Transaction object. - fusion_tx.Transaction fusionTransaction = fusion_tx.Transaction(); + fusion.Transaction fusionTransaction = fusion.Transaction(); // WIP. fusionTransaction.Inputs = await Future.wait(inputs.map((input) async { @@ -546,7 +542,7 @@ extension FusionTransaction on Transaction { fractionDigits: Coin.bitcoincash.decimals, ); - return fusion_input.Input( + return fusion.Input( prevTxid: utf8.encode(input.txid), prevIndex: input.vout, pubKey: scriptPubKeyHex.toUint8ListFromHex, @@ -572,20 +568,20 @@ extension FusionTransaction on Transaction { dbInstance: dbInstance, ); - final fusion_address.DerivationPath? derivationPath; + final fusion.DerivationPath? derivationPath; if (derivationPathString == null) { // TODO: check on this: // The address is not an address of this wallet and in that case we // cannot know the derivation path derivationPath = null; } else { - derivationPath = fusion_address.DerivationPath( + derivationPath = fusion.DerivationPath( derivationPathString, ); } - return fusion_output.Output( - addr: fusion_address.Address( + return fusion.Output( + addr: fusion.Address( addr: output.scriptPubKeyAddress, publicKey: outputAddressScriptPubKey, derivationPath: derivationPath, From 1df986e444a3e2db65342a2841c506d683fd58ea Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 11:09:19 -0600 Subject: [PATCH 130/379] switch to coinlib flutter --- linux/flutter/generated_plugins.cmake | 1 + pubspec.lock | 10 +++++++++- pubspec.yaml | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index f48fdcd94..3a02b87cf 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -15,6 +15,7 @@ list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST + coinlib_flutter tor_ffi_plugin ) diff --git a/pubspec.lock b/pubspec.lock index 8ac1525b0..2eb24b075 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -263,13 +263,21 @@ packages: source: hosted version: "4.6.0" coinlib: - dependency: "direct main" + dependency: transitive description: name: coinlib sha256: "410993f49aef30e48b76bbad8a33fef33f6b90e103b15b6be0277683ffe15399" url: "https://pub.dev" source: hosted version: "1.0.0" + coinlib_flutter: + dependency: "direct main" + description: + name: coinlib_flutter + sha256: d0a6a3694fc8c851f6b912bb1c552e33998e3f453efab3d62f75c0b1773d1ab9 + url: "https://pub.dev" + source: hosted + version: "1.0.0" collection: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 19c33e5e6..f29d94e43 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -149,7 +149,7 @@ dependencies: bip340: ^0.2.0 tezart: ^2.0.5 socks5_proxy: ^1.0.3+dev.3 - coinlib: ^1.0.0 + coinlib_flutter: ^1.0.0 convert: ^3.1.1 dev_dependencies: From 331f5c7614b634b1d3c72cd00f5b2cfd08d5b0f6 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 11:44:17 -0600 Subject: [PATCH 131/379] update fusiondart ref --- fusiondart | 2 +- .../mixins/fusion_wallet_interface.dart | 22 ++++++++----------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/fusiondart b/fusiondart index 6cd09fe76..e4009d5f5 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 6cd09fe76af5e20c3bf36dcd11bf26d20140e510 +Subproject commit e4009d5f588e09ef91b77bae187279421d876e12 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 10f7511a1..2e7d93f15 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -221,13 +221,7 @@ mixin FusionWalletInterface { // Add stack UTXOs. final List<UTXO> walletUtxos = await _db.getUTXOs(_walletId).findAll(); - final List< - ({ - String txid, - int vout, - int value, - List<int> pubKey, - })> coinList = []; + final List<fusion.UtxoDTO> coinList = []; // Loop through UTXOs, checking and adding valid ones. for (final utxo in walletUtxos) { @@ -258,12 +252,14 @@ mixin FusionWalletInterface { List<int> pubKey = scriptPubKeyHex.toUint8ListFromHex; // Add UTXO to coinList. - coinList.add(( - txid: utxo.txid, - vout: utxo.vout, - value: utxo.value, - pubKey: pubKey - )); + coinList.add( + fusion.UtxoDTO( + txid: utxo.txid, + vout: utxo.vout, + value: utxo.value, + pubKey: pubKey, + ), + ); } // Add Stack UTXOs. From 0ff6c2b73a8e681ed9cf0d9d063241c6af8e4a87 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 11:53:40 -0600 Subject: [PATCH 132/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index e4009d5f5..18c880135 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit e4009d5f588e09ef91b77bae187279421d876e12 +Subproject commit 18c88013516b967e44d28113a00168c1f2d296e6 From 534661142a72356cd727c3b96a52f3adf5b282f6 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 13:17:48 -0600 Subject: [PATCH 133/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 18c880135..50e51765b 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 18c88013516b967e44d28113a00168c1f2d296e6 +Subproject commit 50e51765be6c96dbccff12742b597bb440cff396 From 693255a2c09d162665608a9edf3782ce09e3935c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 13:23:45 -0600 Subject: [PATCH 134/379] unneeded log spam --- lib/electrumx_rpc/cached_electrumx.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/electrumx_rpc/cached_electrumx.dart b/lib/electrumx_rpc/cached_electrumx.dart index 8366e259f..a8136dcaf 100644 --- a/lib/electrumx_rpc/cached_electrumx.dart +++ b/lib/electrumx_rpc/cached_electrumx.dart @@ -141,10 +141,10 @@ class CachedElectrumX { await box.put(txHash, result); } - Logging.instance.log("using fetched result", level: LogLevel.Info); + // Logging.instance.log("using fetched result", level: LogLevel.Info); return result; } else { - Logging.instance.log("using cached result", level: LogLevel.Info); + // Logging.instance.log("using cached result", level: LogLevel.Info); return Map<String, dynamic>.from(cachedTx); } } catch (e, s) { From bc0f182b0b05172133b671c2b99adad3e2aac080 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 14:16:48 -0600 Subject: [PATCH 135/379] Simplify fusion_progress_ui_state.dart to work with .family provider, and WIP hook it up to the fusion wallet interface --- lib/models/fusion_progress_state.dart | 44 ------------ lib/models/fusion_progress_ui_state.dart | 69 +++---------------- .../cashfusion/desktop_cashfusion_view.dart | 24 ++++--- .../cashfusion/sub_widgets/fusion_dialog.dart | 28 +++++--- .../fusion_progress_ui_state_provider.dart | 7 +- .../mixins/fusion_wallet_interface.dart | 25 ++++++- 6 files changed, 69 insertions(+), 128 deletions(-) delete mode 100644 lib/models/fusion_progress_state.dart diff --git a/lib/models/fusion_progress_state.dart b/lib/models/fusion_progress_state.dart deleted file mode 100644 index a382d71c4..000000000 --- a/lib/models/fusion_progress_state.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; -import 'package:stackwallet/services/coins/manager.dart'; -import 'package:stackwallet/utilities/enums/coin_enum.dart'; - -class FusionProgressState extends ChangeNotifier { - final String walletId; - final String walletName; - final Coin coin; - late CashFusionStatus _fusionStatus; - Manager? manager; - String? address; - - CashFusionStatus get fusionState => _fusionStatus; - set fusionState(CashFusionStatus fusionStatus) { - _fusionStatus = fusionStatus; - notifyListeners(); - } - - FusionProgressState({ - required this.walletId, - required this.walletName, - required this.coin, - required CashFusionStatus fusionStatus, - this.manager, - this.address, - }) { - _fusionStatus = fusionStatus; - } - - FusionProgressState copyWith({ - CashFusionStatus? fusionStatus, - String? address, - }) { - return FusionProgressState( - walletId: walletId, - walletName: walletName, - coin: coin, - fusionStatus: fusionStatus ?? _fusionStatus, - manager: manager, - address: this.address, - ); - } -} diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 79faeef36..09bc81556 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -1,12 +1,8 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; -import 'package:stackwallet/services/coins/manager.dart'; - -import 'fusion_progress_state.dart'; class FusionProgressUIState extends ChangeNotifier { - bool _ableToConnect = false; + bool _ableToConnect = true; // set to true for now bool get done { if (!_ableToConnect) { @@ -24,10 +20,8 @@ class FusionProgressUIState extends ChangeNotifier { _done &= (_complete == CashFusionStatus.success) || (_complete == CashFusionStatus.failed); - for (final wallet in _fusionState.values) { - _done &= (wallet.fusionState == CashFusionStatus.success) || - (wallet.fusionState == CashFusionStatus.failed); - } + _done &= (fusionState == CashFusionStatus.success) || + (fusionState == CashFusionStatus.failed); return _done; } @@ -43,9 +37,7 @@ class FusionProgressUIState extends ChangeNotifier { _succeeded &= _fusing == CashFusionStatus.success; _succeeded &= _complete == CashFusionStatus.success; - for (final wallet in _fusionState.values) { - _succeeded &= wallet.fusionState == CashFusionStatus.success; - } + _succeeded &= fusionState == CashFusionStatus.success; return _succeeded; } @@ -85,55 +77,10 @@ class FusionProgressUIState extends ChangeNotifier { notifyListeners(); } - List<Manager> get managers { - List<Manager> _managers = []; - for (final item in _fusionState.values) { - if (item.manager != null) { - _managers.add(item.manager!); - } - } - return _managers; - } - - Map<String, FusionProgressState> _fusionState = {}; - Map<String, ChangeNotifierProvider<FusionProgressState>> - _fusionStateProviders = {}; - Map<String, ChangeNotifierProvider<FusionProgressState>> - get fusionStateProviders => _fusionStateProviders; - - set fusionState(Map<String, FusionProgressState> state) { - _fusionState = state; - _fusionStateProviders = {}; - for (final wallet in _fusionState.values) { - _fusionStateProviders[wallet.walletId] = - ChangeNotifierProvider<FusionProgressState>((_) => wallet); - } - - /// todo: is this true - _ableToConnect = true; - notifyListeners(); - } - - FusionProgressState getFusionProgressState(String walletId) { - return _fusionState[walletId]!; - } - - ChangeNotifierProvider<FusionProgressState> getFusionProgressStateProvider( - String walletId) { - return _fusionStateProviders[walletId]!; - } - - void update({ - required String walletId, - required CashFusionStatus fusionStatus, - Manager? manager, - String? address, - }) { - _fusionState[walletId]!.fusionState = fusionStatus; - _fusionState[walletId]!.manager = - manager ?? _fusionState[walletId]!.manager; - _fusionState[walletId]!.address = - address ?? _fusionState[walletId]!.address; + CashFusionStatus _fusionStatus = CashFusionStatus.waiting; + CashFusionStatus get fusionState => _fusionStatus; + set fusionState(CashFusionStatus fusionStatus) { + _fusionStatus = fusionStatus; notifyListeners(); } } diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 67d6cdc36..0c1809450 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -20,6 +20,7 @@ import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_menu.dart'; import 'package:stackwallet/pages_desktop_specific/settings/settings_menu.dart'; +import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/ui/check_box_state_provider.dart'; @@ -630,20 +631,23 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { PrimaryButton( label: "Start", onPressed: () async { - await (ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface) - .fuse(); + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; - // have nullable of variable type that can be set or unset; of notifier - // when pressed, grab wallet as wallet id - // add to fusion wallet interface and connect to provider + fusionWallet.uiState = ref.read( + fusionProgressUIStateProvider(widget.walletId), + ); - await showDialog( + unawaited(fusionWallet.fuse()); + + await showDialog<void>( context: context, builder: (context) { - return FusionDialog(); + return FusionDialog( + walletId: widget.walletId, + ); }, ); }, diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 5d2f50744..88394410b 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -16,8 +16,11 @@ enum CashFusionStatus { waiting, fusing, success, failed } class FusionDialog extends StatelessWidget { const FusionDialog({ Key? key, + required this.walletId, }) : super(key: key); + final String walletId; + @override Widget build(BuildContext context) { Widget _getIconForState(CashFusionStatus state) { @@ -103,8 +106,9 @@ class FusionDialog extends StatelessWidget { height: 20, ), Consumer(builder: (_, ref, __) { - final state = ref.watch(fusionProgressUIStateProvider - .select((value) => value.connecting)); + final state = ref.watch( + fusionProgressUIStateProvider(walletId) + .select((value) => value.connecting)); return RoundedContainer( padding: EdgeInsets.zero, color: @@ -143,8 +147,9 @@ class FusionDialog extends StatelessWidget { height: 12, ), Consumer(builder: (_, ref, __) { - final state = ref.watch(fusionProgressUIStateProvider - .select((value) => value.outputs)); + final state = ref.watch( + fusionProgressUIStateProvider(walletId) + .select((value) => value.outputs)); return RoundedContainer( padding: EdgeInsets.zero, color: @@ -183,8 +188,9 @@ class FusionDialog extends StatelessWidget { height: 12, ), Consumer(builder: (_, ref, __) { - final state = ref.watch(fusionProgressUIStateProvider - .select((value) => value.peers)); + final state = ref.watch( + fusionProgressUIStateProvider(walletId) + .select((value) => value.peers)); return RoundedContainer( padding: EdgeInsets.zero, color: @@ -223,8 +229,9 @@ class FusionDialog extends StatelessWidget { height: 12, ), Consumer(builder: (_, ref, __) { - final state = ref.watch(fusionProgressUIStateProvider - .select((value) => value.fusing)); + final state = ref.watch( + fusionProgressUIStateProvider(walletId) + .select((value) => value.fusing)); return RoundedContainer( padding: EdgeInsets.zero, color: @@ -263,8 +270,9 @@ class FusionDialog extends StatelessWidget { height: 12, ), Consumer(builder: (_, ref, __) { - final state = ref.watch(fusionProgressUIStateProvider - .select((value) => value.complete)); + final state = ref.watch( + fusionProgressUIStateProvider(walletId) + .select((value) => value.complete)); return RoundedContainer( padding: EdgeInsets.zero, color: diff --git a/lib/providers/cash_fusion/fusion_progress_ui_state_provider.dart b/lib/providers/cash_fusion/fusion_progress_ui_state_provider.dart index 2fb74b1f6..872b6586a 100644 --- a/lib/providers/cash_fusion/fusion_progress_ui_state_provider.dart +++ b/lib/providers/cash_fusion/fusion_progress_ui_state_provider.dart @@ -12,5 +12,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/models/fusion_progress_ui_state.dart'; final fusionProgressUIStateProvider = - ChangeNotifierProvider<FusionProgressUIState>( - (ref) => FusionProgressUIState()); + ChangeNotifierProvider.family<FusionProgressUIState, String>( + (ref, walletId) { + return FusionProgressUIState(); + }, +); diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 2e7d93f15..96cf64ef3 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -7,6 +7,7 @@ import 'package:fusiondart/fusiondart.dart' as fusion; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; +import 'package:stackwallet/models/fusion_progress_ui_state.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/fusion_tor_service.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; @@ -24,6 +25,22 @@ mixin FusionWalletInterface { late final MainDB _db; late final FusionTorService _torService; + // setting values on this should notify any listeners (the GUI) + FusionProgressUIState? _uiState; + FusionProgressUIState get uiState { + if (_uiState == null) { + throw Exception("FusionProgressUIState has not been set for $_walletId"); + } + return _uiState!; + } + + set uiState(FusionProgressUIState state) { + if (_uiState != null) { + throw Exception("FusionProgressUIState was already set for $_walletId"); + } + _uiState = state; + } + // Passed in wallet functions. late final Future<Address> Function() _getNextUnusedChangeAddress; late final CachedElectrumX Function() _getWalletCachedElectrumX; @@ -59,6 +76,12 @@ mixin FusionWalletInterface { _getChainHeight = getChainHeight; } + // callback to update the ui state object + void updateStatus(fusion.FusionStatus fusionStatus) { + // TODO: this + // set _uiState states + } + /// Returns a list of all addresses in the wallet. Future<List<fusion.Address>> getFusionAddresses() async { List<Address> _addresses = await _db.getAddresses(_walletId).findAll(); @@ -213,10 +236,10 @@ mixin FusionWalletInterface { getAddresses: getFusionAddresses, getTransactionsByAddress: getTransactionsByAddress, getInputsByAddress: getInputsByAddress, - /*createNewReservedChangeAddress: createNewReservedChangeAddress,*/ getUnusedReservedChangeAddresses: getUnusedReservedChangeAddresses, getSocksProxyAddress: getSocksProxyAddress, getChainHeight: _getChainHeight, + updateStatusCallback: updateStatus, ); // Add stack UTXOs. From 85d29c91a15dd76cde84c799dfbd453dded6b28b Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 14:17:54 -0600 Subject: [PATCH 136/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 50e51765b..3f5b7047e 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 50e51765be6c96dbccff12742b597bb440cff396 +Subproject commit 3f5b7047e8381d58aac56403b8bdc2b42a3fbeed From 6ac15a71f4d1e068677bb741ea030b65acea0c20 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 14:33:58 -0600 Subject: [PATCH 137/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 3f5b7047e..4b7d0d33c 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 3f5b7047e8381d58aac56403b8bdc2b42a3fbeed +Subproject commit 4b7d0d33c3039aca3f297d31b871f8120035c2aa From 21b8f3f0caf2b32acdacc2e2586755ad8b350ebe Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 14:47:06 -0600 Subject: [PATCH 138/379] fix: explicit check of exception --- .../cashfusion/desktop_cashfusion_view.dart | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 0c1809450..0bca26221 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -636,9 +636,16 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { .getManager(widget.walletId) .wallet as FusionWalletInterface; - fusionWallet.uiState = ref.read( - fusionProgressUIStateProvider(widget.walletId), - ); + try { + fusionWallet.uiState = ref.read( + fusionProgressUIStateProvider(widget.walletId), + ); + } catch (e) { + if (!e.toString().contains( + "FusionProgressUIState was already set for ${widget.walletId}")) { + rethrow; + } + } unawaited(fusionWallet.fuse()); From 7b020fbbbb68fbf308d4a09f09f565835a2eec70 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 15:39:59 -0600 Subject: [PATCH 139/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 4b7d0d33c..87137ebb7 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 4b7d0d33c3039aca3f297d31b871f8120035c2aa +Subproject commit 87137ebb74767df3ed9cd6a84323f52beba6b68f From 7c087fadf967d572dbc38becd07d2e1a6abb4739 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 15:41:13 -0600 Subject: [PATCH 140/379] do not close dialog by clicking outside of it --- .../cashfusion/desktop_cashfusion_view.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 0bca26221..eb22f670d 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -651,6 +651,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { await showDialog<void>( context: context, + barrierDismissible: false, builder: (context) { return FusionDialog( walletId: widget.walletId, From 56332f9be7296ce2c958a842818b9a36dd27d91c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 28 Sep 2023 17:12:50 -0600 Subject: [PATCH 141/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 87137ebb7..e05a8f6c1 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 87137ebb74767df3ed9cd6a84323f52beba6b68f +Subproject commit e05a8f6c1977d0ab270ab617ee7aebd162006aaf From dc9a7f65422b8f42f5df01a73538379302d5f322 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 29 Sep 2023 10:32:07 -0600 Subject: [PATCH 142/379] remove duplicate function (addCoinsFromWallet already exists) --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index e05a8f6c1..f436b5f96 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit e05a8f6c1977d0ab270ab617ee7aebd162006aaf +Subproject commit f436b5f962754726b66658fc4e92c727d66746d4 From 1774ad6b73ebe9a8b469e16fe60858d50767cd05 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 29 Sep 2023 10:47:53 -0600 Subject: [PATCH 143/379] remove problem child `_coins` --- fusiondart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fusiondart b/fusiondart index f436b5f96..b11dc661d 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit f436b5f962754726b66658fc4e92c727d66746d4 +Subproject commit b11dc661d14be8acefd575eb105c76129e710dfa diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 96cf64ef3..c61f276c1 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -286,10 +286,10 @@ mixin FusionWalletInterface { } // Add Stack UTXOs. - await mainFusionObject.addCoinsFromWallet(coinList); + final inputs = await mainFusionObject.addCoinsFromWallet(coinList); // Fuse UTXOs. - return await mainFusionObject.fuse(); + return await mainFusionObject.fuse(inputsFromWallet: inputs); //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); // TODO remove or fix code below. From cf1a632642519ced72f91e5f12d1c022446791d8 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 29 Sep 2023 11:07:32 -0600 Subject: [PATCH 144/379] make startCovert functional --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index b11dc661d..742099852 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit b11dc661d14be8acefd575eb105c76129e710dfa +Subproject commit 742099852ba7f38eff847ef71a7c5217e5141675 From 7f3ff14da0497b303f2fca0f054759ac6a5b8d79 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 29 Sep 2023 11:46:20 -0600 Subject: [PATCH 145/379] non "global" Fusion class socket variables --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 742099852..bec7212d2 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 742099852ba7f38eff847ef71a7c5217e5141675 +Subproject commit bec7212d26fff3a0914c11c8802f7bb1db8b6db7 From 33e5980ce2df25b69377566308a12786debb554d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 29 Sep 2023 11:57:53 -0600 Subject: [PATCH 146/379] update fusiondart ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index bec7212d2..28359d604 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit bec7212d26fff3a0914c11c8802f7bb1db8b6db7 +Subproject commit 28359d604b419c7b489addfc0a4cdae9034b1788 From 0a28433fe1712e162ce9c81528062ae6ba6380b8 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 29 Sep 2023 15:12:58 -0600 Subject: [PATCH 147/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 28359d604..18435b6af 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 28359d604b419c7b489addfc0a4cdae9034b1788 +Subproject commit 18435b6af6e3765ee0cd9702f109ea80b6a487d6 From 800399a160a52235bac53c73cb12a60d2e92ec13 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 29 Sep 2023 15:38:06 -0600 Subject: [PATCH 148/379] properly set variables in constructor --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 18435b6af..a2d06e42b 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 18435b6af6e3765ee0cd9702f109ea80b6a487d6 +Subproject commit a2d06e42be3204eb05ec630068436d7b46dd5a6a From 3ef3cab124e1253f7a1ef5e6879e9669b8600f5c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 29 Sep 2023 16:24:09 -0600 Subject: [PATCH 149/379] clean up schedule connections --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index a2d06e42b..aa285589b 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit a2d06e42be3204eb05ec630068436d7b46dd5a6a +Subproject commit aa285589bd723505d21c4f273ed726566d57920c From 719b8fb46c66c6c25dfac1cfd1de81ca2ed6d4ae Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sat, 30 Sep 2023 14:18:17 -0500 Subject: [PATCH 150/379] use socks_socket submodule in fusiondart submodule yo dawg... --- fusiondart | 2 +- pubspec.lock | 7 +++++++ pubspec.yaml | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index aa285589b..3107687d5 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit aa285589bd723505d21c4f273ed726566d57920c +Subproject commit 3107687d58c2708684c897407464e2e54db9fa01 diff --git a/pubspec.lock b/pubspec.lock index 2eb24b075..9784e954a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1482,6 +1482,13 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.3+dev.3" + socks_socket: + dependency: "direct main" + description: + path: "fusiondart/socks_socket" + relative: true + source: path + version: "0.1.0" source_gen: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index f29d94e43..927e056ec 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -146,6 +146,8 @@ dependencies: stellar_flutter_sdk: ^1.5.3 fusiondart: path: ./fusiondart + socks_socket: + path: ./fusiondart/socks_socket bip340: ^0.2.0 tezart: ^2.0.5 socks5_proxy: ^1.0.3+dev.3 From b39ffdf5ef393c19f965ef012978926d1ceaacfb Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sat, 30 Sep 2023 14:59:02 -0500 Subject: [PATCH 151/379] status update and debug prints --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 3107687d5..448451d77 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 3107687d58c2708684c897407464e2e54db9fa01 +Subproject commit 448451d77c326f9711fdd81f53986ca829fc8943 From 71ae22c6a05ee35cf7f2ed64284869eba561b1da Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 2 Oct 2023 10:41:31 -0500 Subject: [PATCH 152/379] update fusiondart#staging ref to use socks_socket package --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index aa285589b..39e8ecd6d 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit aa285589bd723505d21c4f273ed726566d57920c +Subproject commit 39e8ecd6dd1a33530e4c74f3f72ddbde38138c6f From cf053f207123f3ae40d2383963fa38893944c763 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 2 Oct 2023 10:41:49 -0600 Subject: [PATCH 153/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index aa285589b..1a7489830 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit aa285589bd723505d21c4f273ed726566d57920c +Subproject commit 1a748983078db7bf0c4a0fb3c633db6d4940aeb0 From e295357d2d127ddb64cedfffe89a1fffd639612c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 2 Oct 2023 11:32:24 -0600 Subject: [PATCH 154/379] update ref --- fusiondart | 2 +- pubspec.lock | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 1a7489830..da36b1e24 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 1a748983078db7bf0c4a0fb3c633db6d4940aeb0 +Subproject commit da36b1e24f98c45a23490f379e57eabc252a7c81 diff --git a/pubspec.lock b/pubspec.lock index 2eb24b075..db9899be4 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1482,6 +1482,15 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.3+dev.3" + socks_socket: + dependency: transitive + description: + path: "." + ref: ac6d721fe655208a6d488a088a35bab0ddc25702 + resolved-ref: ac6d721fe655208a6d488a088a35bab0ddc25702 + url: "https://github.com/cypherstack/socks_socket.git" + source: git + version: "0.1.0" source_gen: dependency: transitive description: From f29e058c755387444cd035ab26afa55b7ab969dd Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 2 Oct 2023 14:00:10 -0600 Subject: [PATCH 155/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index da36b1e24..a64029ecc 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit da36b1e24f98c45a23490f379e57eabc252a7c81 +Subproject commit a64029eccc12d0ab43d430f76c9434c4e7c279a7 From 10e668ce7bbced8d39e6068c032d558a08692b5f Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 2 Oct 2023 15:04:08 -0500 Subject: [PATCH 156/379] use socks_socket#master --- fusiondart | 2 +- pubspec.lock | 8 +++++--- pubspec.yaml | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/fusiondart b/fusiondart index 448451d77..97d4b9b6d 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 448451d77c326f9711fdd81f53986ca829fc8943 +Subproject commit 97d4b9b6d8a79a965324a55b5001dfe1f54b2a1f diff --git a/pubspec.lock b/pubspec.lock index 9784e954a..ed5f1543a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1485,9 +1485,11 @@ packages: socks_socket: dependency: "direct main" description: - path: "fusiondart/socks_socket" - relative: true - source: path + path: "." + ref: master + resolved-ref: ac6d721fe655208a6d488a088a35bab0ddc25702 + url: "https://github.com/cypherstack/socks_socket.git" + source: git version: "0.1.0" source_gen: dependency: transitive diff --git a/pubspec.yaml b/pubspec.yaml index 927e056ec..5e5c63d6c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -147,7 +147,9 @@ dependencies: fusiondart: path: ./fusiondart socks_socket: - path: ./fusiondart/socks_socket + git: + url: https://github.com/cypherstack/socks_socket.git + ref: master bip340: ^0.2.0 tezart: ^2.0.5 socks5_proxy: ^1.0.3+dev.3 From 7708d3ab8b236bbca9ad8c90458eaa4a5783c088 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 3 Oct 2023 13:04:32 -0600 Subject: [PATCH 157/379] fix fusion recv --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 97d4b9b6d..625c7956e 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 97d4b9b6d8a79a965324a55b5001dfe1f54b2a1f +Subproject commit 625c7956ece2aa64f6b7c14076bb4b697ecb3228 From d8e4ca03a80d614b0d8fceb77a8793c9f5333059 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 4 Oct 2023 15:23:02 -0600 Subject: [PATCH 158/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 625c7956e..e97a6c25e 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 625c7956ece2aa64f6b7c14076bb4b697ecb3228 +Subproject commit e97a6c25edd1ce0c441bfd181a8032275bff6c40 From 9c352d0e992e8279bdf840011eb2086a40e8743c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 6 Oct 2023 16:33:01 -0600 Subject: [PATCH 159/379] update ref --- fusiondart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fusiondart b/fusiondart index e97a6c25e..d17baa1c2 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit e97a6c25edd1ce0c441bfd181a8032275bff6c40 +Subproject commit d17baa1c2ec60f544783c705496435f055830620 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index c61f276c1..6b7443bb7 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -460,7 +460,7 @@ extension FusionUTXO on UTXO { prevTxid: utf8.encode(txid), prevIndex: vout, pubKey: addr.publicKey, - amount: value, + value: BigInt.from(value), ); } catch (e) { rethrow; @@ -525,7 +525,7 @@ extension FusionTransaction on Transaction { fusion.Transaction fusionTransaction = fusion.Transaction(); // WIP. - fusionTransaction.Inputs = await Future.wait(inputs.map((input) async { + fusionTransaction.inputs = await Future.wait(inputs.map((input) async { // Find input amount. Map<String, dynamic> _tx = await cachedElectrumX.getTransaction( coin: Coin.bitcoincash, @@ -565,11 +565,11 @@ extension FusionTransaction on Transaction { prevTxid: utf8.encode(input.txid), prevIndex: input.vout, pubKey: scriptPubKeyHex.toUint8ListFromHex, - amount: value.raw.toInt(), + value: value.raw, ); }).toList()); - fusionTransaction.Outputs = await Future.wait(outputs.map((output) async { + fusionTransaction.outputs = await Future.wait(outputs.map((output) async { // TODO: maybe only need one of these but IIRC scriptPubKeyAddress is required for bitcoincash transactions? if (output.scriptPubKeyAddress.isEmpty) { throw Exception("isar model output.scriptPubKeyAddress is empty!"); From ebabfc9328d83140aaaa473a4f9dca40fb91eab1 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 9 Oct 2023 10:06:27 -0600 Subject: [PATCH 160/379] use bch net params --- fusiondart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/fusiondart b/fusiondart index d17baa1c2..8de8eaaef 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit d17baa1c2ec60f544783c705496435f055830620 +Subproject commit 8de8eaaefef432026602074b5bdd43c6b8c98582 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 6b7443bb7..2b843c762 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -289,7 +289,11 @@ mixin FusionWalletInterface { final inputs = await mainFusionObject.addCoinsFromWallet(coinList); // Fuse UTXOs. - return await mainFusionObject.fuse(inputsFromWallet: inputs); + return await mainFusionObject.fuse( + inputsFromWallet: inputs, + network: + _coin.isTestNet ? fusion.Utilities.testNet : fusion.Utilities.mainNet, + ); //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); // TODO remove or fix code below. @@ -407,7 +411,7 @@ extension FusionAddress on Address { } return fusion.Address( - addr: value, + address: value, publicKey: publicKey, derivationPath: fusion.DerivationPath( derivationPath?.value ?? "", // TODO fix null derivation path. @@ -493,7 +497,7 @@ extension FusionUTXO on UTXO { return fusion.Output( addr: fusion.Address( - addr: address!, + address: address!, publicKey: addr.publicKey, derivationPath: fusion.DerivationPath( addr.derivationPath!.value, @@ -601,7 +605,7 @@ extension FusionTransaction on Transaction { return fusion.Output( addr: fusion.Address( - addr: output.scriptPubKeyAddress, + address: output.scriptPubKeyAddress, publicKey: outputAddressScriptPubKey, derivationPath: derivationPath, ), From bbf0943003a26ca9e9853254b5c3e61ca4be98b6 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 9 Oct 2023 10:55:06 -0600 Subject: [PATCH 161/379] Don't use Transaction for passing data into fusion --- fusiondart | 2 +- .../mixins/fusion_wallet_interface.dart | 132 ++---------------- 2 files changed, 11 insertions(+), 123 deletions(-) diff --git a/fusiondart b/fusiondart index 8de8eaaef..3c288f9fe 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 8de8eaaefef432026602074b5bdd43c6b8c98582 +Subproject commit 3c288f9fe1efb627361e3ace97919b82d5142118 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 2b843c762..f33485955 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:decimal/decimal.dart'; import 'package:fusiondart/fusiondart.dart' as fusion; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; @@ -10,7 +9,6 @@ import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/models/fusion_progress_ui_state.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/fusion_tor_service.dart'; -import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/extensions/impl/string.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; @@ -89,21 +87,20 @@ mixin FusionWalletInterface { } /// Returns a list of all transactions in the wallet for the given address. - Future<List<fusion.Transaction>> getTransactionsByAddress( - String address) async { - final _txs = await _db.getTransactions(_walletId).findAll(); + Future<List<Map<String, dynamic>>> getTransactionsByAddress( + String address, + ) async { + final txidList = + await _db.getTransactions(_walletId).txidProperty().findAll(); - // Use Future.wait to await all the futures in the set and then convert it to a set. - final resultSet = await Future.wait( - _txs.map( - (tx) => tx.toFusionTransaction( - dbInstance: _db, - cachedElectrumX: _getWalletCachedElectrumX(), - ), + final futures = txidList.map( + (e) => _getWalletCachedElectrumX().getTransaction( + txHash: e, + coin: _coin, ), ); - return resultSet; + return await Future.wait(futures); } /// Returns a list of all UTXOs in the wallet for the given address. @@ -507,112 +504,3 @@ extension FusionUTXO on UTXO { ); } } - -/// An extension of Stack Wallet's Transaction class that adds CashFusion functionality. -extension FusionTransaction on Transaction { - /// Fetch the public key of an address stored in the database. - Future<String?> _getAddressDerivationPathString({ - required String address, - required MainDB dbInstance, - }) async { - final Address? addr = await dbInstance.getAddress(walletId, address); - - return addr?.derivationPath?.value; - } - - // WIP. - Future<fusion.Transaction> toFusionTransaction({ - required CachedElectrumX cachedElectrumX, - required MainDB dbInstance, - }) async { - // Initialize Fusion Dart's Transaction object. - fusion.Transaction fusionTransaction = fusion.Transaction(); - - // WIP. - fusionTransaction.inputs = await Future.wait(inputs.map((input) async { - // Find input amount. - Map<String, dynamic> _tx = await cachedElectrumX.getTransaction( - coin: Coin.bitcoincash, - txHash: input.txid, - verbose: true, - ); - - if (_tx.isEmpty) { - throw Exception("Transaction not found for input: ${input.txid}"); - } - - // Check if output amount is available. - final txVoutAmount = Decimal.tryParse( - _tx["vout"]?[input.vout]?["value"].toString() ?? "", - ); - if (txVoutAmount == null) { - throw Exception( - "Output value at index ${input.vout} in transaction ${input.txid} not found", - ); - } - - final scriptPubKeyHex = - _tx["vout"]?[input.vout]?["scriptPubKey"]?["hex"] as String?; - if (scriptPubKeyHex == null) { - throw Exception( - "scriptPubKey of vout index ${input.vout} in transaction is null", - ); - } - - // Assign vout value to amount. - final value = Amount.fromDecimal( - txVoutAmount, - fractionDigits: Coin.bitcoincash.decimals, - ); - - return fusion.Input( - prevTxid: utf8.encode(input.txid), - prevIndex: input.vout, - pubKey: scriptPubKeyHex.toUint8ListFromHex, - value: value.raw, - ); - }).toList()); - - fusionTransaction.outputs = await Future.wait(outputs.map((output) async { - // TODO: maybe only need one of these but IIRC scriptPubKeyAddress is required for bitcoincash transactions? - if (output.scriptPubKeyAddress.isEmpty) { - throw Exception("isar model output.scriptPubKeyAddress is empty!"); - } - if (output.scriptPubKey == null || output.scriptPubKey!.isEmpty) { - throw Exception("isar model output.scriptPubKey is null or empty!"); - } - - final outputAddress = output.scriptPubKeyAddress; - final outputAddressScriptPubKey = output.scriptPubKey!.toUint8ListFromHex; - - // fetch address derivation path - final derivationPathString = await _getAddressDerivationPathString( - address: outputAddress, - dbInstance: dbInstance, - ); - - final fusion.DerivationPath? derivationPath; - if (derivationPathString == null) { - // TODO: check on this: - // The address is not an address of this wallet and in that case we - // cannot know the derivation path - derivationPath = null; - } else { - derivationPath = fusion.DerivationPath( - derivationPathString, - ); - } - - return fusion.Output( - addr: fusion.Address( - address: output.scriptPubKeyAddress, - publicKey: outputAddressScriptPubKey, - derivationPath: derivationPath, - ), - value: output.value, - ); - }).toList()); - - return fusionTransaction; - } -} From 3e2eb2a7c7275af025cddb72e078fb38a04db0b4 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 9 Oct 2023 11:44:17 -0600 Subject: [PATCH 162/379] ensure only wallet owned p2pkh addresses are passed in --- lib/services/mixins/fusion_wallet_interface.dart | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index f33485955..f9f340f6b 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -80,9 +80,19 @@ mixin FusionWalletInterface { // set _uiState states } - /// Returns a list of all addresses in the wallet. + /// Returns a list of all owned p2pkh addresses in the wallet. Future<List<fusion.Address>> getFusionAddresses() async { - List<Address> _addresses = await _db.getAddresses(_walletId).findAll(); + List<Address> _addresses = await _db + .getAddresses(_walletId) + .filter() + .typeEqualTo(AddressType.p2pkh) + .and() + .group((q) => q + .subTypeEqualTo(AddressSubType.receiving) + .or() + .subTypeEqualTo(AddressSubType.change)) + .findAll(); + return _addresses.map((address) => address.toFusionAddress()).toList(); } From 2ce3bac49751d623dbfec908fabc2609f704e7bf Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 9 Oct 2023 11:44:36 -0600 Subject: [PATCH 163/379] reserved address flag --- .../mixins/fusion_wallet_interface.dart | 110 +----------------- 1 file changed, 4 insertions(+), 106 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index f9f340f6b..97a1e13bc 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -301,105 +301,6 @@ mixin FusionWalletInterface { network: _coin.isTestNet ? fusion.Utilities.testNet : fusion.Utilities.mainNet, ); - //print ("DEBUG FUSION bitcoincash_wallet.dart 1202"); - - // TODO remove or fix code below. - - /* - print("DEBUG: Waiting for any potential incoming data..."); - try { - await Future.delayed(Duration(seconds: 5)); // wait for 5 seconds - } - catch (e) { - print (e); - } - print("DEBUG: Done waiting."); - - bool mydebug1 = false; - if (mydebug1 == true) { - var serverIp = '167.114.119.46'; - var serverPort = 8787; - - List<int> frame = [ - 118, - 91, - 232, - 180, - 228, - 57, - 109, - 207, - 0, - 0, - 0, - 45, - 10, - 43, - 10, - 7, - 97, - 108, - 112, - 104, - 97, - 49, - 51, - 18, - 32, - 111, - 226, - 140, - 10, - 182, - 241, - 179, - 114, - 193, - 166, - 162, - 70, - 174, - 99, - 247, - 79, - 147, - 30, - 131, - 101, - 225, - 90, - 8, - 156, - 104, - 214, - 25, - 0, - 0, - 0, - 0, - 0 - ]; - print("lets try to connect to a socket again"); - var socket = await Socket.connect(serverIp, serverPort); - - print('Connected to the server.'); - socket.add(frame); - print('Sent frame: $frame'); - - socket.listen((data) { - print('Received from server: $data'); - }, onDone: () { - print('Server closed connection.'); - socket.destroy(); - }, onError: (error) { - print('Error: $error'); - socket.destroy(); - }); - } - - // await _checkCurrentChangeAddressesForTransactions(); - // await _checkCurrentReceivingAddressesForTransactions(); - */ } Future<void> refreshFusion() { @@ -417,9 +318,12 @@ extension FusionAddress on Address { // TODO calculate a derivation path if it is null. } + final bool fusionReserved = otherData == kReservedFusionAddress; + return fusion.Address( address: value, publicKey: publicKey, + fusionReserved: fusionReserved, derivationPath: fusion.DerivationPath( derivationPath?.value ?? "", // TODO fix null derivation path. ), @@ -503,13 +407,7 @@ extension FusionUTXO on UTXO { } return fusion.Output( - addr: fusion.Address( - address: address!, - publicKey: addr.publicKey, - derivationPath: fusion.DerivationPath( - addr.derivationPath!.value, - ), - ), + addr: addr.toFusionAddress(), value: value, ); } From 9bda961a3bc5b0b981e545e35c4765febfc01ca3 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 9 Oct 2023 11:44:45 -0600 Subject: [PATCH 164/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 3c288f9fe..c63f44c2e 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 3c288f9fe1efb627361e3ace97919b82d5142118 +Subproject commit c63f44c2e48f6c477c4abc148fd172e8759595d6 From 4142b437c7296e14700fa7f319d08575d4d54c27 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 9 Oct 2023 14:22:45 -0600 Subject: [PATCH 165/379] pass in getTransaction in case its needed --- fusiondart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index c63f44c2e..440ec6a81 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit c63f44c2e48f6c477c4abc148fd172e8759595d6 +Subproject commit 440ec6a8189ccbcf4b9570d83c8fe1cd9910bdbe diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 97a1e13bc..8bf14258b 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -247,6 +247,11 @@ mixin FusionWalletInterface { getSocksProxyAddress: getSocksProxyAddress, getChainHeight: _getChainHeight, updateStatusCallback: updateStatus, + getTransactionJson: (String txid) async => + await _getWalletCachedElectrumX().getTransaction( + coin: _coin, + txHash: txid, + ), ); // Add stack UTXOs. From e82a5a1fb8cbb29e443f85b8dfc08a9b35cd5260 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 9 Oct 2023 15:05:04 -0600 Subject: [PATCH 166/379] use utxo class for passing around utxo data --- fusiondart | 2 +- .../mixins/fusion_wallet_interface.dart | 47 ++++--------------- 2 files changed, 9 insertions(+), 40 deletions(-) diff --git a/fusiondart b/fusiondart index 440ec6a81..56de6e9e8 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 440ec6a8189ccbcf4b9570d83c8fe1cd9910bdbe +Subproject commit 56de6e9e8cd3f1af9959be7dc4c14131058e7430 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 8bf14258b..02d093296 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:convert'; import 'dart:io'; import 'package:fusiondart/fusiondart.dart' as fusion; @@ -114,12 +113,12 @@ mixin FusionWalletInterface { } /// Returns a list of all UTXOs in the wallet for the given address. - Future<List<fusion.Input>> getInputsByAddress(String address) async { + Future<List<fusion.UtxoDTO>> getInputsByAddress(String address) async { final _utxos = await _db.getUTXOsByAddress(_walletId, address).findAll(); - List<Future<fusion.Input>> futureInputs = _utxos + List<Future<fusion.UtxoDTO>> futureInputs = _utxos .map( - (utxo) => utxo.toFusionInput( + (utxo) => utxo.toFusionUtxoDTO( walletId: _walletId, dbInstance: _db, ), @@ -357,7 +356,7 @@ extension FusionUTXO on UTXO { } /// Converts a Stack Wallet UTXO to a FusionDart Input. - Future<fusion.Input> toFusionInput({ + Future<fusion.UtxoDTO> toFusionUtxoDTO({ required String walletId, required MainDB dbInstance, }) async { @@ -376,44 +375,14 @@ extension FusionUTXO on UTXO { throw Exception("Public key for fetched address is empty"); } - return fusion.Input( - prevTxid: utf8.encode(txid), - prevIndex: vout, + return fusion.UtxoDTO( + txid: txid, + vout: vout, pubKey: addr.publicKey, - value: BigInt.from(value), + value: value, ); } catch (e) { rethrow; } } - - /// Converts a Stack Wallet UTXO to a FusionDart Output. - Future<fusion.Output> toFusionOutput({ - required String walletId, - required MainDB dbInstance, - }) async { - if (address == null) { - throw Exception("toFutionOutput Address is null"); - } - - // Search isar for address to get pubKey. - final Address addr = await _getAddressPubkey( - address: address!, - walletId: walletId, - dbInstance: dbInstance, - ); - - if (addr.publicKey.isEmpty) { - throw Exception("Public key for fetched address is empty"); - } - - if (addr.derivationPath == null) { - throw Exception("Derivation path for fetched address is empty"); - } - - return fusion.Output( - addr: addr.toFusionAddress(), - value: value, - ); - } } From d73a90fb5177e3b24a12959d24485715bb659cc1 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 9 Oct 2023 15:42:42 -0600 Subject: [PATCH 167/379] privkey lookup for signing --- fusiondart | 2 +- .../coins/bitcoincash/bitcoincash_wallet.dart | 3 ++ .../mixins/fusion_wallet_interface.dart | 35 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 56de6e9e8..dccd3a5c2 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 56de6e9e8cd3f1af9959be7dc4c14131058e7430 +Subproject commit dccd3a5c23aee021f49553c2da1ab8d59e6da5ea diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 4d8d5a444..ab9aedf71 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -146,6 +146,9 @@ class BitcoinCashWallet extends CoinServiceAPI }, getTxCountForAddress: getTxCount, getChainHeight: () async => chainHeight, + mnemonic: mnemonicString, + mnemonicPassphrase: mnemonicPassphrase, + network: _network, ); initCoinControlInterface( walletId: walletId, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 02d093296..1c66271ac 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -1,6 +1,8 @@ import 'dart:async'; import 'dart:io'; +import 'dart:typed_data'; +import 'package:bitcoindart/bitcoindart.dart' as btcdart; import 'package:fusiondart/fusiondart.dart' as fusion; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; @@ -8,6 +10,7 @@ import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/models/fusion_progress_ui_state.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/fusion_tor_service.dart'; +import 'package:stackwallet/utilities/bip32_utils.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/extensions/impl/string.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; @@ -21,6 +24,9 @@ mixin FusionWalletInterface { late final Coin _coin; late final MainDB _db; late final FusionTorService _torService; + late final Future<String?> _mnemonic; + late final Future<String?> _mnemonicPassphrase; + late final btcdart.NetworkType _network; // setting values on this should notify any listeners (the GUI) FusionProgressUIState? _uiState; @@ -61,6 +67,9 @@ mixin FusionWalletInterface { required String address, }) getTxCountForAddress, required Future<int> Function() getChainHeight, + required Future<String?> mnemonic, + required Future<String?> mnemonicPassphrase, + required btcdart.NetworkType network, }) async { // Set passed in wallet data. _walletId = walletId; @@ -71,6 +80,9 @@ mixin FusionWalletInterface { _getWalletCachedElectrumX = getWalletCachedElectrumX; _getTxCountForAddress = getTxCountForAddress; _getChainHeight = getChainHeight; + _mnemonic = mnemonic; + _mnemonicPassphrase = mnemonicPassphrase; + _network = network; } // callback to update the ui state object @@ -112,6 +124,28 @@ mixin FusionWalletInterface { return await Future.wait(futures); } + Future<Uint8List> getPrivateKeyForPubKey(List<int> pubKey) async { + // can't directly query for equal lists in isar so we need to fetch + // all addresses then search in dart + try { + final derivationPath = (await getFusionAddresses()) + .firstWhere((e) => e.publicKey.toString() == pubKey.toString()) + .derivationPath! + .value; + + final node = await Bip32Utils.getBip32Node( + (await _mnemonic)!, + (await _mnemonicPassphrase)!, + _network, + derivationPath, + ); + + return node.privateKey!; + } catch (_) { + throw Exception("Derivation path for pubkey=$pubKey could not be found"); + } + } + /// Returns a list of all UTXOs in the wallet for the given address. Future<List<fusion.UtxoDTO>> getInputsByAddress(String address) async { final _utxos = await _db.getUTXOsByAddress(_walletId, address).findAll(); @@ -251,6 +285,7 @@ mixin FusionWalletInterface { coin: _coin, txHash: txid, ), + getPrivateKeyForPubKey: getPrivateKeyForPubKey, ); // Add stack UTXOs. From 8af4acbdbe3db3401b418b92a5069a444f268da2 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 9 Oct 2023 15:52:13 -0600 Subject: [PATCH 168/379] no need to use any Input class type here --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index dccd3a5c2..b7235f9e5 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit dccd3a5c23aee021f49553c2da1ab8d59e6da5ea +Subproject commit b7235f9e510221bbf601d91aa837605ff1de4d1d From 06b8ee844dc706abaec023f0fe1381e235a07616 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 9 Oct 2023 16:05:21 -0600 Subject: [PATCH 169/379] add broadcast tx functionality to fusion --- fusiondart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index b7235f9e5..acac15597 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit b7235f9e510221bbf601d91aa837605ff1de4d1d +Subproject commit acac1559737cb9e839c7648c76e803f5ab42c2d5 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 1c66271ac..08292eeb9 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -286,6 +286,9 @@ mixin FusionWalletInterface { txHash: txid, ), getPrivateKeyForPubKey: getPrivateKeyForPubKey, + broadcastTransaction: (String txHex) => _getWalletCachedElectrumX() + .electrumXClient + .broadcastTransaction(rawTx: txHex), ); // Add stack UTXOs. From cdcabdc7d833c6b248a9c357c7d3c91eaedc4693 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 9 Oct 2023 16:49:59 -0600 Subject: [PATCH 170/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index acac15597..ec559787c 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit acac1559737cb9e839c7648c76e803f5ab42c2d5 +Subproject commit ec559787c0a6bbe625185c1fa198296b5615d80d From d6e3bbae83d1a3bebbc7504626da9065a4e4c0e3 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 10 Oct 2023 10:45:27 -0600 Subject: [PATCH 171/379] update fusion ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index ec559787c..62ed0e261 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit ec559787c0a6bbe625185c1fa198296b5615d80d +Subproject commit 62ed0e2615a5318fb1cce498d2699960a53cc599 From e2d5b32b236b48de57afce80df2a5bdccd67d92f Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 11 Oct 2023 18:53:45 -0600 Subject: [PATCH 172/379] temp hack --- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index ab9aedf71..22282e2bf 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2166,8 +2166,11 @@ class BitcoinCashWallet extends CoinServiceAPI // outgoing tx type = isar_models.TransactionType.outgoing; amount = amountSentFromWallet - changeAmount - fee; + + // TODO fix this hack + final diff = outputAddresses.difference(myChangeReceivedOnAddresses); final possible = - outputAddresses.difference(myChangeReceivedOnAddresses).first; + diff.isNotEmpty ? diff.first : myChangeReceivedOnAddresses.first; if (transactionAddress.value != possible) { transactionAddress = isar_models.Address( From a076d7a8f567d997f7fe4dfc2bc67248baf33e49 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 11 Oct 2023 19:03:39 -0600 Subject: [PATCH 173/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 62ed0e261..14e5d7512 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 62ed0e2615a5318fb1cce498d2699960a53cc599 +Subproject commit 14e5d75124cf94f996f4825afaf38304a38a345f From fec0e8e0dcc548b11cd2afb3f09f0994c91b89c9 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 12 Oct 2023 14:08:52 -0500 Subject: [PATCH 174/379] add addresses to utxoDTOs --- lib/services/mixins/fusion_wallet_interface.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 08292eeb9..5908b978e 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -330,6 +330,7 @@ mixin FusionWalletInterface { vout: utxo.vout, value: utxo.value, pubKey: pubKey, + address: utxo.address!, // TODO validate null assertion. ), ); } @@ -418,6 +419,7 @@ extension FusionUTXO on UTXO { vout: vout, pubKey: addr.publicKey, value: value, + address: address!, // TODO validate null assertion. ); } catch (e) { rethrow; From e2534bc4a2a2519662d4bb243daca37cbabef0d4 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 12 Oct 2023 12:03:57 -0600 Subject: [PATCH 175/379] clean up duplicate fetching of utxos --- .../mixins/fusion_wallet_interface.dart | 124 +++--------------- 1 file changed, 20 insertions(+), 104 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 5908b978e..d59dde39a 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -12,7 +12,6 @@ import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/fusion_tor_service.dart'; import 'package:stackwallet/utilities/bip32_utils.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; -import 'package:stackwallet/utilities/extensions/impl/string.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; const String kReservedFusionAddress = "reserved_fusion_address"; @@ -146,22 +145,6 @@ mixin FusionWalletInterface { } } - /// Returns a list of all UTXOs in the wallet for the given address. - Future<List<fusion.UtxoDTO>> getInputsByAddress(String address) async { - final _utxos = await _db.getUTXOsByAddress(_walletId, address).findAll(); - - List<Future<fusion.UtxoDTO>> futureInputs = _utxos - .map( - (utxo) => utxo.toFusionUtxoDTO( - walletId: _walletId, - dbInstance: _db, - ), - ) - .toList(); - - return await Future.wait(futureInputs); - } - /// Creates a new reserved change address. Future<fusion.Address> createNewReservedChangeAddress() async { // _getNextUnusedChangeAddress() grabs the latest unused change address @@ -275,7 +258,6 @@ mixin FusionWalletInterface { await mainFusionObject.initFusion( getAddresses: getFusionAddresses, getTransactionsByAddress: getTransactionsByAddress, - getInputsByAddress: getInputsByAddress, getUnusedReservedChangeAddresses: getUnusedReservedChangeAddresses, getSocksProxyAddress: getSocksProxyAddress, getChainHeight: _getChainHeight, @@ -291,56 +273,43 @@ mixin FusionWalletInterface { .broadcastTransaction(rawTx: txHex), ); - // Add stack UTXOs. - final List<UTXO> walletUtxos = await _db.getUTXOs(_walletId).findAll(); + // Add unfrozen stack UTXOs. + final List<UTXO> walletUtxos = await _db + .getUTXOs(_walletId) + .filter() + .isBlockedEqualTo(false) + .and() + .addressIsNotNull() + .findAll(); final List<fusion.UtxoDTO> coinList = []; // Loop through UTXOs, checking and adding valid ones. for (final utxo in walletUtxos) { // Check if address is available. if (utxo.address == null) { - // TODO we could continue here (and below during scriptPubKey validation) instead of throwing. + // A utxo object should always have a non null address + // as per the db query above throw Exception("UTXO ${utxo.txid}:${utxo.vout} address is null"); } // Find public key. - Map<String, dynamic> tx = - await _getWalletCachedElectrumX().getTransaction( - coin: _coin, - txHash: utxo.txid, - verbose: true, + final addr = await _db.getAddress(_walletId, utxo.address!); + + final dto = fusion.UtxoDTO( + txid: utxo.txid, + vout: utxo.vout, + value: utxo.value, + address: utxo.address!, + pubKey: addr!.publicKey, ); - // Check if scriptPubKey is available. - final scriptPubKeyHex = - tx["vout"]?[utxo.vout]?["scriptPubKey"]?["hex"] as String?; - if (scriptPubKeyHex == null) { - throw Exception( - "hex in scriptPubKey of vout index ${utxo.vout} in transaction is null", - ); - } - - // Assign scriptPubKey to pubKey. TODO verify this is correct. - List<int> pubKey = scriptPubKeyHex.toUint8ListFromHex; - // Add UTXO to coinList. - coinList.add( - fusion.UtxoDTO( - txid: utxo.txid, - vout: utxo.vout, - value: utxo.value, - pubKey: pubKey, - address: utxo.address!, // TODO validate null assertion. - ), - ); + coinList.add(dto); } - // Add Stack UTXOs. - final inputs = await mainFusionObject.addCoinsFromWallet(coinList); - // Fuse UTXOs. return await mainFusionObject.fuse( - inputsFromWallet: inputs, + inputsFromWallet: coinList, network: _coin.isTestNet ? fusion.Utilities.testNet : fusion.Utilities.mainNet, ); @@ -373,56 +342,3 @@ extension FusionAddress on Address { ); } } - -/// An extension of Stack Wallet's UTXO class that adds CashFusion functionality. -/// -/// This class is used to convert Stack Wallet's UTXO class to FusionDart's -/// Input and Output classes. -extension FusionUTXO on UTXO { - /// Fetch the public key of an address stored in the database. - Future<Address> _getAddressPubkey({ - required String address, - required String walletId, - required MainDB dbInstance, - }) async { - final Address? addr = await dbInstance.getAddress(walletId, address); - - if (addr == null) { - throw Exception("Address not found"); - } - - return addr; - } - - /// Converts a Stack Wallet UTXO to a FusionDart Input. - Future<fusion.UtxoDTO> toFusionUtxoDTO({ - required String walletId, - required MainDB dbInstance, - }) async { - if (address == null) { - throw Exception("toFusionInput Address is null"); - } - - try { - final Address addr = await _getAddressPubkey( - address: address!, - walletId: walletId, - dbInstance: dbInstance, - ); - - if (addr.publicKey.isEmpty) { - throw Exception("Public key for fetched address is empty"); - } - - return fusion.UtxoDTO( - txid: txid, - vout: vout, - pubKey: addr.publicKey, - value: value, - address: address!, // TODO validate null assertion. - ); - } catch (e) { - rethrow; - } - } -} From 4db1d0b9c2dbf6dd83a33d4327d94e0a903c2741 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 12 Oct 2023 13:12:06 -0600 Subject: [PATCH 176/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 14e5d7512..c7e9521a0 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 14e5d75124cf94f996f4825afaf38304a38a345f +Subproject commit c7e9521a03aa8e6e0b11134027d6ea301acbc273 From 7c1c1cba7dcdb513e15e81494e697a54a9aeeab7 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 12 Oct 2023 14:32:01 -0500 Subject: [PATCH 177/379] update ref and throw on null addr (addr!.publicKey throws) --- fusiondart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/fusiondart b/fusiondart index c7e9521a0..2908a9599 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit c7e9521a03aa8e6e0b11134027d6ea301acbc273 +Subproject commit 2908a9599c0f15e04e14d90e3303bb84e83de121 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index d59dde39a..ffd5503ab 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -287,14 +287,18 @@ mixin FusionWalletInterface { for (final utxo in walletUtxos) { // Check if address is available. if (utxo.address == null) { - // A utxo object should always have a non null address - // as per the db query above + // A utxo object should always have a non null address. throw Exception("UTXO ${utxo.txid}:${utxo.vout} address is null"); } // Find public key. final addr = await _db.getAddress(_walletId, utxo.address!); + if (addr == null) { + // A utxo object should always have a non null address. + throw Exception("UTXO ${utxo.txid}:${utxo.vout} address not found"); + } + final dto = fusion.UtxoDTO( txid: utxo.txid, vout: utxo.vout, From c6010c00aea3fd1cf91fd1c52c3aa5de2cf02682 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 12 Oct 2023 14:35:50 -0500 Subject: [PATCH 178/379] quick hack patch, continue if we can't find the address (for public key) --- lib/services/mixins/fusion_wallet_interface.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index ffd5503ab..5834b38fc 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -296,6 +296,10 @@ mixin FusionWalletInterface { if (addr == null) { // A utxo object should always have a non null address. + fusion.Utilities.debugPrint( + "UTXO ${utxo.txid}:${utxo.vout} address not found. TODO calculate it instead of continuing.", + ); + continue; throw Exception("UTXO ${utxo.txid}:${utxo.vout} address not found"); } From 761d914bca84bd217026e94877a4312cbb7e251b Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 12 Oct 2023 14:00:58 -0600 Subject: [PATCH 179/379] update ref and check for lolcashaddr formatting --- fusiondart | 2 +- .../mixins/fusion_wallet_interface.dart | 30 +++++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/fusiondart b/fusiondart index 2908a9599..418d07c87 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 2908a9599c0f15e04e14d90e3303bb84e83de121 +Subproject commit 418d07c870c36ddf89398f58c3e57893e3efee79 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 5834b38fc..97ba4008f 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; +import 'package:bitbox/bitbox.dart' as bitbox; import 'package:bitcoindart/bitcoindart.dart' as btcdart; import 'package:fusiondart/fusiondart.dart' as fusion; import 'package:isar/isar.dart'; @@ -12,6 +13,7 @@ import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/fusion_tor_service.dart'; import 'package:stackwallet/utilities/bip32_utils.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; const String kReservedFusionAddress = "reserved_fusion_address"; @@ -285,22 +287,32 @@ mixin FusionWalletInterface { // Loop through UTXOs, checking and adding valid ones. for (final utxo in walletUtxos) { - // Check if address is available. - if (utxo.address == null) { - // A utxo object should always have a non null address. - throw Exception("UTXO ${utxo.txid}:${utxo.vout} address is null"); + final String addressString = utxo.address!; + final List<String> possibleAddresses = [addressString]; + + if (bitbox.Address.detectFormat(addressString) == + bitbox.Address.formatCashAddr) { + possibleAddresses.add(bitbox.Address.toLegacyAddress(addressString)); + } else { + possibleAddresses.add(bitbox.Address.toCashAddress(addressString)); } // Find public key. - final addr = await _db.getAddress(_walletId, utxo.address!); + final addr = await _db + .getAddresses(_walletId) + .filter() + .anyOf<String, QueryBuilder<Address, Address, QAfterFilterCondition>>( + possibleAddresses, (q, e) => q.valueEqualTo(e)) + .findFirst(); if (addr == null) { // A utxo object should always have a non null address. - fusion.Utilities.debugPrint( - "UTXO ${utxo.txid}:${utxo.vout} address not found. TODO calculate it instead of continuing.", + // If non found then just ignore the UTXO (aka don't fuse it) + Logging.instance.log( + "Missing address=\"$addressString\" while selecting UTXOs for Fusion", + level: LogLevel.Warning, ); continue; - throw Exception("UTXO ${utxo.txid}:${utxo.vout} address not found"); } final dto = fusion.UtxoDTO( @@ -308,7 +320,7 @@ mixin FusionWalletInterface { vout: utxo.vout, value: utxo.value, address: utxo.address!, - pubKey: addr!.publicKey, + pubKey: addr.publicKey, ); // Add UTXO to coinList. From 92305f558a7281b05e9033cc5664d3dbd8836ec5 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 12 Oct 2023 17:05:17 -0500 Subject: [PATCH 180/379] this isn't the right way to do this --- .../mixins/fusion_wallet_interface.dart | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 97ba4008f..58f8698d9 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -10,6 +10,7 @@ import 'package:stackwallet/db/isar/main_db.dart'; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/models/fusion_progress_ui_state.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; import 'package:stackwallet/services/fusion_tor_service.dart'; import 'package:stackwallet/utilities/bip32_utils.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -56,8 +57,6 @@ mixin FusionWalletInterface { /// Initializes the FusionWalletInterface mixin. /// /// This function must be called before any other functions in this mixin. - /// - /// Returns a `Future<void>` that resolves when Tor has been started. Future<void> initFusionInterface({ required String walletId, required Coin coin, @@ -88,8 +87,29 @@ mixin FusionWalletInterface { // callback to update the ui state object void updateStatus(fusion.FusionStatus fusionStatus) { - // TODO: this - // set _uiState states + switch (fusionStatus) { + case fusion.FusionStatus.setup: + _uiState?.connecting = CashFusionStatus.waiting; + break; + case fusion.FusionStatus.waiting: + _uiState?.connecting = CashFusionStatus.waiting; + break; + case fusion.FusionStatus.connecting: + _uiState?.connecting = CashFusionStatus.waiting; + break; + case fusion.FusionStatus.running: + _uiState?.connecting = CashFusionStatus.fusing; + break; + case fusion.FusionStatus.complete: + _uiState?.connecting = CashFusionStatus.success; + break; + case fusion.FusionStatus.failed: + _uiState?.connecting = CashFusionStatus.failed; + break; + case fusion.FusionStatus.exception: + _uiState?.connecting = CashFusionStatus.failed; + break; + } } /// Returns a list of all owned p2pkh addresses in the wallet. @@ -249,9 +269,6 @@ mixin FusionWalletInterface { /// Fuse the wallet's UTXOs. /// /// This function is called when the user taps the "Fuse" button in the UI. - /// - /// Returns: - /// A `Future<void>` that resolves when the fusion operation is finished. Future<void> fuse() async { // Initial attempt for CashFusion integration goes here. final mainFusionObject = fusion.Fusion(fusion.FusionParams()); From f631678de7c771cdb5c3ccf71cac9b1cca6c0502 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 12 Oct 2023 17:05:17 -0600 Subject: [PATCH 181/379] change query for address slightly. Might revert --- lib/services/mixins/fusion_wallet_interface.dart | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 97ba4008f..1c04b4f3d 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -297,20 +297,28 @@ mixin FusionWalletInterface { possibleAddresses.add(bitbox.Address.toCashAddress(addressString)); } - // Find public key. + // Fetch address to get pubkey final addr = await _db .getAddresses(_walletId) .filter() .anyOf<String, QueryBuilder<Address, Address, QAfterFilterCondition>>( possibleAddresses, (q, e) => q.valueEqualTo(e)) + .and() + .group((q) => q + .subTypeEqualTo(AddressSubType.change) + .or() + .subTypeEqualTo(AddressSubType.receiving)) + .and() + .typeEqualTo(AddressType.p2pkh) .findFirst(); + // depending on the address type in the query above this can be null if (addr == null) { // A utxo object should always have a non null address. // If non found then just ignore the UTXO (aka don't fuse it) Logging.instance.log( - "Missing address=\"$addressString\" while selecting UTXOs for Fusion", - level: LogLevel.Warning, + "Ignoring utxo=$utxo for address=\"$addressString\" while selecting UTXOs for Fusion", + level: LogLevel.Info, ); continue; } From 1aadaa32d172bbe67784aaf8449eab902165a88e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 12 Oct 2023 17:05:26 -0600 Subject: [PATCH 182/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 418d07c87..c5605ee88 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 418d07c870c36ddf89398f58c3e57893e3efee79 +Subproject commit c5605ee88ec13c83aac1bcd38e4ccbf3bb0339f0 From 84529f37db74676a741b8a0a60e098108c27bf31 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 13 Oct 2023 08:59:06 -0600 Subject: [PATCH 183/379] update fusiondart ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index c5605ee88..1f10b8056 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit c5605ee88ec13c83aac1bcd38e4ccbf3bb0339f0 +Subproject commit 1f10b8056db61fdd19b2d09db4f599dccffb0c11 From 706b98834ba8647e9b4961211f1f0074955323d9 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 10:52:28 -0500 Subject: [PATCH 184/379] add comment --- lib/services/mixins/fusion_wallet_interface.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 1c04b4f3d..fb4eefac7 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -155,6 +155,7 @@ mixin FusionWalletInterface { final address = (await _getNextUnusedChangeAddress()) .copyWith(otherData: kReservedFusionAddress); + // Make sure the address is in the database as reserved for Fusion. final _address = await _db.getAddress(_walletId, address.value); if (_address != null) { await _db.updateAddress(_address, address); From 18dcdbddf17a86880428c1215c845be01137f5d9 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 13 Oct 2023 11:17:11 -0600 Subject: [PATCH 185/379] clean up api, remove unused function, and unneeded code --- .../mixins/fusion_wallet_interface.dart | 96 ++++++++----------- 1 file changed, 40 insertions(+), 56 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index c892e5b24..ec5888036 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -86,7 +86,7 @@ mixin FusionWalletInterface { } // callback to update the ui state object - void updateStatus(fusion.FusionStatus fusionStatus) { + void _updateStatus(fusion.FusionStatus fusionStatus) { switch (fusionStatus) { case fusion.FusionStatus.setup: _uiState?.connecting = CashFusionStatus.waiting; @@ -112,24 +112,8 @@ mixin FusionWalletInterface { } } - /// Returns a list of all owned p2pkh addresses in the wallet. - Future<List<fusion.Address>> getFusionAddresses() async { - List<Address> _addresses = await _db - .getAddresses(_walletId) - .filter() - .typeEqualTo(AddressType.p2pkh) - .and() - .group((q) => q - .subTypeEqualTo(AddressSubType.receiving) - .or() - .subTypeEqualTo(AddressSubType.change)) - .findAll(); - - return _addresses.map((address) => address.toFusionAddress()).toList(); - } - /// Returns a list of all transactions in the wallet for the given address. - Future<List<Map<String, dynamic>>> getTransactionsByAddress( + Future<List<Map<String, dynamic>>> _getTransactionsByAddress( String address, ) async { final txidList = @@ -145,11 +129,22 @@ mixin FusionWalletInterface { return await Future.wait(futures); } - Future<Uint8List> getPrivateKeyForPubKey(List<int> pubKey) async { + Future<Uint8List> _getPrivateKeyForPubKey(List<int> pubKey) async { // can't directly query for equal lists in isar so we need to fetch // all addresses then search in dart try { - final derivationPath = (await getFusionAddresses()) + final derivationPath = (await _db + .getAddresses(_walletId) + .filter() + .typeEqualTo(AddressType.p2pkh) + .and() + .derivationPathIsNotNull() + .and() + .group((q) => q + .subTypeEqualTo(AddressSubType.receiving) + .or() + .subTypeEqualTo(AddressSubType.change)) + .findAll()) .firstWhere((e) => e.publicKey.toString() == pubKey.toString()) .derivationPath! .value; @@ -168,7 +163,7 @@ mixin FusionWalletInterface { } /// Creates a new reserved change address. - Future<fusion.Address> createNewReservedChangeAddress() async { + Future<Address> _createNewReservedChangeAddress() async { // _getNextUnusedChangeAddress() grabs the latest unused change address // from the wallet. // CopyWith to mark it as a fusion reserved change address @@ -183,13 +178,13 @@ mixin FusionWalletInterface { await _db.putAddress(address); } - return address.toFusionAddress(); + return address; } /// Returns a list of unused reserved change addresses. /// /// If there are not enough unused reserved change addresses, new ones are created. - Future<List<fusion.Address>> getUnusedReservedChangeAddresses( + Future<List<fusion.Address>> _getUnusedReservedChangeAddresses( int numberOfAddresses, ) async { // Fetch all reserved change addresses. @@ -202,7 +197,7 @@ mixin FusionWalletInterface { .findAll(); // Initialize a list of unused reserved change addresses. - final List<fusion.Address> unusedAddresses = []; + final List<Address> unusedAddresses = []; // check addresses for tx history for (final address in reservedChangeAddresses) { @@ -217,24 +212,35 @@ mixin FusionWalletInterface { // _getTxCountForAddress can throw! final count = await _getTxCountForAddress(address: address.value); if (count == 0) { - unusedAddresses.add(address.toFusionAddress()); + unusedAddresses.add(address); } } } // If there are not enough unused reserved change addresses, create new ones. while (unusedAddresses.length < numberOfAddresses) { - unusedAddresses.add(await createNewReservedChangeAddress()); + unusedAddresses.add(await _createNewReservedChangeAddress()); } // Return the list of unused reserved change addresses. - return unusedAddresses.sublist(0, numberOfAddresses); + return unusedAddresses.sublist(0, numberOfAddresses).map((e) { + final bool fusionReserved = e.otherData == kReservedFusionAddress; + + return fusion.Address( + address: e.value, + publicKey: e.publicKey, + fusionReserved: fusionReserved, + derivationPath: fusion.DerivationPath( + e.derivationPath!.value, + ), + ); + }).toList(); } int _torStartCount = 0; /// Returns the current Tor proxy address. - Future<({InternetAddress host, int port})> getSocksProxyAddress() async { + Future<({InternetAddress host, int port})> _getSocksProxyAddress() async { if (_torStartCount > 5) { // something is quite broken so stop trying to recursively fetch // start up tor and fetch proxy info @@ -261,7 +267,7 @@ mixin FusionWalletInterface { await _torService.start(); // try again to fetch proxy info - return await getSocksProxyAddress(); + return await _getSocksProxyAddress(); } } @@ -276,18 +282,17 @@ mixin FusionWalletInterface { // Pass wallet functions to the Fusion object await mainFusionObject.initFusion( - getAddresses: getFusionAddresses, - getTransactionsByAddress: getTransactionsByAddress, - getUnusedReservedChangeAddresses: getUnusedReservedChangeAddresses, - getSocksProxyAddress: getSocksProxyAddress, + getTransactionsByAddress: _getTransactionsByAddress, + getUnusedReservedChangeAddresses: _getUnusedReservedChangeAddresses, + getSocksProxyAddress: _getSocksProxyAddress, getChainHeight: _getChainHeight, - updateStatusCallback: updateStatus, + updateStatusCallback: _updateStatus, getTransactionJson: (String txid) async => await _getWalletCachedElectrumX().getTransaction( coin: _coin, txHash: txid, ), - getPrivateKeyForPubKey: getPrivateKeyForPubKey, + getPrivateKeyForPubKey: _getPrivateKeyForPubKey, broadcastTransaction: (String txHex) => _getWalletCachedElectrumX() .electrumXClient .broadcastTransaction(rawTx: txHex), @@ -367,24 +372,3 @@ mixin FusionWalletInterface { "TODO refreshFusion eg look up number of fusion participants connected/coordinating"); } } - -/// An extension of Stack Wallet's Address class that adds CashFusion functionality. -extension FusionAddress on Address { - fusion.Address toFusionAddress() { - if (derivationPath == null) { - // throw Exception("Fusion Addresses require a derivation path"); - // TODO calculate a derivation path if it is null. - } - - final bool fusionReserved = otherData == kReservedFusionAddress; - - return fusion.Address( - address: value, - publicKey: publicKey, - fusionReserved: fusionReserved, - derivationPath: fusion.DerivationPath( - derivationPath?.value ?? "", // TODO fix null derivation path. - ), - ); - } -} From 41ced4ecd7ad1ec9f97b4987ff0525571d58bfc1 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 13 Oct 2023 11:17:41 -0600 Subject: [PATCH 186/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 1f10b8056..4f1e5f2e5 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 1f10b8056db61fdd19b2d09db4f599dccffb0c11 +Subproject commit 4f1e5f2e50972fe12ab501c002cf3c9ce685b4b5 From f4c450f6cec4e2ad9d0bc1c63d4b5f7c4d5db2ab Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 12:41:01 -0500 Subject: [PATCH 187/379] WIP status updates --- lib/services/mixins/fusion_wallet_interface.dart | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index ec5888036..91740ea78 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -98,16 +98,19 @@ mixin FusionWalletInterface { _uiState?.connecting = CashFusionStatus.waiting; break; case fusion.FusionStatus.running: - _uiState?.connecting = CashFusionStatus.fusing; + _uiState?.fusing = CashFusionStatus.fusing; break; case fusion.FusionStatus.complete: - _uiState?.connecting = CashFusionStatus.success; + _uiState?.fusing = CashFusionStatus.success; + _uiState?.complete = CashFusionStatus.success; break; case fusion.FusionStatus.failed: - _uiState?.connecting = CashFusionStatus.failed; + _uiState?.fusing = CashFusionStatus.failed; + _uiState?.complete = CashFusionStatus.failed; break; case fusion.FusionStatus.exception: - _uiState?.connecting = CashFusionStatus.failed; + _uiState?.fusing = CashFusionStatus.failed; + _uiState?.complete = CashFusionStatus.failed; break; } } From 75a84c740f8601a232fac7cd68796393d713fa98 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 12:42:16 -0500 Subject: [PATCH 188/379] ui stepper --- .../cashfusion/desktop_cashfusion_view.dart | 1 + .../mixins/fusion_wallet_interface.dart | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index eb22f670d..a8ac6fc7b 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -648,6 +648,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { } unawaited(fusionWallet.fuse()); + unawaited(fusionWallet.stepThruUiStates()); await showDialog<void>( context: context, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 91740ea78..9d0d91faa 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -374,4 +374,29 @@ mixin FusionWalletInterface { throw UnimplementedError( "TODO refreshFusion eg look up number of fusion participants connected/coordinating"); } + + /// Testing ground for iterating thru the UI state. + /// + /// TODO remove this, just for development. + Future<void> stepThruUiStates() async { + // Define the list of states. + final List<fusion.FusionStatus> states = [ + fusion.FusionStatus.setup, + fusion.FusionStatus.waiting, + fusion.FusionStatus.connecting, + fusion.FusionStatus.running, + fusion.FusionStatus.complete, + fusion.FusionStatus.failed, + fusion.FusionStatus.exception, + ]; + + // Iterate through the list of states, waiting one second between each. + for (final state in states) { + // Set the connecting status to the current state. + _updateStatus(state); + + // Wait one second. + await Future.delayed(const Duration(seconds: 1)); + } + } } From 3266b623b6edd4dd436d7bd4c3dcf2b83bb78757 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 12:50:21 -0500 Subject: [PATCH 189/379] WIP ui state updates --- lib/services/mixins/fusion_wallet_interface.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 9d0d91faa..468a75809 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -89,15 +89,16 @@ mixin FusionWalletInterface { void _updateStatus(fusion.FusionStatus fusionStatus) { switch (fusionStatus) { case fusion.FusionStatus.setup: - _uiState?.connecting = CashFusionStatus.waiting; + _uiState?.outputs = CashFusionStatus.waiting; break; case fusion.FusionStatus.waiting: - _uiState?.connecting = CashFusionStatus.waiting; + _uiState?.outputs = CashFusionStatus.success; break; case fusion.FusionStatus.connecting: _uiState?.connecting = CashFusionStatus.waiting; break; case fusion.FusionStatus.running: + _uiState?.connecting = CashFusionStatus.success; _uiState?.fusing = CashFusionStatus.fusing; break; case fusion.FusionStatus.complete: From 20dde81da1b4e68944c5fce9c1719bf9d9951180 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 13:00:35 -0500 Subject: [PATCH 190/379] add ui state reset helper TODO remove, just for development --- lib/services/mixins/fusion_wallet_interface.dart | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 468a75809..295fbaf8f 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -113,6 +113,14 @@ mixin FusionWalletInterface { _uiState?.fusing = CashFusionStatus.failed; _uiState?.complete = CashFusionStatus.failed; break; + case fusion.FusionStatus.reset: + _uiState?.outputs = CashFusionStatus.waiting; + _uiState?.peers = CashFusionStatus.waiting; + _uiState?.connecting = CashFusionStatus.waiting; + _uiState?.fusing = CashFusionStatus.waiting; + _uiState?.complete = CashFusionStatus.waiting; + _uiState?.fusionState = CashFusionStatus.waiting; + break; } } @@ -389,6 +397,7 @@ mixin FusionWalletInterface { fusion.FusionStatus.complete, fusion.FusionStatus.failed, fusion.FusionStatus.exception, + fusion.FusionStatus.reset, ]; // Iterate through the list of states, waiting one second between each. From 6877c00a498fb552a56773aa60ba4ab95db5a605 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 13:05:53 -0500 Subject: [PATCH 191/379] refactor fusing to running and update fusiondart ref --- fusiondart | 2 +- .../cashfusion/sub_widgets/fusion_dialog.dart | 4 ++-- lib/services/mixins/fusion_wallet_interface.dart | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/fusiondart b/fusiondart index 4f1e5f2e5..64a78efc4 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 4f1e5f2e50972fe12ab501c002cf3c9ce685b4b5 +Subproject commit 64a78efc4a2f874f16975e2aa7fca564444e4aae diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 88394410b..ac3a115d8 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -11,7 +11,7 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; -enum CashFusionStatus { waiting, fusing, success, failed } +enum CashFusionStatus { waiting, running, success, failed } class FusionDialog extends StatelessWidget { const FusionDialog({ @@ -31,7 +31,7 @@ class FusionDialog extends StatelessWidget { color: Theme.of(context).extension<StackColors>()!.buttonBackSecondary, ); - case CashFusionStatus.fusing: + case CashFusionStatus.running: return SvgPicture.asset( Assets.svg.loader, color: Theme.of(context).extension<StackColors>()!.accentColorGreen, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 295fbaf8f..49598471e 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -89,9 +89,10 @@ mixin FusionWalletInterface { void _updateStatus(fusion.FusionStatus fusionStatus) { switch (fusionStatus) { case fusion.FusionStatus.setup: - _uiState?.outputs = CashFusionStatus.waiting; + _uiState?.connecting = CashFusionStatus.running; break; case fusion.FusionStatus.waiting: + _uiState?.connecting = CashFusionStatus.success; _uiState?.outputs = CashFusionStatus.success; break; case fusion.FusionStatus.connecting: @@ -99,7 +100,7 @@ mixin FusionWalletInterface { break; case fusion.FusionStatus.running: _uiState?.connecting = CashFusionStatus.success; - _uiState?.fusing = CashFusionStatus.fusing; + _uiState?.fusing = CashFusionStatus.running; break; case fusion.FusionStatus.complete: _uiState?.fusing = CashFusionStatus.success; From ac6952f5ebc4ab39a32eda4d1164ddad0b4c83e8 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 13:14:16 -0500 Subject: [PATCH 192/379] update ui status updates with example stepper --- .../cashfusion/desktop_cashfusion_view.dart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index a8ac6fc7b..93c6dfab6 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -648,7 +648,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { } unawaited(fusionWallet.fuse()); - unawaited(fusionWallet.stepThruUiStates()); + // unawaited(fusionWallet.stepThruUiStates()); await showDialog<void>( context: context, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 49598471e..fea80bf25 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -88,18 +88,19 @@ mixin FusionWalletInterface { // callback to update the ui state object void _updateStatus(fusion.FusionStatus fusionStatus) { switch (fusionStatus) { - case fusion.FusionStatus.setup: + case fusion.FusionStatus.connecting: _uiState?.connecting = CashFusionStatus.running; break; - case fusion.FusionStatus.waiting: + case fusion.FusionStatus.setup: _uiState?.connecting = CashFusionStatus.success; - _uiState?.outputs = CashFusionStatus.success; + _uiState?.outputs = CashFusionStatus.running; break; - case fusion.FusionStatus.connecting: - _uiState?.connecting = CashFusionStatus.waiting; + case fusion.FusionStatus.waiting: + _uiState?.outputs = CashFusionStatus.success; + _uiState?.peers = CashFusionStatus.running; break; case fusion.FusionStatus.running: - _uiState?.connecting = CashFusionStatus.success; + _uiState?.peers = CashFusionStatus.success; _uiState?.fusing = CashFusionStatus.running; break; case fusion.FusionStatus.complete: @@ -391,9 +392,9 @@ mixin FusionWalletInterface { Future<void> stepThruUiStates() async { // Define the list of states. final List<fusion.FusionStatus> states = [ + fusion.FusionStatus.connecting, fusion.FusionStatus.setup, fusion.FusionStatus.waiting, - fusion.FusionStatus.connecting, fusion.FusionStatus.running, fusion.FusionStatus.complete, fusion.FusionStatus.failed, From c61f3ca94b59284d47a2093f736b91266af4f399 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 13 Oct 2023 12:17:59 -0600 Subject: [PATCH 193/379] handle change addresses differently --- .../coins/bitcoincash/bitcoincash_wallet.dart | 169 +++++++++--------- .../mixins/fusion_wallet_interface.dart | 96 +++++----- 2 files changed, 122 insertions(+), 143 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 22282e2bf..5a2abfe9b 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -140,10 +140,7 @@ class BitcoinCashWallet extends CoinServiceAPI coin: coin, db: db, getWalletCachedElectrumX: () => cachedElectrumXClient, - getNextUnusedChangeAddress: () async { - await checkCurrentChangeAddressesForTransactions(); - return await _currentChangeAddress; - }, + getNextUnusedChangeAddress: _getUnusedChangeAddresses, getTxCountForAddress: getTxCount, getChainHeight: () async => chainHeight, mnemonic: mnemonicString, @@ -208,16 +205,80 @@ class BitcoinCashWallet extends CoinServiceAPI .findFirst()) ?? await _generateAddressForChain(0, 0, DerivePathTypeExt.primaryFor(coin)); - Future<isar_models.Address> get _currentChangeAddress async => - (await db - .getAddresses(walletId) - .filter() - .typeEqualTo(isar_models.AddressType.p2pkh) - .subTypeEqualTo(isar_models.AddressSubType.change) - .derivationPath((q) => q.not().valueStartsWith("m/44'/0'")) - .sortByDerivationIndexDesc() - .findFirst()) ?? - await _generateAddressForChain(1, 0, DerivePathTypeExt.primaryFor(coin)); + Future<List<isar_models.Address>> _getUnusedChangeAddresses({ + int numberOfAddresses = 1, + }) async { + if (numberOfAddresses < 1) { + throw ArgumentError.value( + numberOfAddresses, + "numberOfAddresses", + "Must not be less than 1", + ); + } + + final changeAddresses = await db + .getAddresses(walletId) + .filter() + .typeEqualTo(isar_models.AddressType.p2pkh) + .subTypeEqualTo(isar_models.AddressSubType.change) + .derivationPath((q) => q.not().valueStartsWith("m/44'/0'")) + .sortByDerivationIndex() + .findAll(); + + final List<isar_models.Address> unused = []; + + for (final addr in changeAddresses) { + if (await _isUnused(addr.value)) { + unused.add(addr); + if (unused.length == numberOfAddresses) { + return unused; + } + } + } + + // if not returned by now, we need to create more addresses + int countMissing = numberOfAddresses - unused.length; + + int nextIndex = + changeAddresses.isEmpty ? 0 : changeAddresses.last.derivationIndex + 1; + + while (countMissing > 0) { + // create a new address + final address = await _generateAddressForChain( + 1, + nextIndex, + DerivePathTypeExt.primaryFor(coin), + ); + nextIndex++; + await db.putAddress(address); + + // check if it has been used before adding + if (await _isUnused(address.value)) { + unused.add(address); + countMissing--; + } + } + + return unused; + } + + Future<bool> _isUnused(String address) async { + final txCountInDB = await db + .getTransactions(_walletId) + .filter() + .address((q) => q.valueEqualTo(address)) + .count(); + if (txCountInDB == 0) { + // double check via electrumx + // _getTxCountForAddress can throw! + final count = await getTxCount(address: address); + if (count == 0) { + return true; + } + } + + return false; + } @override Future<void> exit() async { @@ -888,7 +949,6 @@ class BitcoinCashWallet extends CoinServiceAPI if (currentHeight != storedHeight) { GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.2, walletId)); - await _checkChangeAddressForTransactions(); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.3, walletId)); await _checkCurrentReceivingAddressesForTransactions(); @@ -1810,52 +1870,6 @@ class BitcoinCashWallet extends CoinServiceAPI } } - Future<void> _checkChangeAddressForTransactions() async { - try { - final currentChange = await _currentChangeAddress; - final int txCount = await getTxCount(address: currentChange.value); - Logging.instance.log( - 'Number of txs for current change address $currentChange: $txCount', - level: LogLevel.Info); - - if (txCount >= 1 || currentChange.derivationIndex < 0) { - // First increment the change index - final newChangeIndex = currentChange.derivationIndex + 1; - - // Use new index to derive a new change address - final newChangeAddress = await _generateAddressForChain( - 1, newChangeIndex, DerivePathTypeExt.primaryFor(coin)); - - final existing = await db - .getAddresses(walletId) - .filter() - .valueEqualTo(newChangeAddress.value) - .findFirst(); - if (existing == null) { - // Add that new change address - await db.putAddress(newChangeAddress); - } else { - if (existing.otherData != kReservedFusionAddress) { - // we need to update the address - await db.updateAddress(existing, newChangeAddress); - } - } - // keep checking until address with no tx history is set as current - await _checkChangeAddressForTransactions(); - } - } on SocketException catch (se, s) { - Logging.instance.log( - "SocketException caught in _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $se\n$s", - level: LogLevel.Error); - return; - } catch (e, s) { - Logging.instance.log( - "Exception rethrown from _checkReceivingAddressForTransactions(${DerivePathTypeExt.primaryFor(coin)}): $e\n$s", - level: LogLevel.Error); - rethrow; - } - } - Future<void> _checkCurrentReceivingAddressesForTransactions() async { try { // for (final type in DerivePathType.values) { @@ -1880,30 +1894,6 @@ class BitcoinCashWallet extends CoinServiceAPI } } - Future<void> _checkCurrentChangeAddressesForTransactions() async { - try { - // for (final type in DerivePathType.values) { - await _checkChangeAddressForTransactions(); - // } - } catch (e, s) { - Logging.instance.log( - "Exception rethrown from _checkCurrentChangeAddressesForTransactions(): $e\n$s", - level: LogLevel.Error); - rethrow; - } - } - - /// public wrapper because dart can't test private... - Future<void> checkCurrentChangeAddressesForTransactions() async { - if (Platform.environment["FLUTTER_TEST"] == "true") { - try { - return _checkCurrentChangeAddressesForTransactions(); - } catch (_) { - rethrow; - } - } - } - /// attempts to convert a string to a valid scripthash /// /// Returns the scripthash or throws an exception on invalid bch address @@ -2485,10 +2475,11 @@ class BitcoinCashWallet extends CoinServiceAPI if (changeOutputSize > DUST_LIMIT.raw.toInt() && satoshisBeingUsed - satoshiAmountToSend - changeOutputSize == feeForTwoOutputs) { - // generate new change address if current change address has been used - await _checkChangeAddressForTransactions(); - final String newChangeAddress = await _getCurrentAddressForChain( - 1, DerivePathTypeExt.primaryFor(coin)); + // get the next unused change address + final String newChangeAddress = + (await _getUnusedChangeAddresses(numberOfAddresses: 1)) + .first + .value; int feeBeingPaid = satoshisBeingUsed - satoshiAmountToSend - changeOutputSize; diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index fea80bf25..c4c8d027f 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -47,7 +47,8 @@ mixin FusionWalletInterface { } // Passed in wallet functions. - late final Future<Address> Function() _getNextUnusedChangeAddress; + late final Future<List<Address>> Function({int numberOfAddresses}) + _getNextUnusedChangeAddresses; late final CachedElectrumX Function() _getWalletCachedElectrumX; late final Future<int> Function({ required String address, @@ -61,7 +62,8 @@ mixin FusionWalletInterface { required String walletId, required Coin coin, required MainDB db, - required Future<Address> Function() getNextUnusedChangeAddress, + required Future<List<Address>> Function({int numberOfAddresses}) + getNextUnusedChangeAddress, required CachedElectrumX Function() getWalletCachedElectrumX, required Future<int> Function({ required String address, @@ -75,7 +77,7 @@ mixin FusionWalletInterface { _walletId = walletId; _coin = coin; _db = db; - _getNextUnusedChangeAddress = getNextUnusedChangeAddress; + _getNextUnusedChangeAddresses = getNextUnusedChangeAddress; _torService = FusionTorService.sharedInstance; _getWalletCachedElectrumX = getWalletCachedElectrumX; _getTxCountForAddress = getTxCountForAddress; @@ -176,15 +178,11 @@ mixin FusionWalletInterface { } } - /// Creates a new reserved change address. - Future<Address> _createNewReservedChangeAddress() async { - // _getNextUnusedChangeAddress() grabs the latest unused change address - // from the wallet. - // CopyWith to mark it as a fusion reserved change address - final address = (await _getNextUnusedChangeAddress()) - .copyWith(otherData: kReservedFusionAddress); + /// Reserve an address for fusion. + Future<Address> _reserveAddress(Address address) async { + address = address.copyWith(otherData: kReservedFusionAddress); - // Make sure the address is in the database as reserved for Fusion. + // Make sure the address is updated in the database as reserved for Fusion. final _address = await _db.getAddress(_walletId, address.value); if (_address != null) { await _db.updateAddress(_address, address); @@ -195,60 +193,50 @@ mixin FusionWalletInterface { return address; } + /// un reserve a fusion reserved address. + /// If [address] is not reserved nothing happens + Future<Address> _unReserveAddress(Address address) async { + if (address.otherData != kReservedFusionAddress) { + return address; + } + + final updated = address.copyWith(otherData: null); + + // Make sure the address is updated in the database. + await _db.updateAddress(address, updated); + + return updated; + } + /// Returns a list of unused reserved change addresses. /// /// If there are not enough unused reserved change addresses, new ones are created. Future<List<fusion.Address>> _getUnusedReservedChangeAddresses( int numberOfAddresses, ) async { - // Fetch all reserved change addresses. - final List<Address> reservedChangeAddresses = await _db - .getAddresses(_walletId) - .filter() - .otherDataEqualTo(kReservedFusionAddress) - .and() - .subTypeEqualTo(AddressSubType.change) - .findAll(); + final unusedChangeAddresses = await _getNextUnusedChangeAddresses( + numberOfAddresses: numberOfAddresses, + ); // Initialize a list of unused reserved change addresses. - final List<Address> unusedAddresses = []; - - // check addresses for tx history - for (final address in reservedChangeAddresses) { - // first check in db to avoid unnecessary network calls - final txCountInDB = await _db - .getTransactions(_walletId) - .filter() - .address((q) => q.valueEqualTo(address.value)) - .count(); - if (txCountInDB == 0) { - // double check via electrumx - // _getTxCountForAddress can throw! - final count = await _getTxCountForAddress(address: address.value); - if (count == 0) { - unusedAddresses.add(address); - } - } - } - - // If there are not enough unused reserved change addresses, create new ones. - while (unusedAddresses.length < numberOfAddresses) { - unusedAddresses.add(await _createNewReservedChangeAddress()); + final List<Address> unusedReservedAddresses = []; + for (final address in unusedChangeAddresses) { + unusedReservedAddresses.add(await _reserveAddress(address)); } // Return the list of unused reserved change addresses. - return unusedAddresses.sublist(0, numberOfAddresses).map((e) { - final bool fusionReserved = e.otherData == kReservedFusionAddress; - - return fusion.Address( - address: e.value, - publicKey: e.publicKey, - fusionReserved: fusionReserved, - derivationPath: fusion.DerivationPath( - e.derivationPath!.value, - ), - ); - }).toList(); + return unusedReservedAddresses + .map( + (e) => fusion.Address( + address: e.value, + publicKey: e.publicKey, + fusionReserved: true, + derivationPath: fusion.DerivationPath( + e.derivationPath!.value, + ), + ), + ) + .toList(); } int _torStartCount = 0; From ad965e081cf55f90ee984f7eff8a6471c3d9149d Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 13:29:04 -0500 Subject: [PATCH 194/379] refactor logic to fail currently-running state step --- .../mixins/fusion_wallet_interface.dart | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index c4c8d027f..86e2fc318 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -112,10 +112,14 @@ mixin FusionWalletInterface { case fusion.FusionStatus.failed: _uiState?.fusing = CashFusionStatus.failed; _uiState?.complete = CashFusionStatus.failed; + + failCurrentUiState(); + break; case fusion.FusionStatus.exception: - _uiState?.fusing = CashFusionStatus.failed; _uiState?.complete = CashFusionStatus.failed; + + failCurrentUiState(); break; case fusion.FusionStatus.reset: _uiState?.outputs = CashFusionStatus.waiting; @@ -128,6 +132,22 @@ mixin FusionWalletInterface { } } + void failCurrentUiState() { + // Check each _uiState value to see if it is running. If so, set it to failed. + if (_uiState?.connecting == CashFusionStatus.running) { + _uiState?.connecting = CashFusionStatus.failed; + } + if (_uiState?.outputs == CashFusionStatus.running) { + _uiState?.outputs = CashFusionStatus.failed; + } + if (_uiState?.peers == CashFusionStatus.running) { + _uiState?.peers = CashFusionStatus.failed; + } + if (_uiState?.fusing == CashFusionStatus.running) { + _uiState?.fusing = CashFusionStatus.failed; + } + } + /// Returns a list of all transactions in the wallet for the given address. Future<List<Map<String, dynamic>>> _getTransactionsByAddress( String address, From d357b8dd69e4ab5372deeb07dc14da98a61b140a Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 13:29:11 -0500 Subject: [PATCH 195/379] remove helper func --- .../mixins/fusion_wallet_interface.dart | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 86e2fc318..eee4a9ce6 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -393,30 +393,4 @@ mixin FusionWalletInterface { throw UnimplementedError( "TODO refreshFusion eg look up number of fusion participants connected/coordinating"); } - - /// Testing ground for iterating thru the UI state. - /// - /// TODO remove this, just for development. - Future<void> stepThruUiStates() async { - // Define the list of states. - final List<fusion.FusionStatus> states = [ - fusion.FusionStatus.connecting, - fusion.FusionStatus.setup, - fusion.FusionStatus.waiting, - fusion.FusionStatus.running, - fusion.FusionStatus.complete, - fusion.FusionStatus.failed, - fusion.FusionStatus.exception, - fusion.FusionStatus.reset, - ]; - - // Iterate through the list of states, waiting one second between each. - for (final state in states) { - // Set the connecting status to the current state. - _updateStatus(state); - - // Wait one second. - await Future.delayed(const Duration(seconds: 1)); - } - } } From 0934fa99045016b2144732a832929726b6167e5b Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 13:29:17 -0500 Subject: [PATCH 196/379] update fusiondart ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 64a78efc4..a66f82dd6 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 64a78efc4a2f874f16975e2aa7fca564444e4aae +Subproject commit a66f82dd6dd20b21f46085f9c3cfbd610ebd0275 From 057f794fde9b10897cf36cd48b3612fb1007b971 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 13:40:13 -0500 Subject: [PATCH 197/379] don't prematurely set fusing to failed --- lib/services/mixins/fusion_wallet_interface.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index eee4a9ce6..8815cbab4 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -110,7 +110,7 @@ mixin FusionWalletInterface { _uiState?.complete = CashFusionStatus.success; break; case fusion.FusionStatus.failed: - _uiState?.fusing = CashFusionStatus.failed; + // _uiState?.fusing = CashFusionStatus.failed; _uiState?.complete = CashFusionStatus.failed; failCurrentUiState(); From 63b03e5b57971e96b0fba73a5d37d64c942673fb Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 13 Oct 2023 13:40:54 -0500 Subject: [PATCH 198/379] move ui status update to after output check --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index a66f82dd6..1d88132b2 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit a66f82dd6dd20b21f46085f9c3cfbd610ebd0275 +Subproject commit 1d88132b28c20d0b52e6db3feac3744093b2d5d9 From 5b37b9466864aff03313e10f2223486e42df6aff Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 13 Oct 2023 12:48:17 -0600 Subject: [PATCH 199/379] implement unreserve --- .../mixins/fusion_wallet_interface.dart | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 8815cbab4..0a14b55fa 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -318,6 +318,26 @@ mixin FusionWalletInterface { broadcastTransaction: (String txHex) => _getWalletCachedElectrumX() .electrumXClient .broadcastTransaction(rawTx: txHex), + unReserveAddresses: (List<fusion.Address> addresses) async { + final List<Future<void>> futures = []; + for (final addr in addresses) { + futures.add( + _db.getAddress(_walletId, addr.address).then( + (address) async { + if (address == null) { + // matching address not found in db so cannot mark as unreserved + // just ignore I guess. Should never actually happen in practice. + // Might be useful check in debugging cases? + return; + } else { + await _unReserveAddress(address); + } + }, + ), + ); + } + await Future.wait(futures); + }, ); // Add unfrozen stack UTXOs. From 129c760180f0d76c22a221d79075d0e7d0af1223 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 13 Oct 2023 12:50:01 -0600 Subject: [PATCH 200/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 1d88132b2..0a151a84f 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 1d88132b28c20d0b52e6db3feac3744093b2d5d9 +Subproject commit 0a151a84ff6ba4cbfe6bd4c67a89a2d01df26f95 From fbf8e60094212e635db13b8645a4058c8d75b1ed Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 13 Oct 2023 12:52:15 -0600 Subject: [PATCH 201/379] remove unused function --- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 1 - lib/services/mixins/fusion_wallet_interface.dart | 7 ------- 2 files changed, 8 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 5a2abfe9b..73d15a05d 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -141,7 +141,6 @@ class BitcoinCashWallet extends CoinServiceAPI db: db, getWalletCachedElectrumX: () => cachedElectrumXClient, getNextUnusedChangeAddress: _getUnusedChangeAddresses, - getTxCountForAddress: getTxCount, getChainHeight: () async => chainHeight, mnemonic: mnemonicString, mnemonicPassphrase: mnemonicPassphrase, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 0a14b55fa..f6447ce6c 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -50,9 +50,6 @@ mixin FusionWalletInterface { late final Future<List<Address>> Function({int numberOfAddresses}) _getNextUnusedChangeAddresses; late final CachedElectrumX Function() _getWalletCachedElectrumX; - late final Future<int> Function({ - required String address, - }) _getTxCountForAddress; late final Future<int> Function() _getChainHeight; /// Initializes the FusionWalletInterface mixin. @@ -65,9 +62,6 @@ mixin FusionWalletInterface { required Future<List<Address>> Function({int numberOfAddresses}) getNextUnusedChangeAddress, required CachedElectrumX Function() getWalletCachedElectrumX, - required Future<int> Function({ - required String address, - }) getTxCountForAddress, required Future<int> Function() getChainHeight, required Future<String?> mnemonic, required Future<String?> mnemonicPassphrase, @@ -80,7 +74,6 @@ mixin FusionWalletInterface { _getNextUnusedChangeAddresses = getNextUnusedChangeAddress; _torService = FusionTorService.sharedInstance; _getWalletCachedElectrumX = getWalletCachedElectrumX; - _getTxCountForAddress = getTxCountForAddress; _getChainHeight = getChainHeight; _mnemonic = mnemonic; _mnemonicPassphrase = mnemonicPassphrase; From cc0a1eee33015ff63a6d4f861af3f1a77008a816 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 13 Oct 2023 15:30:40 -0600 Subject: [PATCH 202/379] fix bch transaction signing --- .../coins/bitcoincash/bitcoincash_wallet.dart | 87 +++++++------------ 1 file changed, 32 insertions(+), 55 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 73d15a05d..0a07ed579 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2809,66 +2809,43 @@ class BitcoinCashWallet extends CoinServiceAPI testnet: coin == Coin.bitcoincashTestnet, ); - // retrieve address' utxos from the rest api - List<bitbox.Utxo> _utxos = - []; // await Bitbox.Address.utxo(address) as List<Bitbox.Utxo>; - for (var element in utxosToUse) { - _utxos.add(bitbox.Utxo( - element.txid, - element.vout, - bitbox.BitcoinCash.fromSatoshi(element.value), - element.value, - 0, - MINIMUM_CONFIRMATIONS + 1)); - } - Logger.print("bch utxos: $_utxos"); - - // placeholder for input signatures - final List<Map<dynamic, dynamic>> signatures = []; - - // placeholder for total input balance - // int totalBalance = 0; - - // iterate through the list of address _utxos and use them as inputs for the - // withdrawal transaction - for (var utxo in _utxos) { - // add the utxo as an input for the transaction - builder.addInput(utxo.txid, utxo.vout); - final ec = - utxoSigningData.firstWhere((e) => e.utxo.txid == utxo.txid).keyPair!; - - final bitboxEC = bitbox.ECPair.fromWIF(ec.toWIF()); - - // add a signature to the list to be used later - signatures.add({ - "vin": signatures.length, - "key_pair": bitboxEC, - "original_amount": utxo.satoshis - }); - - // totalBalance += utxo.satoshis; - } - - // calculate the fee based on number of inputs and one expected output - // final fee = - // bitbox.BitcoinCash.getByteCount(signatures.length, recipients.length); - - // calculate how much balance will be left over to spend after the fee - // final sendAmount = totalBalance - fee; - // add the output based on the address provided in the testing data for (int i = 0; i < recipients.length; i++) { - String recipient = recipients[i]; - int satoshiAmount = satoshiAmounts[i]; - builder.addOutput(recipient, satoshiAmount); + builder.addOutput(recipients[i], satoshiAmounts[i]); } - // sign all inputs - for (var signature in signatures) { + assert(utxosToUse.length == utxoSigningData.length); + + final List<({bitbox.ECPair ecPair, int sats})> signingData = []; + + for (final sd in utxoSigningData) { + final utxo = bitbox.Utxo( + sd.utxo.txid, + sd.utxo.vout, + bitbox.BitcoinCash.fromSatoshi(sd.utxo.value), + sd.utxo.value, + 0, + MINIMUM_CONFIRMATIONS + 1, // why +1 ? + ); + + // add the utxo as an input for the transaction + builder.addInput(utxo.txid, utxo.vout); + + // prepare signing data + signingData.add( + ( + ecPair: bitbox.ECPair.fromWIF(sd.keyPair!.toWIF()), + sats: utxo.satoshis, + ), + ); + } + + for (int i = 0; i < signingData.length; i++) { builder.sign( - signature["vin"] as int, - signature["key_pair"] as bitbox.ECPair, - signature["original_amount"] as int); + i, + signingData[i].ecPair, + signingData[i].sats, + ); } // build the transaction From 7616e70923cb05c90d84dd665b45edae8c2f36f9 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 13 Oct 2023 15:44:10 -0600 Subject: [PATCH 203/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 0a151a84f..d371eb264 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 0a151a84ff6ba4cbfe6bd4c67a89a2d01df26f95 +Subproject commit d371eb2643493f78fa5583f1dc41d2c988bf9e28 From 85e248f2e13c2527aecaae125af2258ca61edeb9 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 13 Oct 2023 16:05:26 -0600 Subject: [PATCH 204/379] added extra logging --- lib/services/mixins/fusion_wallet_interface.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index f6447ce6c..a66e5e0c1 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -186,7 +186,8 @@ mixin FusionWalletInterface { ); return node.privateKey!; - } catch (_) { + } catch (e, s) { + Logging.instance.log("$e\n$s", level: LogLevel.Fatal); throw Exception("Derivation path for pubkey=$pubKey could not be found"); } } From a21eb37b2640f0629509671378cc6ce401c7f56f Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 09:53:04 -0600 Subject: [PATCH 205/379] WIP bch transaction parsing --- .../global_settings_view/hidden_settings.dart | 77 +++++++++++++++++++ lib/services/mixins/electrum_x_parsing.dart | 14 ++++ lib/utilities/util.dart | 13 +++- 3 files changed, 101 insertions(+), 3 deletions(-) diff --git a/lib/pages/settings_views/global_settings_view/hidden_settings.dart b/lib/pages/settings_views/global_settings_view/hidden_settings.dart index 924524de7..c6782cff4 100644 --- a/lib/pages/settings_views/global_settings_view/hidden_settings.dart +++ b/lib/pages/settings_views/global_settings_view/hidden_settings.dart @@ -15,12 +15,15 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:stackwallet/db/hive/db.dart'; +import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/providers/global/debug_service_provider.dart'; import 'package:stackwallet/providers/providers.dart'; +import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/background.dart'; @@ -343,6 +346,80 @@ class HiddenSettings extends StatelessWidget { } }, ), + const SizedBox( + height: 12, + ), + Consumer( + builder: (_, ref, __) { + return GestureDetector( + onTap: () async { + try { + final p = TT(); + + final n = ref + .read(nodeServiceChangeNotifierProvider) + .getPrimaryNodeFor( + coin: Coin.bitcoincash)!; + + final e = ElectrumX.from( + node: ElectrumXNode( + address: n.host, + port: n.port, + name: n.name, + id: n.id, + useSSL: n.useSSL, + ), + prefs: + ref.read(prefsChangeNotifierProvider), + failovers: [], + ); + + final txids = [ + "", // cashTokenTxid + "6a0444358bc41913c5b04a8dc06896053184b3641bc62502d18f954865b6ce1e", // normalTxid + "67f13c375f9be897036cac77b7900dc74312c4ba6fe22f419f5cb21d4151678c", // fusionTxid + "c0ac3f88b238a023d2a87226dc90c3b0f9abc3eeb227e2730087b0b95ee5b3f9", // slpTokenSendTxid + "7a427a156fe70f83d3ccdd17e75804cc0df8c95c64ce04d256b3851385002a0b", // slpTokenGenesisTxid + ]; + + // final json = + // await e.getTransaction(txHash: txids[1]); + // await p.parseBchTx(json, "NORMAL TXID:"); + // + // final json2 = + // await e.getTransaction(txHash: txids[2]); + // await p.parseBchTx(json2, "FUSION TXID:"); + // + // // print("CASH TOKEN TXID:"); + // // final json3 = + // // await e.getTransaction(txHash: txids[2]); + // // await p.parseBchTx(json3); + // + final json4 = + await e.getTransaction(txHash: txids[3]); + await p.parseBchTx( + json4, "SLP TOKEN SEND TXID:"); + + final json5 = + await e.getTransaction(txHash: txids[4]); + await p.parseBchTx( + json5, "SLP TOKEN GENESIS TXID:"); + } catch (e, s) { + print("$e\n$s"); + } + }, + child: RoundedWhiteContainer( + child: Text( + "Parse BCH tx test", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .accentColorDark), + ), + ), + ); + }, + ), // const SizedBox( // height: 12, // ), diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index d0b88ba35..224073574 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -16,9 +16,23 @@ import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/util.dart' as util; import 'package:tuple/tuple.dart'; +class TT with ElectrumXParsing { + // +} + mixin ElectrumXParsing { + Future<dynamic> parseBchTx( + Map<String, dynamic> json, [ + String? debugTitle, + ]) async { + print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + util.Util.printJson(json, debugTitle); + print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + } + Future<Tuple2<Transaction, Address>> parseTransaction( Map<String, dynamic> txData, dynamic electrumxClient, diff --git a/lib/utilities/util.dart b/lib/utilities/util.dart index c73f697cc..cdfc1bfb7 100644 --- a/lib/utilities/util.dart +++ b/lib/utilities/util.dart @@ -73,14 +73,21 @@ abstract class Util { return MaterialColor(color.value, swatch); } - static void printJson(dynamic json) { + static void printJson(dynamic json, [String? debugTitle]) { + final String result; if (json is Map || json is List) { final spaces = ' ' * 4; final encoder = JsonEncoder.withIndent(spaces); final pretty = encoder.convert(json); - log(pretty); + result = pretty; } else { - log(dynamic.toString()); + result = dynamic.toString(); + } + + if (debugTitle != null) { + log("$debugTitle\n$result"); + } else { + log(result); } } } From f502cf2d805b9fafa394a4036fc0da0b18328b38 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 10:39:54 -0600 Subject: [PATCH 206/379] increase rescan gap bch --- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 0a07ed579..7d241ce1d 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -570,7 +570,7 @@ class BitcoinCashWallet extends CoinServiceAPI Future<void> _recoverWalletFromBIP32SeedPhrase({ required String mnemonic, required String mnemonicPassphrase, - int maxUnusedAddressGap = 20, + int maxUnusedAddressGap = 50, int maxNumberOfIndexesToCheck = 1000, bool isRescan = false, Coin? coin, From d7083cb7251b54cfc22780bbf30962f7c053e963 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 11:04:18 -0600 Subject: [PATCH 207/379] mobile fusion screen layout --- lib/pages/cashfusion/cashfusion_view.dart | 257 ++++++++++++++++++---- 1 file changed, 213 insertions(+), 44 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 2d61828d4..6db751bcd 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -15,10 +15,11 @@ import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; -import 'package:stackwallet/utilities/show_loading.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; class CashFusionView extends ConsumerStatefulWidget { const CashFusionView({ @@ -66,7 +67,7 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { child: AppBarIconButton( size: 36, icon: SvgPicture.asset( - Assets.svg.arrowRotate, + Assets.svg.circleQuestion, width: 20, height: 20, color: Theme.of(context) @@ -74,55 +75,223 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { .topNavIconPrimary, ), onPressed: () async { - // show loading for a minimum of 2 seconds on refreshing - await showLoading( - whileFuture: Future.wait<void>([ - Future.delayed(const Duration(seconds: 2)), - (ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface) - .refreshFusion() - ]), - context: context, - message: "Refreshing..."); + //' TODO show about? }, ), ), ], ), - body: Padding( - padding: const EdgeInsets.only( - left: 16, - right: 16, - top: 8, - ), - child: Column( - children: [ - Expanded( - // child: CashFusionParticipantList( - // walletId: widget.walletId, - // ), - child: Text( - "TODO CashFusionView", - style: STextStyles.desktopTextMedium(context), + body: LayoutBuilder( + builder: (builderContext, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + RoundedWhiteContainer( + child: Text( + "CashFusion allows you to anonymize your BCH coins." + " You must be connected to the Tor network.", + style: STextStyles.w500_12(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, + ), + ), + ), + const SizedBox( + height: 16, + ), + Text( + "Server settings", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark3, + ), + ), + const SizedBox( + height: 12, + ), + TextField(), // TODO replace placholder textfield + const SizedBox( + height: 10, + ), + TextField(), // TODO replace placholder textfield + const SizedBox( + height: 10, + ), + Checkbox( + value: true, + onChanged: (_) {}, + ), // TODO replace placholder Checkbox + const SizedBox( + height: 16, + ), + Text( + "Rounds of fusion", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark3, + ), + ), + const SizedBox( + height: 12, + ), + TextField(), // TODO replace placholder textfield with button for bottom sheet + const SizedBox( + height: 16, + ), + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Text( + // "Tor status", + // textAlign: TextAlign.left, + // style: isDesktop + // ? STextStyles.desktopTextExtraExtraSmall(context) + // : STextStyles.smallMed12(context), + // ), + // CustomTextButton( + // text: ref.watch(prefsChangeNotifierProvider + // .select((value) => value.useTor)) + // ? "Disconnect" + // : "Connect", + // onTap: onTorTapped, + // ), + // ], + // ), + // const SizedBox( + // height: 12, + // ),RoundedWhiteContainer( + // borderColor: isDesktop + // ? Theme.of(context).extension<StackColors>()!.background + // : null, + // padding: + // isDesktop ? const EdgeInsets.all(16) : const EdgeInsets.all(12), + // child: Row( + // children: [ + // if (ref.watch(prefsChangeNotifierProvider + // .select((value) => value.useTor))) + // Container( + // width: _iconSize, + // height: _iconSize, + // decoration: BoxDecoration( + // color: Theme.of(context) + // .extension<StackColors>()! + // .accentColorGreen + // .withOpacity(0.2), + // borderRadius: BorderRadius.circular(_iconSize), + // ), + // child: Center( + // child: SvgPicture.asset( + // Assets.svg.tor, + // height: isDesktop ? 19 : 14, + // width: isDesktop ? 19 : 14, + // color: Theme.of(context) + // .extension<StackColors>()! + // .accentColorGreen, + // ), + // ), + // ), + // if (!ref.watch(prefsChangeNotifierProvider + // .select((value) => value.useTor))) + // Container( + // width: _iconSize, + // height: _iconSize, + // decoration: BoxDecoration( + // color: Theme.of(context) + // .extension<StackColors>()! + // .textDark + // .withOpacity(0.08), + // borderRadius: BorderRadius.circular(_iconSize), + // ), + // child: Center( + // child: SvgPicture.asset( + // Assets.svg.tor, + // height: isDesktop ? 19 : 14, + // width: isDesktop ? 19 : 14, + // color: Theme.of(context) + // .extension<StackColors>()! + // .textDark, + // ), + // ), + // ), + // SizedBox( + // width: _boxPadding, + // ), + // TorSubscription( + // onTorStatusChanged: (status) { + // setState(() { + // _torConnectionStatus = status; + // }); + // }, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // "Tor status", + // style: STextStyles.desktopTextExtraExtraSmall(context) + // .copyWith( + // color: Theme.of(context) + // .extension<StackColors>()! + // .textDark, + // ), + // ), + // if (_torConnectionStatus == TorConnectionStatus.connected) + // Text( + // "Connected", + // style: + // STextStyles.desktopTextExtraExtraSmall(context), + // ), + // if (_torConnectionStatus == + // TorConnectionStatus.connecting) + // Text( + // "Connecting...", + // style: + // STextStyles.desktopTextExtraExtraSmall(context), + // ), + // if (_torConnectionStatus == + // TorConnectionStatus.disconnected) + // Text( + // "Disconnected", + // style: + // STextStyles.desktopTextExtraExtraSmall(context), + // ), + // ], + // ), + // ), + // ], + // ), + // ), + const SizedBox( + height: 16, + ), + const Spacer(), + PrimaryButton( + label: "Start", + onPressed: () => { + (ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface) + .fuse() + }, + ), + ], + ), + ), ), ), - TextButton( - onPressed: () => { - (ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface) - .fuse() - }, - child: Text( - "Fuse", - style: STextStyles.desktopTextMedium(context), - ), - ) - ], - ), + ); + }, ), ), ), From 006c0a19f32d2a437f6964262c7748716e8bd126 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 16 Oct 2023 12:38:24 -0500 Subject: [PATCH 208/379] add cashfusion svg --- assets/svg/cashfusion-icon.svg | 3 +++ lib/utilities/assets.dart | 2 +- pubspec.yaml | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 assets/svg/cashfusion-icon.svg diff --git a/assets/svg/cashfusion-icon.svg b/assets/svg/cashfusion-icon.svg new file mode 100644 index 000000000..e1d010ada --- /dev/null +++ b/assets/svg/cashfusion-icon.svg @@ -0,0 +1,3 @@ +<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M20.5449 14.8336V9.00229C21.2517 8.76248 21.7692 8.09352 21.7692 7.31096C21.7692 6.32645 20.974 5.53127 19.9895 5.53127C19.5225 5.53127 19.0933 5.7206 18.7652 6.02352L13.7921 3.15835C13.8174 3.03213 13.83 2.90591 13.83 2.77969C13.83 1.79518 13.0348 1 12.0503 1C11.0658 1 10.258 1.79518 10.258 2.77969C10.258 2.90591 10.2706 3.01951 10.2959 3.14573L5.27235 6.04877C4.94418 5.73322 4.50241 5.53127 4.01016 5.53127C3.02565 5.53127 2.23047 6.32645 2.23047 7.31096C2.23047 8.13138 2.78583 8.82559 3.55577 9.02754V14.8084C2.79845 15.0103 2.23047 15.7045 2.23047 16.525C2.23047 17.5095 3.02565 18.3046 4.01016 18.3046C4.47717 18.3046 4.90632 18.1153 5.23449 17.8124L10.3211 20.7533C10.2833 20.9048 10.258 21.0562 10.258 21.2203C10.258 22.2048 11.0532 23 12.0377 23C13.0222 23 13.83 22.2174 13.83 21.2329C13.83 21.0688 13.8048 20.9174 13.7669 20.7659L18.803 17.8629C19.1186 18.1406 19.5351 18.3173 19.9895 18.3173C20.974 18.3173 21.7692 17.5221 21.7692 16.5376C21.7692 15.7424 21.2517 15.0734 20.5449 14.8336ZM19.6487 17.3201C19.3584 17.1939 19.1438 16.9162 19.1312 16.5754C19.1312 16.5628 19.1312 16.5502 19.1312 16.5376V16.525C19.1312 16.5123 19.1312 16.4997 19.1312 16.4745C19.1438 16.1968 19.2953 15.9443 19.5225 15.8055C19.5351 15.7929 19.5477 15.7803 19.573 15.7803C19.5856 15.7803 19.5982 15.7676 19.6108 15.7676C19.7244 15.7045 19.8633 15.6793 20.0021 15.6793C20.1915 15.6793 20.3682 15.7424 20.5196 15.856C20.5322 15.8686 20.5575 15.8812 20.5701 15.8939C20.7468 16.0453 20.8604 16.2851 20.8604 16.5376C20.8604 17.0046 20.4818 17.3959 20.0021 17.3959C19.9012 17.3959 19.8128 17.3832 19.7244 17.3454C19.6866 17.3328 19.674 17.3201 19.6487 17.3201ZM12.0503 22.0912C11.5959 22.0912 11.2173 21.7252 11.192 21.2708C11.192 21.2582 11.192 21.2456 11.192 21.2456C11.192 21.2329 11.192 21.2329 11.192 21.2203C11.2047 20.93 11.3561 20.6776 11.5833 20.5261C11.6338 20.5009 11.6717 20.4756 11.7222 20.4504C11.7474 20.4377 11.76 20.4377 11.7853 20.4251C11.8736 20.3999 11.962 20.3873 12.0503 20.3873C12.1387 20.3873 12.227 20.3999 12.3154 20.4251C12.3406 20.4377 12.3532 20.4377 12.3785 20.4504C12.429 20.4756 12.4795 20.5009 12.5173 20.5261C12.7445 20.6776 12.896 20.93 12.9086 21.2203C12.9086 21.2329 12.9086 21.2329 12.9086 21.2456C12.9086 21.2582 12.9086 21.2708 12.9086 21.2708C12.8834 21.7252 12.5047 22.0912 12.0503 22.0912ZM4.35095 17.3201C4.24998 17.358 4.13638 17.3832 4.01016 17.3832C3.54315 17.3832 3.15187 17.0046 3.15187 16.525C3.15187 16.222 3.30333 15.957 3.54315 15.8055C3.55577 15.7929 3.56839 15.7803 3.59364 15.7803C3.71985 15.7045 3.8587 15.6667 4.01016 15.6667C4.02278 15.6667 4.04802 15.6667 4.06065 15.6667C4.23735 15.6793 4.38882 15.7424 4.52766 15.8307C4.54028 15.8434 4.56552 15.856 4.57815 15.8686C4.72961 16.0075 4.84321 16.1968 4.86845 16.4114C4.86845 16.424 4.86845 16.4492 4.86845 16.4745C4.86845 16.4871 4.86845 16.4997 4.86845 16.525C4.86845 16.5628 4.86845 16.5881 4.85583 16.6259C4.81796 16.9162 4.64125 17.1561 4.40144 17.2823C4.38882 17.2949 4.36357 17.3075 4.35095 17.3201ZM3.16449 7.31096C3.16449 6.84395 3.54315 6.45267 4.02278 6.45267C4.16162 6.45267 4.28784 6.49053 4.41406 6.54102C4.42668 6.55364 4.45193 6.55364 4.46455 6.56626C4.59077 6.642 4.70436 6.75559 4.7801 6.89443C4.84321 7.02065 4.88107 7.15949 4.88107 7.31096C4.88107 7.34882 4.88107 7.37407 4.86845 7.41193C4.86845 7.43718 4.86845 7.4498 4.85583 7.47504C4.83058 7.61388 4.76747 7.72748 4.69174 7.82846C4.65388 7.87894 4.61601 7.91681 4.57815 7.95468C4.56552 7.9673 4.5529 7.97992 4.52766 7.99254C4.38882 8.10614 4.21211 8.16925 4.01016 8.16925C3.8587 8.16925 3.71985 8.13138 3.59364 8.05565C3.58101 8.04303 3.55577 8.04303 3.54315 8.03041C3.31595 7.86632 3.16449 7.61388 3.16449 7.31096ZM12.0503 1.9214C12.4668 1.9214 12.8076 2.22433 12.8834 2.61561C12.8834 2.64085 12.896 2.65347 12.896 2.67871C12.896 2.71658 12.9086 2.74182 12.9086 2.77969C12.9086 3.09524 12.7445 3.3603 12.4921 3.51176C12.4795 3.52438 12.4542 3.52438 12.4416 3.537C12.3406 3.58749 12.227 3.62536 12.1008 3.62536C12.0882 3.62536 12.0756 3.62536 12.0503 3.62536C11.9115 3.62536 11.7853 3.58749 11.659 3.537C11.6464 3.52438 11.6212 3.52438 11.6086 3.51176C11.4697 3.42341 11.3561 3.30981 11.2804 3.15835C11.2173 3.04475 11.192 2.90591 11.192 2.76707C11.192 2.7292 11.192 2.70396 11.2047 2.66609C11.2047 2.64085 11.2047 2.62823 11.2173 2.60298C11.2804 2.22433 11.6338 1.9214 12.0503 1.9214ZM19.6487 6.5284C19.7497 6.49053 19.8633 6.46529 19.9895 6.46529C20.4565 6.46529 20.8478 6.84395 20.8478 7.32358C20.8478 7.57602 20.7342 7.81583 20.5575 7.9673C20.5449 7.97992 20.5322 7.99254 20.507 8.00516C20.3682 8.11876 20.1915 8.18187 19.9895 8.18187C19.8759 8.18187 19.7623 8.15663 19.6487 8.11876C19.6235 8.10614 19.5982 8.09352 19.5604 8.08089C19.5477 8.06827 19.5225 8.06827 19.5099 8.05565C19.3079 7.91681 19.1565 7.70224 19.1312 7.4498C19.1312 7.43718 19.1312 7.41193 19.1312 7.38669C19.1312 7.37407 19.1312 7.36144 19.1312 7.3362C19.1312 7.18474 19.1691 7.0459 19.2322 6.91968C19.3205 6.76822 19.4468 6.642 19.5982 6.56626C19.6108 6.54102 19.6361 6.5284 19.6487 6.5284ZM18.7273 15.2628L13.7669 12.3976C13.8048 12.2461 13.83 12.0947 13.83 11.9432C13.83 11.7791 13.8048 11.6277 13.7669 11.4888L18.7652 8.61101C18.9798 8.81296 19.2322 8.95181 19.5225 9.04016V14.821C19.2196 14.8967 18.9419 15.0482 18.7273 15.2628ZM5.72674 7.82846H7.70838C7.79673 8.11876 7.96082 8.3712 8.16277 8.58577L4.57815 14.7958V9.00229C5.12089 8.82559 5.55003 8.38382 5.72674 7.82846ZM9.41234 6.45267C9.87935 6.45267 10.2706 6.83133 10.2706 7.31096C10.2706 7.51291 10.2075 7.68961 10.0939 7.82846C9.95508 8.01778 9.74051 8.144 9.48807 8.15663C9.46283 8.15663 9.43758 8.15663 9.41234 8.15663C8.94533 8.15663 8.55405 7.77797 8.55405 7.29834C8.55405 7.14687 8.59192 7.00803 8.65502 6.88181C8.79387 6.62937 9.07155 6.45267 9.3871 6.44005C9.39972 6.45267 9.39972 6.45267 9.41234 6.45267ZM8.97057 9.04016C9.10941 9.07803 9.26088 9.09065 9.41234 9.09065C10.2201 9.09065 10.9017 8.56053 11.1163 7.82846H18.2477L13.2999 10.681C12.9717 10.3655 12.53 10.1635 12.0377 10.1635C11.0532 10.1635 10.258 10.9587 10.258 11.9432C10.258 12.1073 10.2833 12.2587 10.3211 12.3976L5.37333 15.2501L8.97057 9.04016ZM12.0503 12.8015C11.9115 12.8015 11.7853 12.7636 11.659 12.7131C11.6338 12.7005 11.6086 12.6879 11.5833 12.6627C11.3561 12.5112 11.192 12.2461 11.192 11.9432C11.192 11.9306 11.192 11.918 11.192 11.8927C11.2173 11.4383 11.5833 11.0849 12.0377 11.0849C12.1765 11.0849 12.3028 11.1228 12.429 11.1733C12.694 11.3121 12.8834 11.5772 12.896 11.8927C12.896 11.9053 12.896 11.918 12.896 11.9432C12.896 11.9558 12.896 11.9684 12.896 11.9937C12.8707 12.4481 12.5047 12.8015 12.0503 12.8015ZM11.1415 6.89443C11.0658 6.57889 10.9017 6.28858 10.6872 6.06139L11.5959 4.49627C11.7474 4.53414 11.8989 4.55938 12.0503 4.55938C12.5426 4.55938 12.9843 4.35743 13.3125 4.04188L18.2477 6.89443H11.1415ZM9.89197 5.59438C9.74051 5.55651 9.57642 5.53127 9.41234 5.53127C8.56667 5.53127 7.85984 6.1245 7.68314 6.90706H5.84034L10.7755 4.06713L9.89197 5.59438ZM5.75198 16.1211L10.7881 13.2054C11.0027 13.42 11.2804 13.584 11.5833 13.6598V19.5037C11.3182 19.5795 11.0784 19.7057 10.8765 19.8824L5.75198 16.9415C5.77723 16.8153 5.80247 16.6764 5.80247 16.5376C5.80247 16.3861 5.77723 16.2473 5.75198 16.1211ZM12.5173 19.5164V13.6724C12.8203 13.5841 13.0979 13.4326 13.3125 13.218L18.2729 16.0832C18.2351 16.2347 18.2098 16.3861 18.2098 16.5376C18.2098 16.7017 18.2351 16.8531 18.2729 16.992L13.2368 19.9076C13.0222 19.7183 12.7824 19.5921 12.5173 19.5164Z" fill="#22CC77"/> +</svg> diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart index b668bf304..0d7951706 100644 --- a/lib/utilities/assets.dart +++ b/lib/utilities/assets.dart @@ -198,7 +198,7 @@ class _SVG { String get arrowDown => "assets/svg/arrow-down.svg"; String get robotHead => "assets/svg/robot-head.svg"; String get whirlPool => "assets/svg/whirlpool.svg"; - String get cashFusion => "assets/svg/whirlpool.svg"; + String get cashFusion => "assets/svg/cashfusion-icon.svg"; String get fingerprint => "assets/svg/fingerprint.svg"; String get faceId => "assets/svg/faceid.svg"; String get tokens => "assets/svg/tokens.svg"; diff --git a/pubspec.yaml b/pubspec.yaml index 5e5c63d6c..d8e1f877d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -371,6 +371,7 @@ flutter: - assets/svg/up-from-line.svg - assets/svg/peers.svg - assets/svg/fusing.svg + - assets/svg/cashfusion-icon.svg # coin control icons - assets/svg/coin_control/ From e99c32ea00533a00e81d09313d2352563b35afe2 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 12:00:35 -0600 Subject: [PATCH 209/379] add fusion rounds selection sheet --- lib/pages/cashfusion/cashfusion_view.dart | 187 +++++------------- .../fusion_rounds_selection_sheet.dart | 167 ++++++++++++++++ pubspec.lock | 8 + pubspec.yaml | 1 + 4 files changed, 228 insertions(+), 135 deletions(-) create mode 100644 lib/pages/cashfusion/fusion_rounds_selection_sheet.dart diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 6db751bcd..240e9b087 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -9,8 +9,10 @@ */ import 'package:flutter/material.dart'; +import 'package:flutter_native_splash/cli_commands.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/pages/cashfusion/fusion_rounds_selection_sheet.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; @@ -19,6 +21,7 @@ import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/rounded_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; class CashFusionView extends ConsumerStatefulWidget { @@ -36,15 +39,7 @@ class CashFusionView extends ConsumerStatefulWidget { } class _CashFusionViewState extends ConsumerState<CashFusionView> { - @override - void initState() { - super.initState(); - } - - @override - void dispose() { - super.dispose(); - } + FusionOption _option = FusionOption.continuous; @override Widget build(BuildContext context) { @@ -145,135 +140,57 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { const SizedBox( height: 12, ), - TextField(), // TODO replace placholder textfield with button for bottom sheet - const SizedBox( - height: 16, - ), - // Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // Text( - // "Tor status", - // textAlign: TextAlign.left, - // style: isDesktop - // ? STextStyles.desktopTextExtraExtraSmall(context) - // : STextStyles.smallMed12(context), - // ), - // CustomTextButton( - // text: ref.watch(prefsChangeNotifierProvider - // .select((value) => value.useTor)) - // ? "Disconnect" - // : "Connect", - // onTap: onTorTapped, - // ), - // ], - // ), - // const SizedBox( - // height: 12, - // ),RoundedWhiteContainer( - // borderColor: isDesktop - // ? Theme.of(context).extension<StackColors>()!.background - // : null, - // padding: - // isDesktop ? const EdgeInsets.all(16) : const EdgeInsets.all(12), - // child: Row( - // children: [ - // if (ref.watch(prefsChangeNotifierProvider - // .select((value) => value.useTor))) - // Container( - // width: _iconSize, - // height: _iconSize, - // decoration: BoxDecoration( - // color: Theme.of(context) - // .extension<StackColors>()! - // .accentColorGreen - // .withOpacity(0.2), - // borderRadius: BorderRadius.circular(_iconSize), - // ), - // child: Center( - // child: SvgPicture.asset( - // Assets.svg.tor, - // height: isDesktop ? 19 : 14, - // width: isDesktop ? 19 : 14, - // color: Theme.of(context) - // .extension<StackColors>()! - // .accentColorGreen, - // ), - // ), - // ), - // if (!ref.watch(prefsChangeNotifierProvider - // .select((value) => value.useTor))) - // Container( - // width: _iconSize, - // height: _iconSize, - // decoration: BoxDecoration( - // color: Theme.of(context) - // .extension<StackColors>()! - // .textDark - // .withOpacity(0.08), - // borderRadius: BorderRadius.circular(_iconSize), - // ), - // child: Center( - // child: SvgPicture.asset( - // Assets.svg.tor, - // height: isDesktop ? 19 : 14, - // width: isDesktop ? 19 : 14, - // color: Theme.of(context) - // .extension<StackColors>()! - // .textDark, - // ), - // ), - // ), - // SizedBox( - // width: _boxPadding, - // ), - // TorSubscription( - // onTorStatusChanged: (status) { - // setState(() { - // _torConnectionStatus = status; - // }); - // }, - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // Text( - // "Tor status", - // style: STextStyles.desktopTextExtraExtraSmall(context) - // .copyWith( - // color: Theme.of(context) - // .extension<StackColors>()! - // .textDark, - // ), - // ), - // if (_torConnectionStatus == TorConnectionStatus.connected) - // Text( - // "Connected", - // style: - // STextStyles.desktopTextExtraExtraSmall(context), - // ), - // if (_torConnectionStatus == - // TorConnectionStatus.connecting) - // Text( - // "Connecting...", - // style: - // STextStyles.desktopTextExtraExtraSmall(context), - // ), - // if (_torConnectionStatus == - // TorConnectionStatus.disconnected) - // Text( - // "Disconnected", - // style: - // STextStyles.desktopTextExtraExtraSmall(context), - // ), - // ], - // ), - // ), - // ], - // ), - // ), + RoundedContainer( + onPressed: () async { + final option = + await showModalBottomSheet<FusionOption?>( + backgroundColor: Colors.transparent, + context: context, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + builder: (_) { + return FusionRoundCountSelectSheet( + currentOption: _option, + ); + }, + ); + if (option != null) { + setState(() { + _option = option; + }); + } + }, + color: Theme.of(context) + .extension<StackColors>()! + .textFieldActiveBG, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + _option.name.capitalize(), + style: STextStyles.w500_12(context), + ), + SvgPicture.asset( + Assets.svg.chevronDown, + width: 12, + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, + ), + ], + ), + ), + ), const SizedBox( height: 16, ), + const Spacer(), PrimaryButton( label: "Start", diff --git a/lib/pages/cashfusion/fusion_rounds_selection_sheet.dart b/lib/pages/cashfusion/fusion_rounds_selection_sheet.dart new file mode 100644 index 000000000..f3b00890f --- /dev/null +++ b/lib/pages/cashfusion/fusion_rounds_selection_sheet.dart @@ -0,0 +1,167 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by julian on 2023-10-16 + * + */ + +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:flutter_native_splash/cli_commands.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; + +enum FusionOption { + continuous, + custom; +} + +class FusionRoundCountSelectSheet extends HookWidget { + const FusionRoundCountSelectSheet({ + Key? key, + required this.currentOption, + }) : super(key: key); + + final FusionOption currentOption; + + @override + Widget build(BuildContext context) { + final option = useState(currentOption); + + return WillPopScope( + onWillPop: () async { + Navigator.of(context).pop(option.value); + return false; + }, + child: Container( + decoration: BoxDecoration( + color: Theme.of(context).extension<StackColors>()!.popupBG, + borderRadius: const BorderRadius.vertical( + top: Radius.circular(20), + ), + ), + child: Padding( + padding: const EdgeInsets.only( + left: 24, + right: 24, + top: 10, + bottom: 0, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Center( + child: Container( + decoration: BoxDecoration( + color: Theme.of(context) + .extension<StackColors>()! + .textFieldDefaultBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + width: 60, + height: 4, + ), + ), + const SizedBox( + height: 36, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Rounds of fusion", + style: STextStyles.pageTitleH2(context), + textAlign: TextAlign.left, + ), + const SizedBox( + height: 20, + ), + for (int i = 0; i < FusionOption.values.length; i++) + Column( + children: [ + GestureDetector( + onTap: () { + option.value = FusionOption.values[i]; + Navigator.of(context).pop(option.value); + }, + child: Container( + color: Colors.transparent, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Column( + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + SizedBox( + width: 20, + height: 20, + child: Radio( + activeColor: Theme.of(context) + .extension<StackColors>()! + .radioButtonIconEnabled, + value: FusionOption.values[i], + groupValue: option.value, + onChanged: (_) { + option.value = FusionOption.values[i]; + Navigator.of(context).pop(option.value); + }, + ), + ), + // ], + // ), + const SizedBox( + width: 12, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + FusionOption.values[i].name.capitalize(), + style: STextStyles.titleBold12(context), + textAlign: TextAlign.left, + ), + const SizedBox( + height: 2, + ), + Text( + option.value == FusionOption.continuous + ? "Keep fusing until manually stopped" + : "Stop after a set number of fusions", + style: STextStyles.itemSubtitle12(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark3, + ), + textAlign: TextAlign.left, + ), + ], + ), + ], + ), + ), + ), + const SizedBox( + height: 16, + ), + ], + ), + const SizedBox( + height: 16, + ), + ], + ), + ], + ), + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index ed5f1543a..49125d53d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -621,6 +621,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0+1" + flutter_hooks: + dependency: "direct main" + description: + name: flutter_hooks + sha256: "7c8db779c2d1010aa7f9ea3fbefe8f86524fcb87b69e8b0af31e1a4b55422dec" + url: "https://pub.dev" + source: hosted + version: "0.20.3" flutter_launcher_icons: dependency: "direct dev" description: diff --git a/pubspec.yaml b/pubspec.yaml index d8e1f877d..95480ff05 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -155,6 +155,7 @@ dependencies: socks5_proxy: ^1.0.3+dev.3 coinlib_flutter: ^1.0.0 convert: ^3.1.1 + flutter_hooks: ^0.20.3 dev_dependencies: flutter_test: From e163081b383b08236da3443125daf6e8c64e18ff Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 16 Oct 2023 13:48:02 -0500 Subject: [PATCH 210/379] add server and port controllers --- lib/pages/cashfusion/cashfusion_view.dart | 70 ++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 240e9b087..560e17c08 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -23,6 +23,7 @@ import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:stackwallet/widgets/stack_text_field.dart'; class CashFusionView extends ConsumerStatefulWidget { const CashFusionView({ @@ -39,8 +40,38 @@ class CashFusionView extends ConsumerStatefulWidget { } class _CashFusionViewState extends ConsumerState<CashFusionView> { + late final TextEditingController serverController; + late final FocusNode serverFocusNode; + late final TextEditingController portController; + late final FocusNode portFocusNode; + + String _serverTerm = ""; + String _portTerm = ""; + int? port; + late bool enableSSLCheckbox; + FusionOption _option = FusionOption.continuous; + @override + void initState() { + serverController = TextEditingController(); + portController = TextEditingController(); + + serverFocusNode = FocusNode(); + portFocusNode = FocusNode(); + } + + @override + void dispose() { + serverController.dispose(); + portController.dispose(); + + serverFocusNode.dispose(); + portFocusNode.dispose(); + + super.dispose(); + } + @override Widget build(BuildContext context) { return Background( @@ -114,11 +145,46 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { const SizedBox( height: 12, ), - TextField(), // TODO replace placholder textfield + TextField( + autocorrect: false, + enableSuggestions: false, + controller: serverController, + focusNode: serverFocusNode, + onChanged: (value) { + setState(() { + _serverTerm = value; + }); + }, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "Server", + serverFocusNode, + context, + desktopMed: true, + ) + // .copyWith(labelStyle: ), + ), const SizedBox( height: 10, ), - TextField(), // TODO replace placholder textfield + TextField( + autocorrect: false, + enableSuggestions: false, + controller: portController, + focusNode: portFocusNode, + onChanged: (value) { + setState(() { + _portTerm = value; + }); + }, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "Port", + portFocusNode, + context, + desktopMed: true, + ), + ), const SizedBox( height: 10, ), From f186f01c484c40297e36d4dafe9b2eab6a548311 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 13:45:23 -0600 Subject: [PATCH 211/379] fix: info text bug --- lib/pages/cashfusion/fusion_rounds_selection_sheet.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/pages/cashfusion/fusion_rounds_selection_sheet.dart b/lib/pages/cashfusion/fusion_rounds_selection_sheet.dart index f3b00890f..3b36864ab 100644 --- a/lib/pages/cashfusion/fusion_rounds_selection_sheet.dart +++ b/lib/pages/cashfusion/fusion_rounds_selection_sheet.dart @@ -131,7 +131,8 @@ class FusionRoundCountSelectSheet extends HookWidget { height: 2, ), Text( - option.value == FusionOption.continuous + FusionOption.values[i] == + FusionOption.continuous ? "Keep fusing until manually stopped" : "Stop after a set number of fusions", style: STextStyles.itemSubtitle12(context) From 9b9a7cbb28ccec487ae83b3bdbceba9d662d46fc Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 13:46:05 -0600 Subject: [PATCH 212/379] broken utxo fetch attempt --- .../global_settings_view/hidden_settings.dart | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/lib/pages/settings_views/global_settings_view/hidden_settings.dart b/lib/pages/settings_views/global_settings_view/hidden_settings.dart index c6782cff4..d2aaf4535 100644 --- a/lib/pages/settings_views/global_settings_view/hidden_settings.dart +++ b/lib/pages/settings_views/global_settings_view/hidden_settings.dart @@ -9,7 +9,9 @@ */ import 'dart:async'; +import 'dart:typed_data'; +import 'package:bitcoindart/bitcoindart.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -19,8 +21,10 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/providers/global/debug_service_provider.dart'; import 'package:stackwallet/providers/providers.dart'; +import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'; import 'package:stackwallet/services/mixins/electrum_x_parsing.dart'; import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/address_utils.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -420,6 +424,90 @@ class HiddenSettings extends StatelessWidget { ); }, ), + const SizedBox( + height: 12, + ), + Consumer( + builder: (_, ref, __) { + return GestureDetector( + onTap: () async { + try { + final p = TT(); + + final n = ref + .read(nodeServiceChangeNotifierProvider) + .getPrimaryNodeFor( + coin: Coin.bitcoincash)!; + + final e = ElectrumX.from( + node: ElectrumXNode( + address: n.host, + port: n.port, + name: n.name, + id: n.id, + useSSL: n.useSSL, + ), + prefs: + ref.read(prefsChangeNotifierProvider), + failovers: [], + ); + + final address = + "qzmd5vxgh9m22m6fgvm57yd6kjnjl9qnwyztz2p80d"; + + List<int> _base32Decode(String string) { + final data = Uint8List(string.length); + for (int i = 0; i < string.length; i++) { + final value = string[i]; + if (!_CHARSET_INVERSE_INDEX + .containsKey(value)) + throw FormatException( + "Invalid character '$value'"); + data[i] = + _CHARSET_INVERSE_INDEX[string[i]]!; + } + + return data.sublist(1); + } + + final dec = _base32Decode(address); + + final pd = PaymentData( + pubkey: Uint8List.fromList(dec)); + + final p2pkh = + P2PKH(data: pd, network: bitcoincash); + + final addr = p2pkh.data.address!; + + final scripthash = + AddressUtils.convertToScriptHash( + addr, bitcoincash); + + final hist = await e.getHistory( + scripthash: scripthash); + + Util.printJson(hist, "HISTORY for $address"); + final utxos = + await e.getUTXOs(scripthash: scripthash); + + Util.printJson(utxos, "UTXOS for $address"); + } catch (e, s) { + print("$e\n$s"); + } + }, + child: RoundedWhiteContainer( + child: Text( + "UTXOs", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .accentColorDark), + ), + ), + ); + }, + ), // const SizedBox( // height: 12, // ), @@ -461,3 +549,38 @@ class HiddenSettings extends StatelessWidget { ); } } + +const _CHARSET_INVERSE_INDEX = { + 'q': 0, + 'p': 1, + 'z': 2, + 'r': 3, + 'y': 4, + '9': 5, + 'x': 6, + '8': 7, + 'g': 8, + 'f': 9, + '2': 10, + 't': 11, + 'v': 12, + 'd': 13, + 'w': 14, + '0': 15, + 's': 16, + '3': 17, + 'j': 18, + 'n': 19, + '5': 20, + '4': 21, + 'k': 22, + 'h': 23, + 'c': 24, + 'e': 25, + '6': 26, + 'm': 27, + 'u': 28, + 'a': 29, + '7': 30, + 'l': 31, +}; From 67cd3e5948bee60e013fa5021fc0d046628c0a6e Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 16 Oct 2023 14:46:45 -0500 Subject: [PATCH 213/379] pass in a custom FusionParams from _serverTerm and _portTerm --- fusiondart | 2 +- lib/pages/cashfusion/cashfusion_view.dart | 5 +++-- .../cashfusion/desktop_cashfusion_view.dart | 4 +++- lib/services/mixins/fusion_wallet_interface.dart | 14 ++++++++++++-- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/fusiondart b/fusiondart index d371eb264..7ebd6daa3 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit d371eb2643493f78fa5583f1dc41d2c988bf9e28 +Subproject commit 7ebd6daa321867acebcc6adb8107c1322c03f3e7 diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 560e17c08..22c0d42fb 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -47,7 +47,6 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { String _serverTerm = ""; String _portTerm = ""; - int? port; late bool enableSSLCheckbox; FusionOption _option = FusionOption.continuous; @@ -265,7 +264,9 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { .read(walletsChangeNotifierProvider) .getManager(widget.walletId) .wallet as FusionWalletInterface) - .fuse() + .fuse( + serverHost: _serverTerm, + serverPort: int.parse(_portTerm)) }, ), ], diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 93c6dfab6..f1a4d8f63 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -647,7 +647,9 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { } } - unawaited(fusionWallet.fuse()); + unawaited(fusionWallet.fuse( + serverHost: _serverTerm, + serverPort: int.parse(_portTerm))); // unawaited(fusionWallet.stepThruUiStates()); await showDialog<void>( diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index a66e5e0c1..b98de4573 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -292,9 +292,19 @@ mixin FusionWalletInterface { /// Fuse the wallet's UTXOs. /// /// This function is called when the user taps the "Fuse" button in the UI. - Future<void> fuse() async { + Future<void> fuse( + {required String serverHost, required int serverPort}) async { // Initial attempt for CashFusion integration goes here. - final mainFusionObject = fusion.Fusion(fusion.FusionParams()); + + // Use server host and port which ultimately come from text fields. + // TODO validate. + fusion.FusionParams serverParams = fusion.FusionParams( + serverHost: serverHost, + serverPort: serverPort, + ); + + // Instantiate a Fusion object with custom parameters. + final mainFusionObject = fusion.Fusion(serverParams); // Pass wallet functions to the Fusion object await mainFusionObject.initFusion( From a0e2456cf235a46619929bd4a319029354a703b1 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 13:49:50 -0600 Subject: [PATCH 214/379] ssl checkbox --- lib/pages/cashfusion/cashfusion_view.dart | 45 ++++++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 22c0d42fb..43f0afae3 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -47,7 +47,7 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { String _serverTerm = ""; String _portTerm = ""; - late bool enableSSLCheckbox; + bool _enableSSLCheckbox = false; FusionOption _option = FusionOption.continuous; @@ -187,10 +187,44 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { const SizedBox( height: 10, ), - Checkbox( - value: true, - onChanged: (_) {}, - ), // TODO replace placholder Checkbox + GestureDetector( + onTap: () { + setState(() { + _enableSSLCheckbox = !_enableSSLCheckbox; + }); + }, + child: Container( + color: Colors.transparent, + child: Row( + children: [ + SizedBox( + width: 20, + height: 20, + child: Checkbox( + materialTapTargetSize: + MaterialTapTargetSize.shrinkWrap, + value: _enableSSLCheckbox, + onChanged: (newValue) { + setState( + () { + _enableSSLCheckbox = + !_enableSSLCheckbox; + }, + ); + }, + ), + ), + const SizedBox( + width: 12, + ), + Text( + "Use SSL", + style: STextStyles.itemSubtitle12(context), + ), + ], + ), + ), + ), const SizedBox( height: 16, ), @@ -255,7 +289,6 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { const SizedBox( height: 16, ), - const Spacer(), PrimaryButton( label: "Start", From 849303f9a7949f2ddef61eb0a26f6241d4db872d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 13:51:08 -0600 Subject: [PATCH 215/379] add super.init --- lib/pages/cashfusion/cashfusion_view.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 43f0afae3..64894f4cd 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -53,6 +53,7 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { @override void initState() { + super.initState(); serverController = TextEditingController(); portController = TextEditingController(); From a7b2ec08d3b3257870cfe3eadd8c6c429fb9b4d7 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 16 Oct 2023 14:58:29 -0500 Subject: [PATCH 216/379] add serverSsl param --- lib/services/mixins/fusion_wallet_interface.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index b98de4573..ada5edc2f 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -293,15 +293,15 @@ mixin FusionWalletInterface { /// /// This function is called when the user taps the "Fuse" button in the UI. Future<void> fuse( - {required String serverHost, required int serverPort}) async { + {required String serverHost, + required int serverPort, + required bool serverSsl}) async { // Initial attempt for CashFusion integration goes here. // Use server host and port which ultimately come from text fields. // TODO validate. fusion.FusionParams serverParams = fusion.FusionParams( - serverHost: serverHost, - serverPort: serverPort, - ); + serverHost: serverHost, serverPort: serverPort, serverSsl: serverSsl); // Instantiate a Fusion object with custom parameters. final mainFusionObject = fusion.Fusion(serverParams); From 77d1d53866108aba911ec50fbc01dcfe7aa00d21 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 16 Oct 2023 14:59:11 -0500 Subject: [PATCH 217/379] pass values from form in to fuse() --- lib/pages/cashfusion/cashfusion_view.dart | 6 ++++-- .../cashfusion/desktop_cashfusion_view.dart | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 64894f4cd..c5cac8c6b 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -299,8 +299,10 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { .getManager(widget.walletId) .wallet as FusionWalletInterface) .fuse( - serverHost: _serverTerm, - serverPort: int.parse(_portTerm)) + serverHost: _serverTerm, + serverPort: int.parse(_portTerm), + serverSsl: _enableSSLCheckbox, + ) }, ), ], diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index f1a4d8f63..07c936afe 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -648,8 +648,10 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { } unawaited(fusionWallet.fuse( - serverHost: _serverTerm, - serverPort: int.parse(_portTerm))); + serverHost: _serverTerm, + serverPort: int.parse(_portTerm), + serverSsl: _useSSL, + )); // unawaited(fusionWallet.stepThruUiStates()); await showDialog<void>( From cfa4a46fee7e1d2399151f8edc958249d83117f2 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 14:01:26 -0600 Subject: [PATCH 218/379] desktop fusion port digits only filter --- .../cashfusion/desktop_cashfusion_view.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 07c936afe..61ba12efa 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -14,6 +14,7 @@ import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:event_bus/event_bus.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_native_splash/cli_commands.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; @@ -407,6 +408,9 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { enableSuggestions: false, controller: portController, focusNode: portFocusNode, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], onChanged: (value) { setState(() { _portTerm = value; From 6c993e6cbc132bdc7e748faf245b658f1e4af6c8 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 14:01:42 -0600 Subject: [PATCH 219/379] mobile fusion port digits only filter and rounded textfields --- lib/pages/cashfusion/cashfusion_view.dart | 52 ++++++++++++++--------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index c5cac8c6b..e4cfe276a 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -9,6 +9,7 @@ */ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_native_splash/cli_commands.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; @@ -17,6 +18,7 @@ import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; @@ -145,7 +147,11 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { const SizedBox( height: 12, ), - TextField( + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( autocorrect: false, enableSuggestions: false, controller: serverController, @@ -161,28 +167,36 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { serverFocusNode, context, desktopMed: true, - ) - // .copyWith(labelStyle: ), ), + ), + ), const SizedBox( height: 10, ), - TextField( - autocorrect: false, - enableSuggestions: false, - controller: portController, - focusNode: portFocusNode, - onChanged: (value) { - setState(() { - _portTerm = value; - }); - }, - style: STextStyles.field(context), - decoration: standardInputDecoration( - "Port", - portFocusNode, - context, - desktopMed: true, + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: false, + enableSuggestions: false, + controller: portController, + focusNode: portFocusNode, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + keyboardType: TextInputType.number, + onChanged: (value) { + setState(() { + _portTerm = value; + }); + }, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "Port", + portFocusNode, + context, + ), ), ), const SizedBox( From 6351e473844d71336ea45435864084ca9c1e795d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 14:15:55 -0600 Subject: [PATCH 220/379] remove tor from desktop and clean up --- lib/pages/cashfusion/cashfusion_view.dart | 54 +++-- .../cashfusion/desktop_cashfusion_view.dart | 184 ++---------------- 2 files changed, 60 insertions(+), 178 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index e4cfe276a..03ffc1227 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -8,12 +8,15 @@ * */ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_native_splash/cli_commands.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/pages/cashfusion/fusion_rounds_selection_sheet.dart'; +import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; @@ -47,20 +50,25 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { late final TextEditingController portController; late final FocusNode portFocusNode; - String _serverTerm = ""; - String _portTerm = ""; bool _enableSSLCheckbox = false; + bool _enableStartButton = false; FusionOption _option = FusionOption.continuous; @override void initState() { - super.initState(); serverController = TextEditingController(); portController = TextEditingController(); serverFocusNode = FocusNode(); portFocusNode = FocusNode(); + + // TODO set controller text values to saved info + + _enableStartButton = + serverController.text.isNotEmpty && portController.text.isNotEmpty; + + super.initState(); } @override @@ -158,7 +166,8 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { focusNode: serverFocusNode, onChanged: (value) { setState(() { - _serverTerm = value; + _enableStartButton = value.isNotEmpty & + portController.text.isNotEmpty; }); }, style: STextStyles.field(context), @@ -188,7 +197,8 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { keyboardType: TextInputType.number, onChanged: (value) { setState(() { - _portTerm = value; + _enableStartButton = value.isNotEmpty & + serverController.text.isNotEmpty; }); }, style: STextStyles.field(context), @@ -307,16 +317,32 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { const Spacer(), PrimaryButton( label: "Start", - onPressed: () => { - (ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface) - .fuse( - serverHost: _serverTerm, - serverPort: int.parse(_portTerm), + enabled: _enableStartButton, + onPressed: () async { + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + try { + fusionWallet.uiState = ref.read( + fusionProgressUIStateProvider( + widget.walletId), + ); + } catch (e) { + if (!e.toString().contains( + "FusionProgressUIState was already set for ${widget.walletId}")) { + rethrow; + } + } + + unawaited(fusionWallet.fuse( + serverHost: serverController.text, + serverPort: int.parse(portController.text), serverSsl: _enableSSLCheckbox, - ) + )); + + // TODO: navigate to progress screen }, ), ], diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 61ba12efa..67d3a6ae2 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -11,24 +11,18 @@ import 'dart:async'; import 'package:dropdown_button2/dropdown_button2.dart'; -import 'package:event_bus/event_bus.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_native_splash/cli_commands.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/pages/cashfusion/fusion_rounds_selection_sheet.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; -import 'package:stackwallet/pages_desktop_specific/desktop_menu.dart'; -import 'package:stackwallet/pages_desktop_specific/settings/settings_menu.dart'; import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; -import 'package:stackwallet/providers/desktop/current_desktop_menu_item.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/providers/ui/check_box_state_provider.dart'; -import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart'; -import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; -import 'package:stackwallet/services/tor_service.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; @@ -42,11 +36,6 @@ import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/stack_text_field.dart'; -enum FusionRounds { - Continuous, - Custom; -} - class DesktopCashFusionView extends ConsumerStatefulWidget { const DesktopCashFusionView({ super.key, @@ -69,78 +58,11 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { late final TextEditingController fusionRoundController; late final FocusNode fusionRoundFocusNode; - String _serverTerm = ""; - String _portTerm = ""; String _fusionRoundTerm = ""; - bool _useSSL = false; - bool _trusted = false; - int? port; - late bool enableSSLCheckbox; - late final bool enableAuthFields; + bool _enableStartButton = false; - FusionRounds _roundType = FusionRounds.Continuous; - - /// The global event bus. - late final EventBus eventBus; - - /// The subscription to the TorConnectionStatusChangedEvent. - late final StreamSubscription<TorConnectionStatusChangedEvent> - _torConnectionStatusSubscription; - - /// The current status of the Tor connection. - late TorConnectionStatus _torConnectionStatus = - TorConnectionStatus.disconnected; - - /// Build the connect/disconnect button - /// pushes to Tor settings - Widget _buildConnectButton(TorConnectionStatus status) { - switch (status) { - case TorConnectionStatus.disconnected: - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: () { - ref.read(currentDesktopMenuItemProvider.state).state = - DesktopMenuItemId.settings; - ref.watch(selectedSettingsMenuItemStateProvider.state).state = 4; - }, - child: Text( - "Connect", - style: STextStyles.richLink(context).copyWith( - fontSize: 14, - ), - ), - ), - ); - case TorConnectionStatus.connecting: - return AbsorbPointer( - child: Text( - "Connecting", - style: STextStyles.richLink(context).copyWith( - fontSize: 14, - ), - ), - ); - case TorConnectionStatus.connected: - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( - onTap: () { - ref.read(currentDesktopMenuItemProvider.state).state = - DesktopMenuItemId.settings; - ref.watch(selectedSettingsMenuItemStateProvider.state).state = 4; - }, - child: Text( - "Disconnect", - style: STextStyles.richLink(context).copyWith( - fontSize: 14, - ), - ), - ), - ); - } - } + FusionOption _roundType = FusionOption.continuous; @override void initState() { @@ -152,24 +74,10 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { portFocusNode = FocusNode(); fusionRoundFocusNode = FocusNode(); - enableSSLCheckbox = true; + // TODO set controller text values to saved info - // Initialize the global event bus. - eventBus = GlobalEventBus.instance; - - // Initialize the TorConnectionStatus. - _torConnectionStatus = ref.read(pTorService).status; - - // Subscribe to the TorConnectionStatusChangedEvent. - _torConnectionStatusSubscription = - eventBus.on<TorConnectionStatusChangedEvent>().listen( - (event) async { - // Rebuild the widget. - setState(() { - _torConnectionStatus = event.newStatus; - }); - }, - ); + _enableStartButton = + serverController.text.isNotEmpty && portController.text.isNotEmpty; super.initState(); } @@ -383,7 +291,8 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { focusNode: serverFocusNode, onChanged: (value) { setState(() { - _serverTerm = value; + _enableStartButton = value.isNotEmpty & + portController.text.isNotEmpty; }); }, style: STextStyles.field(context), @@ -413,7 +322,8 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { ], onChanged: (value) { setState(() { - _portTerm = value; + _enableStartButton = value.isNotEmpty & + serverController.text.isNotEmpty; }); }, style: STextStyles.field(context), @@ -443,12 +353,6 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { width: 20, height: 20, child: Checkbox( - // fillColor: enableSSLCheckbox - // ? null - // : MaterialStateProperty.all( - // Theme.of(context) - // .extension<StackColors>()! - // .checkboxBGDisabled), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, value: ref @@ -484,14 +388,14 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { height: 10, ), DropdownButtonHideUnderline( - child: DropdownButton2<FusionRounds>( + child: DropdownButton2<FusionOption>( value: _roundType, items: [ - ...FusionRounds.values.map( + ...FusionOption.values.map( (e) => DropdownMenuItem( value: e, child: Text( - e.name, + e.name.capitalize(), style: STextStyles.smallMed14(context) .copyWith( color: Theme.of(context) @@ -503,7 +407,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { ), ], onChanged: (value) { - if (value is FusionRounds) { + if (value is FusionOption) { setState(() { _roundType = value; }); @@ -540,11 +444,11 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { ), ), ), - if (_roundType == FusionRounds.Custom) + if (_roundType == FusionOption.custom) const SizedBox( height: 10, ), - if (_roundType == FusionRounds.Custom) + if (_roundType == FusionOption.custom) SizedBox( width: 460, child: RoundedWhiteContainer( @@ -583,57 +487,9 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { const SizedBox( height: 20, ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Tor status", - style: STextStyles.desktopTextExtraExtraSmall( - context), - ), - _buildConnectButton(_torConnectionStatus), - ], - ), - const SizedBox( - height: 10, - ), - RoundedWhiteContainer( - borderColor: Theme.of(context) - .extension<StackColors>()! - .shadow, - child: Row( - children: [ - SvgPicture.asset( - Assets.svg.circleTor, - width: 48, - height: 48, - ), - const SizedBox( - width: 10, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Tor Network", - style: STextStyles.itemSubtitle12(context), - ), - const SizedBox( - height: 4, - ), - Text(_torConnectionStatus.name.capitalize(), - style: STextStyles - .desktopTextExtraExtraSmall(context)), - ], - ) - ], - ), - ), - const SizedBox( - height: 20, - ), PrimaryButton( label: "Start", + enabled: _enableStartButton, onPressed: () async { final fusionWallet = ref .read(walletsChangeNotifierProvider) @@ -652,9 +508,9 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { } unawaited(fusionWallet.fuse( - serverHost: _serverTerm, - serverPort: int.parse(_portTerm), - serverSsl: _useSSL, + serverHost: serverController.text, + serverPort: int.parse(portController.text), + serverSsl: ref.read(checkBoxStateProvider), )); // unawaited(fusionWallet.stepThruUiStates()); From a4c1814224a932ded88773208571edf7dcad9658 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 16 Oct 2023 15:55:08 -0500 Subject: [PATCH 221/379] add roundCount param to FusionParams --- fusiondart | 2 +- lib/pages/cashfusion/cashfusion_view.dart | 1 + .../cashfusion/desktop_cashfusion_view.dart | 1 + lib/services/mixins/fusion_wallet_interface.dart | 5 +++-- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/fusiondart b/fusiondart index 7ebd6daa3..1e291d807 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 7ebd6daa321867acebcc6adb8107c1322c03f3e7 +Subproject commit 1e291d807c3fa9d9287007588cd3bbfa45875b30 diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 03ffc1227..f17ddaefc 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -340,6 +340,7 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { serverHost: serverController.text, serverPort: int.parse(portController.text), serverSsl: _enableSSLCheckbox, + roundCount: 0, // TODO update fusion rounds. )); // TODO: navigate to progress screen diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 67d3a6ae2..c5f17cc34 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -511,6 +511,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { serverHost: serverController.text, serverPort: int.parse(portController.text), serverSsl: ref.read(checkBoxStateProvider), + roundCount: 0, // TODO update fusion rounds. )); // unawaited(fusionWallet.stepThruUiStates()); diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index ada5edc2f..8931a45ff 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -295,13 +295,14 @@ mixin FusionWalletInterface { Future<void> fuse( {required String serverHost, required int serverPort, - required bool serverSsl}) async { + required bool serverSsl, + required int roundCount}) async { // Initial attempt for CashFusion integration goes here. // Use server host and port which ultimately come from text fields. // TODO validate. fusion.FusionParams serverParams = fusion.FusionParams( - serverHost: serverHost, serverPort: serverPort, serverSsl: serverSsl); + serverHost: serverHost, serverPort: serverPort, serverSsl: serverSsl, roundCount: roundCount); // Instantiate a Fusion object with custom parameters. final mainFusionObject = fusion.Fusion(serverParams); From c54b4d39d3fbc1121cbb7de1285371d85656fb88 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 15:04:27 -0600 Subject: [PATCH 222/379] add persistent fusion server prefs --- lib/pages/cashfusion/cashfusion_view.dart | 86 +++++++++++-- .../cashfusion/desktop_cashfusion_view.dart | 115 +++++++++++------- .../mixins/fusion_wallet_interface.dart | 89 ++++++++++++-- lib/utilities/prefs.dart | 33 +++++ 4 files changed, 262 insertions(+), 61 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index f17ddaefc..0b86db791 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -17,6 +17,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/pages/cashfusion/fusion_rounds_selection_sheet.dart'; import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; +import 'package:stackwallet/providers/global/prefs_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; @@ -49,6 +50,8 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { late final FocusNode serverFocusNode; late final TextEditingController portController; late final FocusNode portFocusNode; + late final TextEditingController fusionRoundController; + late final FocusNode fusionRoundFocusNode; bool _enableSSLCheckbox = false; bool _enableStartButton = false; @@ -59,11 +62,18 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { void initState() { serverController = TextEditingController(); portController = TextEditingController(); + fusionRoundController = TextEditingController(); serverFocusNode = FocusNode(); portFocusNode = FocusNode(); + fusionRoundFocusNode = FocusNode(); - // TODO set controller text values to saved info + final info = ref.read(prefsChangeNotifierProvider).fusionServerInfo; + serverController.text = info.host; + portController.text = info.port.toString(); + _enableSSLCheckbox = info.ssl; + _option = info.rounds == 0 ? FusionOption.continuous : FusionOption.custom; + fusionRoundController.text = info.rounds.toString(); _enableStartButton = serverController.text.isNotEmpty && portController.text.isNotEmpty; @@ -75,9 +85,11 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { void dispose() { serverController.dispose(); portController.dispose(); + fusionRoundController.dispose(); serverFocusNode.dispose(); portFocusNode.dispose(); + fusionRoundFocusNode.dispose(); super.dispose(); } @@ -166,8 +178,9 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { focusNode: serverFocusNode, onChanged: (value) { setState(() { - _enableStartButton = value.isNotEmpty & - portController.text.isNotEmpty; + _enableStartButton = value.isNotEmpty && + portController.text.isNotEmpty && + fusionRoundController.text.isNotEmpty; }); }, style: STextStyles.field(context), @@ -197,8 +210,9 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { keyboardType: TextInputType.number, onChanged: (value) { setState(() { - _enableStartButton = value.isNotEmpty & - serverController.text.isNotEmpty; + _enableStartButton = value.isNotEmpty && + serverController.text.isNotEmpty && + fusionRoundController.text.isNotEmpty; }); }, style: STextStyles.field(context), @@ -311,6 +325,40 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { ), ), ), + if (_option == FusionOption.custom) + const SizedBox( + height: 10, + ), + if (_option == FusionOption.custom) + ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: false, + enableSuggestions: false, + controller: fusionRoundController, + focusNode: fusionRoundFocusNode, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + keyboardType: TextInputType.number, + onChanged: (value) { + setState(() { + _enableStartButton = value.isNotEmpty && + serverController.text.isNotEmpty && + portController.text.isNotEmpty; + }); + }, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "Number of fusions", + fusionRoundFocusNode, + context, + ).copyWith( + labelText: "Enter number of fusions.."), + ), + ), const SizedBox( height: 16, ), @@ -336,12 +384,28 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { } } - unawaited(fusionWallet.fuse( - serverHost: serverController.text, - serverPort: int.parse(portController.text), - serverSsl: _enableSSLCheckbox, - roundCount: 0, // TODO update fusion rounds. - )); + final int rounds = + _option == FusionOption.continuous + ? 0 + : int.parse(fusionRoundController.text); + + final newInfo = FusionInfo( + host: serverController.text, + port: int.parse(portController.text), + ssl: _enableSSLCheckbox, + rounds: rounds, + ); + + // update user prefs (persistent) + ref + .read(prefsChangeNotifierProvider) + .fusionServerInfo = newInfo; + + unawaited( + fusionWallet.fuse( + fusionInfo: newInfo, + ), + ); // TODO: navigate to progress screen }, diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index c5f17cc34..af2ec178e 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -20,8 +20,8 @@ import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/pages/cashfusion/fusion_rounds_selection_sheet.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; +import 'package:stackwallet/providers/global/prefs_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; -import 'package:stackwallet/providers/ui/check_box_state_provider.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; @@ -58,9 +58,8 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { late final TextEditingController fusionRoundController; late final FocusNode fusionRoundFocusNode; - String _fusionRoundTerm = ""; - bool _enableStartButton = false; + bool _enableSSLCheckbox = false; FusionOption _roundType = FusionOption.continuous; @@ -74,7 +73,13 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { portFocusNode = FocusNode(); fusionRoundFocusNode = FocusNode(); - // TODO set controller text values to saved info + final info = ref.read(prefsChangeNotifierProvider).fusionServerInfo; + serverController.text = info.host; + portController.text = info.port.toString(); + _enableSSLCheckbox = info.ssl; + _roundType = + info.rounds == 0 ? FusionOption.continuous : FusionOption.custom; + fusionRoundController.text = info.rounds.toString(); _enableStartButton = serverController.text.isNotEmpty && portController.text.isNotEmpty; @@ -285,25 +290,25 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { Constants.size.circularBorderRadius, ), child: TextField( - autocorrect: false, - enableSuggestions: false, - controller: serverController, - focusNode: serverFocusNode, - onChanged: (value) { - setState(() { - _enableStartButton = value.isNotEmpty & - portController.text.isNotEmpty; - }); - }, - style: STextStyles.field(context), - decoration: standardInputDecoration( - "Server", - serverFocusNode, - context, - desktopMed: true, - ) - // .copyWith(labelStyle: ), - ), + autocorrect: false, + enableSuggestions: false, + controller: serverController, + focusNode: serverFocusNode, + onChanged: (value) { + setState(() { + _enableStartButton = value.isNotEmpty && + portController.text.isNotEmpty && + fusionRoundController.text.isNotEmpty; + }); + }, + style: STextStyles.field(context), + decoration: standardInputDecoration( + "Server", + serverFocusNode, + context, + desktopMed: true, + ), + ), ), const SizedBox( height: 12, @@ -322,8 +327,9 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { ], onChanged: (value) { setState(() { - _enableStartButton = value.isNotEmpty & - serverController.text.isNotEmpty; + _enableStartButton = value.isNotEmpty && + serverController.text.isNotEmpty && + fusionRoundController.text.isNotEmpty; }); }, style: STextStyles.field(context), @@ -340,10 +346,9 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { ), GestureDetector( onTap: () { - final value = - ref.read(checkBoxStateProvider.state).state; - ref.read(checkBoxStateProvider.state).state = - !value; + setState(() { + _enableSSLCheckbox = !_enableSSLCheckbox; + }); }, child: Container( color: Colors.transparent, @@ -355,13 +360,14 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { child: Checkbox( materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - value: ref - .watch(checkBoxStateProvider.state) - .state, + value: _enableSSLCheckbox, onChanged: (newValue) { - ref - .watch(checkBoxStateProvider.state) - .state = newValue!; + setState( + () { + _enableSSLCheckbox = + !_enableSSLCheckbox; + }, + ); }, ), ), @@ -464,14 +470,21 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { enableSuggestions: false, controller: fusionRoundController, focusNode: fusionRoundFocusNode, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], onChanged: (value) { setState(() { - _fusionRoundTerm = value; + _enableStartButton = value + .isNotEmpty && + serverController + .text.isNotEmpty && + portController.text.isNotEmpty; }); }, style: STextStyles.field(context), decoration: standardInputDecoration( - "", + "Number of fusions", fusionRoundFocusNode, context, desktopMed: true, @@ -507,12 +520,28 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { } } - unawaited(fusionWallet.fuse( - serverHost: serverController.text, - serverPort: int.parse(portController.text), - serverSsl: ref.read(checkBoxStateProvider), - roundCount: 0, // TODO update fusion rounds. - )); + final int rounds = + _roundType == FusionOption.continuous + ? 0 + : int.parse(fusionRoundController.text); + + final newInfo = FusionInfo( + host: serverController.text, + port: int.parse(portController.text), + ssl: _enableSSLCheckbox, + rounds: rounds, + ); + + // update user prefs (persistent) + ref + .read(prefsChangeNotifierProvider) + .fusionServerInfo = newInfo; + + unawaited( + fusionWallet.fuse( + fusionInfo: newInfo, + ), + ); // unawaited(fusionWallet.stepThruUiStates()); await showDialog<void>( diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 8931a45ff..ea12faf70 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; @@ -19,6 +20,77 @@ import 'package:stackwallet/utilities/stack_file_system.dart'; const String kReservedFusionAddress = "reserved_fusion_address"; +class FusionInfo { + final String host; + final int port; + final bool ssl; + + /// set to 0 for continuous + final int rounds; + + const FusionInfo({ + required this.host, + required this.port, + required this.ssl, + required this.rounds, + }) : assert(rounds >= 0); + + // TODO update defaults + static const DEFAULTS = FusionInfo( + host: "cashfusion.stackwallet.com", + port: 8787, + ssl: false, + rounds: 0, // 0 is continuous + ); + + factory FusionInfo.fromJsonString(String jsonString) { + final json = jsonDecode(jsonString); + return FusionInfo( + host: json['host'] as String, + port: json['port'] as int, + ssl: json['ssl'] as bool, + rounds: json['rounds'] as int, + ); + } + + String toJsonString() { + return { + 'host': host, + 'port': port, + 'ssl': ssl, + 'rounds': rounds, + }.toString(); + } + + @override + String toString() { + return toJsonString(); + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) { + return true; + } + + return other is FusionInfo && + other.host == host && + other.port == port && + other.ssl == ssl && + other.rounds == rounds; + } + + @override + int get hashCode { + return Object.hash( + host.hashCode, + port.hashCode, + ssl.hashCode, + rounds.hashCode, + ); + } +} + /// A mixin for the BitcoinCashWallet class that adds CashFusion functionality. mixin FusionWalletInterface { // Passed in wallet data. @@ -292,17 +364,20 @@ mixin FusionWalletInterface { /// Fuse the wallet's UTXOs. /// /// This function is called when the user taps the "Fuse" button in the UI. - Future<void> fuse( - {required String serverHost, - required int serverPort, - required bool serverSsl, - required int roundCount}) async { + Future<void> fuse({ + required FusionInfo fusionInfo, + }) async { // Initial attempt for CashFusion integration goes here. // Use server host and port which ultimately come from text fields. - // TODO validate. fusion.FusionParams serverParams = fusion.FusionParams( - serverHost: serverHost, serverPort: serverPort, serverSsl: serverSsl, roundCount: roundCount); + serverHost: fusionInfo.host, + serverPort: fusionInfo.port, + serverSsl: fusionInfo.ssl, + ); + + // TODO use as required. Zero indicates continuous + final roundCount = fusionInfo.rounds; // Instantiate a Fusion object with custom parameters. final mainFusionObject = fusion.Fusion(serverParams); diff --git a/lib/utilities/prefs.dart b/lib/utilities/prefs.dart index 583d9804b..4dcd9a65d 100644 --- a/lib/utilities/prefs.dart +++ b/lib/utilities/prefs.dart @@ -12,6 +12,7 @@ import 'package:flutter/cupertino.dart'; import 'package:stackwallet/db/hive/db.dart'; import 'package:stackwallet/services/event_bus/events/global/tor_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart'; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/utilities/amount/amount_unit.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart'; @@ -64,6 +65,7 @@ class Prefs extends ChangeNotifier { await _setAmountUnits(); await _setMaxDecimals(); _useTor = await _getUseTor(); + _fusionServerInfo = await _getFusionServerInfo(); _initialized = true; } @@ -931,4 +933,35 @@ class Prefs extends ChangeNotifier { ) as bool? ?? false; } + + // fusion server info + + FusionInfo _fusionServerInfo = FusionInfo.DEFAULTS; + + FusionInfo get fusionServerInfo => _fusionServerInfo; + + set fusionServerInfo(FusionInfo fusionServerInfo) { + if (this.fusionServerInfo != fusionServerInfo) { + DB.instance.put<dynamic>( + boxName: DB.boxNamePrefs, + key: "fusionServerInfo", + value: fusionServerInfo.toJsonString(), + ); + _fusionServerInfo = fusionServerInfo; + notifyListeners(); + } + } + + Future<FusionInfo> _getFusionServerInfo() async { + final saved = await DB.instance.get<dynamic>( + boxName: DB.boxNamePrefs, + key: "fusionServerInfo", + ) as String?; + + if (saved == null) { + return FusionInfo.DEFAULTS; + } else { + return FusionInfo.fromJsonString(saved); + } + } } From 1b868426f94c25950973e7f166e88e6b613fb1d9 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 15:28:09 -0600 Subject: [PATCH 223/379] WIP mobile fusion progress view --- lib/pages/cashfusion/cashfusion_view.dart | 6 +- .../cashfusion/fusion_progress_view.dart | 370 ++++++++++++++++++ .../cashfusion/sub_widgets/fusion_dialog.dart | 2 +- lib/route_generator.dart | 15 + 4 files changed, 391 insertions(+), 2 deletions(-) create mode 100644 lib/pages/cashfusion/fusion_progress_view.dart diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 0b86db791..354b6377e 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -15,6 +15,7 @@ import 'package:flutter/services.dart'; import 'package:flutter_native_splash/cli_commands.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/pages/cashfusion/fusion_progress_view.dart'; import 'package:stackwallet/pages/cashfusion/fusion_rounds_selection_sheet.dart'; import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; import 'package:stackwallet/providers/global/prefs_provider.dart'; @@ -407,7 +408,10 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { ), ); - // TODO: navigate to progress screen + await Navigator.of(context).pushNamed( + FusionProgressView.routeName, + arguments: widget.walletId, + ); }, ), ], diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart new file mode 100644 index 000000000..d061e6674 --- /dev/null +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -0,0 +1,370 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by julian on 2023-10-16 + * + */ + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_item_card.dart'; +import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; +import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/widgets/background.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/rounded_container.dart'; + +class FusionProgressView extends StatefulWidget { + const FusionProgressView({ + super.key, + required this.walletId, + }); + + static const routeName = "/cashFusionProgressView"; + + final String walletId; + + @override + State<FusionProgressView> createState() => _FusionProgressViewState(); +} + +class _FusionProgressViewState extends State<FusionProgressView> { + Widget _getIconForState(CashFusionStatus state) { + switch (state) { + case CashFusionStatus.waiting: + return SvgPicture.asset( + Assets.svg.loader, + color: + Theme.of(context).extension<StackColors>()!.buttonBackSecondary, + ); + case CashFusionStatus.running: + return SvgPicture.asset( + Assets.svg.loader, + color: Theme.of(context).extension<StackColors>()!.accentColorGreen, + ); + case CashFusionStatus.success: + return SvgPicture.asset( + Assets.svg.checkCircle, + color: Theme.of(context).extension<StackColors>()!.accentColorGreen, + ); + case CashFusionStatus.failed: + return SvgPicture.asset( + Assets.svg.circleAlert, + color: Theme.of(context).extension<StackColors>()!.textError, + ); + } + } + + /// return true on will cancel, false if cancel cancelled + Future<bool> _requestCancel() async { + // + + return false; + } + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () async { + return await _requestCancel(); + }, + child: Background( + child: SafeArea( + child: Scaffold( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + appBar: AppBar( + automaticallyImplyLeading: false, + leading: AppBarBackButton( + onPressed: () async { + if (await _requestCancel()) { + if (mounted) { + Navigator.of(context).pop(); + } + } + }, + ), + title: Text( + "Fusion progress", + style: STextStyles.navBarTitle(context), + ), + titleSpacing: 0, + ), + body: LayoutBuilder( + builder: (builderContext, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: IntrinsicHeight( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + children: [ + RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackError, + child: Text( + "Do not close this window. If you exit, " + "the process will be canceled.", + style: STextStyles.smallMed14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextError, + ), + textAlign: TextAlign.center, + ), + ), + const SizedBox( + height: 20, + ), + Consumer( + builder: (_, ref, __) { + final state = ref.watch( + fusionProgressUIStateProvider( + widget.walletId) + .select((value) => value.connecting)); + return RoundedContainer( + padding: EdgeInsets.zero, + color: Theme.of(context) + .extension<StackColors>()! + .popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.node, + width: 16, + height: 16, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Connecting to server", + ), + ); + }, + ), + const SizedBox( + height: 12, + ), + Consumer(builder: (_, ref, __) { + final state = ref.watch( + fusionProgressUIStateProvider(widget.walletId) + .select((value) => value.outputs)); + return RoundedContainer( + padding: EdgeInsets.zero, + color: Theme.of(context) + .extension<StackColors>()! + .popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.upFromLine, + width: 18, + height: 18, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Allocating outputs", + ), + ); + }), + const SizedBox( + height: 12, + ), + Consumer(builder: (_, ref, __) { + final state = ref.watch( + fusionProgressUIStateProvider(widget.walletId) + .select((value) => value.peers)); + return RoundedContainer( + padding: EdgeInsets.zero, + color: Theme.of(context) + .extension<StackColors>()! + .popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.peers, + width: 20, + height: 20, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Waiting for peers", + ), + ); + }), + const SizedBox( + height: 12, + ), + Consumer(builder: (_, ref, __) { + final state = ref.watch( + fusionProgressUIStateProvider(widget.walletId) + .select((value) => value.fusing)); + return RoundedContainer( + padding: EdgeInsets.zero, + color: Theme.of(context) + .extension<StackColors>()! + .popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .background, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.fusing, + width: 20, + height: 20, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Fusing", + ), + ); + }), + const SizedBox( + height: 12, + ), + Consumer(builder: (_, ref, __) { + final state = ref.watch( + fusionProgressUIStateProvider(widget.walletId) + .select((value) => value.complete)); + return RoundedContainer( + padding: EdgeInsets.zero, + color: Theme.of(context) + .extension<StackColors>()! + .popupBG, + borderColor: Theme.of(context) + .extension<StackColors>()! + .shadow, + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: Theme.of(context) + .extension<StackColors>()! + .buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + Assets.svg.checkCircle, + width: 18, + height: 18, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(state), + ), + title: "Complete", + ), + ); + }), + const Spacer(), + const SizedBox( + height: 16, + ), + // TODO: various button states + // tempt only show cancel button + SecondaryButton( + label: "Cancel", + onPressed: () async { + if (await _requestCancel()) { + if (mounted) { + Navigator.of(context).pop(); + } + } + }, + ), + ], + ), + ), + ), + ), + ); + }, + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index ac3a115d8..caf2bcf2b 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -96,7 +96,7 @@ class FusionDialog extends StatelessWidget { style: STextStyles.smallMed14(context).copyWith( color: Theme.of(context) .extension<StackColors>()! - .textDark, + .snackBarTextError, ), ), ], diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 4c52bc236..1f1eb9fe8 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -45,6 +45,7 @@ import 'package:stackwallet/pages/buy_view/buy_in_wallet_view.dart'; import 'package:stackwallet/pages/buy_view/buy_quote_preview.dart'; import 'package:stackwallet/pages/buy_view/buy_view.dart'; import 'package:stackwallet/pages/cashfusion/cashfusion_view.dart'; +import 'package:stackwallet/pages/cashfusion/fusion_progress_view.dart'; import 'package:stackwallet/pages/coin_control/coin_control_view.dart'; import 'package:stackwallet/pages/coin_control/utxo_details_view.dart'; import 'package:stackwallet/pages/exchange_view/choose_from_stack_view.dart'; @@ -595,6 +596,20 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case FusionProgressView.routeName: + if (args is String) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => FusionProgressView( + walletId: args, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case DesktopCashFusionView.routeName: if (args is String) { return getRoute( From 26055f402b72b4d16e5b865631b26a52dcc11f1c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 15:31:03 -0600 Subject: [PATCH 224/379] font size fix --- lib/pages/cashfusion/fusion_progress_view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index d061e6674..c487f0465 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -117,7 +117,7 @@ class _FusionProgressViewState extends State<FusionProgressView> { child: Text( "Do not close this window. If you exit, " "the process will be canceled.", - style: STextStyles.smallMed14(context).copyWith( + style: STextStyles.w500_14(context).copyWith( color: Theme.of(context) .extension<StackColors>()! .snackBarTextError, From 98de6dba0182bbc8bd6a35d7504d7ccefc7791d4 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 16:08:15 -0600 Subject: [PATCH 225/379] extract shared code into shared widget --- .../cashfusion/fusion_progress_view.dart | 234 +----------------- .../cashfusion/sub_widgets/fusion_dialog.dart | 229 +---------------- .../sub_widgets/fusion_progress.dart | 162 ++++++++++++ 3 files changed, 168 insertions(+), 457 deletions(-) create mode 100644 lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index c487f0465..93bb88c6e 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -9,18 +9,15 @@ */ import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_item_card.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; -import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; +import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; -import 'package:stackwallet/widgets/rounded_container.dart'; class FusionProgressView extends StatefulWidget { const FusionProgressView({ @@ -110,234 +107,9 @@ class _FusionProgressViewState extends State<FusionProgressView> { padding: const EdgeInsets.all(16), child: Column( children: [ - RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackError, - child: Text( - "Do not close this window. If you exit, " - "the process will be canceled.", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextError, - ), - textAlign: TextAlign.center, - ), + FusionProgress( + walletId: widget.walletId, ), - const SizedBox( - height: 20, - ), - Consumer( - builder: (_, ref, __) { - final state = ref.watch( - fusionProgressUIStateProvider( - widget.walletId) - .select((value) => value.connecting)); - return RoundedContainer( - padding: EdgeInsets.zero, - color: Theme.of(context) - .extension<StackColors>()! - .popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.node, - width: 16, - height: 16, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Connecting to server", - ), - ); - }, - ), - const SizedBox( - height: 12, - ), - Consumer(builder: (_, ref, __) { - final state = ref.watch( - fusionProgressUIStateProvider(widget.walletId) - .select((value) => value.outputs)); - return RoundedContainer( - padding: EdgeInsets.zero, - color: Theme.of(context) - .extension<StackColors>()! - .popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.upFromLine, - width: 18, - height: 18, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Allocating outputs", - ), - ); - }), - const SizedBox( - height: 12, - ), - Consumer(builder: (_, ref, __) { - final state = ref.watch( - fusionProgressUIStateProvider(widget.walletId) - .select((value) => value.peers)); - return RoundedContainer( - padding: EdgeInsets.zero, - color: Theme.of(context) - .extension<StackColors>()! - .popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.peers, - width: 20, - height: 20, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Waiting for peers", - ), - ); - }), - const SizedBox( - height: 12, - ), - Consumer(builder: (_, ref, __) { - final state = ref.watch( - fusionProgressUIStateProvider(widget.walletId) - .select((value) => value.fusing)); - return RoundedContainer( - padding: EdgeInsets.zero, - color: Theme.of(context) - .extension<StackColors>()! - .popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.fusing, - width: 20, - height: 20, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Fusing", - ), - ); - }), - const SizedBox( - height: 12, - ), - Consumer(builder: (_, ref, __) { - final state = ref.watch( - fusionProgressUIStateProvider(widget.walletId) - .select((value) => value.complete)); - return RoundedContainer( - padding: EdgeInsets.zero, - color: Theme.of(context) - .extension<StackColors>()! - .popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .shadow, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.checkCircle, - width: 18, - height: 18, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Complete", - ), - ); - }), const Spacer(), const SizedBox( height: 16, diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index caf2bcf2b..d2e7ef34e 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -1,15 +1,12 @@ import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; -import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_item_card.dart'; -import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; +import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; -import 'package:stackwallet/widgets/rounded_container.dart'; enum CashFusionStatus { waiting, running, success, failed } @@ -83,229 +80,9 @@ class FusionDialog extends StatelessWidget { const SizedBox( height: 20, ), - RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackError, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "Do not close this window. If you exit, " - "the process will be canceled.", - style: STextStyles.smallMed14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextError, - ), - ), - ], - ), + FusionProgress( + walletId: walletId, ), - const SizedBox( - height: 20, - ), - Consumer(builder: (_, ref, __) { - final state = ref.watch( - fusionProgressUIStateProvider(walletId) - .select((value) => value.connecting)); - return RoundedContainer( - padding: EdgeInsets.zero, - color: - Theme.of(context).extension<StackColors>()!.popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.node, - width: 16, - height: 16, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Connecting to server", - ), - ); - }), - const SizedBox( - height: 12, - ), - Consumer(builder: (_, ref, __) { - final state = ref.watch( - fusionProgressUIStateProvider(walletId) - .select((value) => value.outputs)); - return RoundedContainer( - padding: EdgeInsets.zero, - color: - Theme.of(context).extension<StackColors>()!.popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.upFromLine, - width: 30, - height: 30, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Allocating outputs", - ), - ); - }), - const SizedBox( - height: 12, - ), - Consumer(builder: (_, ref, __) { - final state = ref.watch( - fusionProgressUIStateProvider(walletId) - .select((value) => value.peers)); - return RoundedContainer( - padding: EdgeInsets.zero, - color: - Theme.of(context).extension<StackColors>()!.popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.peers, - width: 30, - height: 30, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Waiting for peers", - ), - ); - }), - const SizedBox( - height: 12, - ), - Consumer(builder: (_, ref, __) { - final state = ref.watch( - fusionProgressUIStateProvider(walletId) - .select((value) => value.fusing)); - return RoundedContainer( - padding: EdgeInsets.zero, - color: - Theme.of(context).extension<StackColors>()!.popupBG, - borderColor: Theme.of(context) - .extension<StackColors>()! - .background, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.fusing, - width: 30, - height: 30, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Fusing", - ), - ); - }), - const SizedBox( - height: 12, - ), - Consumer(builder: (_, ref, __) { - final state = ref.watch( - fusionProgressUIStateProvider(walletId) - .select((value) => value.complete)); - return RoundedContainer( - padding: EdgeInsets.zero, - color: - Theme.of(context).extension<StackColors>()!.popupBG, - borderColor: - Theme.of(context).extension<StackColors>()!.shadow, - child: RestoringItemCard( - left: SizedBox( - width: 32, - height: 32, - child: RoundedContainer( - padding: const EdgeInsets.all(0), - color: Theme.of(context) - .extension<StackColors>()! - .buttonBackSecondary, - child: Center( - child: SvgPicture.asset( - Assets.svg.checkCircle, - width: 16, - height: 16, - ), - ), - ), - ), - right: SizedBox( - width: 20, - height: 20, - child: _getIconForState(state), - ), - title: "Complete", - ), - ); - }), const SizedBox( height: 12, ), diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart new file mode 100644 index 000000000..f3ce1b426 --- /dev/null +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart @@ -0,0 +1,162 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:stackwallet/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_item_card.dart'; +import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; +import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/rounded_container.dart'; + +class FusionProgress extends ConsumerWidget { + const FusionProgress({super.key, required this.walletId}); + + final String walletId; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + RoundedContainer( + color: Theme.of(context).extension<StackColors>()!.snackBarBackError, + child: Text( + "Do not close this window. If you exit, " + "the process will be canceled.", + style: Util.isDesktop + ? STextStyles.smallMed14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextError, + ) + : STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextError, + ), + textAlign: TextAlign.center, + ), + ), + const SizedBox( + height: 20, + ), + _ProgressItem( + iconAsset: Assets.svg.node, + label: "Connecting to server", + status: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.connecting))), + const SizedBox( + height: 12, + ), + _ProgressItem( + iconAsset: Assets.svg.upFromLine, + label: "Allocating outputs", + status: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.outputs))), + const SizedBox( + height: 12, + ), + _ProgressItem( + iconAsset: Assets.svg.peers, + label: "Waiting for peers", + status: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.peers))), + const SizedBox( + height: 12, + ), + _ProgressItem( + iconAsset: Assets.svg.fusing, + label: "Fusing", + status: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.fusing))), + const SizedBox( + height: 12, + ), + _ProgressItem( + iconAsset: Assets.svg.checkCircle, + label: "Complete", + status: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.complete))), + ], + ); + } +} + +class _ProgressItem extends StatelessWidget { + const _ProgressItem({ + super.key, + required this.iconAsset, + required this.label, + required this.status, + }); + + final String iconAsset; + final String label; + final CashFusionStatus status; + + Widget _getIconForState(CashFusionStatus state, BuildContext context) { + switch (state) { + case CashFusionStatus.waiting: + return SvgPicture.asset( + Assets.svg.loader, + color: + Theme.of(context).extension<StackColors>()!.buttonBackSecondary, + ); + case CashFusionStatus.running: + return SvgPicture.asset( + Assets.svg.loader, + color: Theme.of(context).extension<StackColors>()!.accentColorGreen, + ); + case CashFusionStatus.success: + return SvgPicture.asset( + Assets.svg.checkCircle, + color: Theme.of(context).extension<StackColors>()!.accentColorGreen, + ); + case CashFusionStatus.failed: + return SvgPicture.asset( + Assets.svg.circleAlert, + color: Theme.of(context).extension<StackColors>()!.textError, + ); + } + } + + @override + Widget build(BuildContext context) { + return ConditionalParent( + condition: Util.isDesktop, + builder: (child) => RoundedContainer( + padding: EdgeInsets.zero, + color: Theme.of(context).extension<StackColors>()!.popupBG, + borderColor: Theme.of(context).extension<StackColors>()!.background, + child: child, + ), + child: RestoringItemCard( + left: SizedBox( + width: 32, + height: 32, + child: RoundedContainer( + padding: const EdgeInsets.all(0), + color: + Theme.of(context).extension<StackColors>()!.buttonBackSecondary, + child: Center( + child: SvgPicture.asset( + iconAsset, + width: 18, + height: 18, + ), + ), + ), + ), + right: SizedBox( + width: 20, + height: 20, + child: _getIconForState(status, context), + ), + title: label, + ), + ); + } +} From 589bd51e70fd1e93c208fc1fa89448749850bf2d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 16 Oct 2023 16:45:36 -0600 Subject: [PATCH 226/379] clean up unused function --- .../cashfusion/fusion_progress_view.dart | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 93bb88c6e..544088b11 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -9,11 +9,8 @@ */ import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart'; import 'package:stackwallet/themes/stack_colors.dart'; -import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; @@ -34,32 +31,6 @@ class FusionProgressView extends StatefulWidget { } class _FusionProgressViewState extends State<FusionProgressView> { - Widget _getIconForState(CashFusionStatus state) { - switch (state) { - case CashFusionStatus.waiting: - return SvgPicture.asset( - Assets.svg.loader, - color: - Theme.of(context).extension<StackColors>()!.buttonBackSecondary, - ); - case CashFusionStatus.running: - return SvgPicture.asset( - Assets.svg.loader, - color: Theme.of(context).extension<StackColors>()!.accentColorGreen, - ); - case CashFusionStatus.success: - return SvgPicture.asset( - Assets.svg.checkCircle, - color: Theme.of(context).extension<StackColors>()!.accentColorGreen, - ); - case CashFusionStatus.failed: - return SvgPicture.asset( - Assets.svg.circleAlert, - color: Theme.of(context).extension<StackColors>()!.textError, - ); - } - } - /// return true on will cancel, false if cancel cancelled Future<bool> _requestCancel() async { // From aa31f04c20c9ade0c70130b6fcbd117cb6cb4c7d Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 16 Oct 2023 23:00:22 -0500 Subject: [PATCH 227/379] repeated fusion rounds functionality I'd like it to loop until it allocates outputs successfully, but alas, this may not be safe to ignore --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 1e291d807..0d22e933c 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 1e291d807c3fa9d9287007588cd3bbfa45875b30 +Subproject commit 0d22e933ca1cf081262064d3a42f031f5285f77b From 3d72e83d2f99beba2194efe86db95349c3415af4 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 00:00:54 -0500 Subject: [PATCH 228/379] WIP fusion progress error labels --- fusiondart | 2 +- lib/models/fusion_progress_ui_state.dart | 44 +++++++++++++++++++ .../sub_widgets/fusion_progress.dart | 25 ++++++++--- .../mixins/fusion_wallet_interface.dart | 18 +++++--- 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/fusiondart b/fusiondart index 0d22e933c..d93bfccb1 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 0d22e933ca1cf081262064d3a42f031f5285f77b +Subproject commit d93bfccb1ad4d169a27da647c82186bc44de660b diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 09bc81556..b6e05b602 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -83,4 +83,48 @@ class FusionProgressUIState extends ChangeNotifier { _fusionStatus = fusionStatus; notifyListeners(); } + + // Instance variables for info labels on fusion progress steps. + // + // "Connecting to server" + String? _connectionInfo; + String? get connectionInfo => _connectionInfo; + set connectionInfo(String? fusionInfo) { + _connectionInfo = fusionInfo; + notifyListeners(); + } + + // "Allocating outputs" + String? _outputsInfo; + String? get outputsInfo => _outputsInfo; + set outputsInfo(String? fusionInfo) { + _outputsInfo = fusionInfo; + notifyListeners(); + } + + // "Waiting for peers" + String? _peersInfo; + String? get peersInfo => _peersInfo; + set peersInfo(String? fusionInfo) { + _peersInfo = fusionInfo; + notifyListeners(); + } + + // "Fusing" + String? _fusingInfo; + String? get fusingInfo => _fusingInfo; + set fusingInfo(String? fusionInfo) { + _fusingInfo = fusionInfo; + notifyListeners(); + } + + // "Complete" + // + // Should show txId if successful. + String? _completeInfo; + String? get completeInfo => _completeInfo; + set completeInfo(String? fusionInfo) { + _completeInfo = fusionInfo; + notifyListeners(); + } } diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart index f3ce1b426..61b9275c7 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart @@ -47,7 +47,9 @@ class FusionProgress extends ConsumerWidget { iconAsset: Assets.svg.node, label: "Connecting to server", status: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.connecting))), + .select((value) => value.connecting)), + info: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.connectionInfo))), const SizedBox( height: 12, ), @@ -55,7 +57,9 @@ class FusionProgress extends ConsumerWidget { iconAsset: Assets.svg.upFromLine, label: "Allocating outputs", status: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.outputs))), + .select((value) => value.outputs)), + info: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.outputsInfo))), const SizedBox( height: 12, ), @@ -63,7 +67,9 @@ class FusionProgress extends ConsumerWidget { iconAsset: Assets.svg.peers, label: "Waiting for peers", status: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.peers))), + .select((value) => value.peers)), + info: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.peersInfo))), const SizedBox( height: 12, ), @@ -71,7 +77,9 @@ class FusionProgress extends ConsumerWidget { iconAsset: Assets.svg.fusing, label: "Fusing", status: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.fusing))), + .select((value) => value.fusing)), + info: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.fusingInfo))), const SizedBox( height: 12, ), @@ -79,7 +87,9 @@ class FusionProgress extends ConsumerWidget { iconAsset: Assets.svg.checkCircle, label: "Complete", status: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.complete))), + .select((value) => value.complete)), + info: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.completeInfo))), ], ); } @@ -91,11 +101,13 @@ class _ProgressItem extends StatelessWidget { required this.iconAsset, required this.label, required this.status, + this.info, }); final String iconAsset; final String label; final CashFusionStatus status; + final String? info; Widget _getIconForState(CashFusionStatus state, BuildContext context) { switch (state) { @@ -156,6 +168,9 @@ class _ProgressItem extends StatelessWidget { child: _getIconForState(status, context), ), title: label, + subTitle: info != null + ? Text(info!) // TODO style error message eg. red. + : null, ), ); } diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index ea12faf70..699c41439 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -153,8 +153,8 @@ mixin FusionWalletInterface { } // callback to update the ui state object - void _updateStatus(fusion.FusionStatus fusionStatus) { - switch (fusionStatus) { + void _updateStatus({required fusion.FusionStatus status, String? info}) { + switch (status) { case fusion.FusionStatus.connecting: _uiState?.connecting = CashFusionStatus.running; break; @@ -178,13 +178,13 @@ mixin FusionWalletInterface { // _uiState?.fusing = CashFusionStatus.failed; _uiState?.complete = CashFusionStatus.failed; - failCurrentUiState(); + failCurrentUiState(info); break; case fusion.FusionStatus.exception: _uiState?.complete = CashFusionStatus.failed; - failCurrentUiState(); + failCurrentUiState(info); break; case fusion.FusionStatus.reset: _uiState?.outputs = CashFusionStatus.waiting; @@ -197,19 +197,27 @@ mixin FusionWalletInterface { } } - void failCurrentUiState() { + void failCurrentUiState(String? info) { // Check each _uiState value to see if it is running. If so, set it to failed. if (_uiState?.connecting == CashFusionStatus.running) { _uiState?.connecting = CashFusionStatus.failed; + _uiState?.connectionInfo = info; } if (_uiState?.outputs == CashFusionStatus.running) { _uiState?.outputs = CashFusionStatus.failed; + _uiState?.outputsInfo = info; } if (_uiState?.peers == CashFusionStatus.running) { _uiState?.peers = CashFusionStatus.failed; + _uiState?.connectionInfo = info; } if (_uiState?.fusing == CashFusionStatus.running) { _uiState?.fusing = CashFusionStatus.failed; + _uiState?.fusingInfo = info; + } + if (_uiState?.complete == CashFusionStatus.running) { + _uiState?.complete = CashFusionStatus.failed; + _uiState?.completeInfo = info; } } From b949e1e727d41dc9a2c9340deb2d71518692eb75 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 09:08:28 -0600 Subject: [PATCH 229/379] clean up unused function --- .../cashfusion/sub_widgets/fusion_dialog.dart | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index d2e7ef34e..8ca43f8f7 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -1,8 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart'; -import 'package:stackwallet/themes/stack_colors.dart'; -import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; @@ -20,32 +17,6 @@ class FusionDialog extends StatelessWidget { @override Widget build(BuildContext context) { - Widget _getIconForState(CashFusionStatus state) { - switch (state) { - case CashFusionStatus.waiting: - return SvgPicture.asset( - Assets.svg.loader, - color: - Theme.of(context).extension<StackColors>()!.buttonBackSecondary, - ); - case CashFusionStatus.running: - return SvgPicture.asset( - Assets.svg.loader, - color: Theme.of(context).extension<StackColors>()!.accentColorGreen, - ); - case CashFusionStatus.success: - return SvgPicture.asset( - Assets.svg.checkCircle, - color: Theme.of(context).extension<StackColors>()!.accentColorGreen, - ); - case CashFusionStatus.failed: - return SvgPicture.asset( - Assets.svg.circleAlert, - color: Theme.of(context).extension<StackColors>()!.textError, - ); - } - } - return DesktopDialog( maxHeight: 600, child: SingleChildScrollView( From d21964fbdc488793cbf5d42b605849a40a3fa389 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 09:11:49 -0600 Subject: [PATCH 230/379] immutable params properties --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index d93bfccb1..8052be203 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit d93bfccb1ad4d169a27da647c82186bc44de660b +Subproject commit 8052be203d9bf3af1170420177b98c92c481f884 From b87ec27773f5efcc558163be18385ab0fc1fb883 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 09:32:02 -0600 Subject: [PATCH 231/379] error message style --- .../cashfusion/sub_widgets/fusion_progress.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart index 61b9275c7..a5edceafb 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart @@ -169,7 +169,12 @@ class _ProgressItem extends StatelessWidget { ), title: label, subTitle: info != null - ? Text(info!) // TODO style error message eg. red. + ? Text( + info!, + style: STextStyles.w500_12(context).copyWith( + color: Theme.of(context).extension<StackColors>()!.textError, + ), + ) : null, ), ); From 74dbc718befccccf9844b883c741330ab7327d14 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 10:56:37 -0500 Subject: [PATCH 232/379] refactor status to state, a Record containing status and info --- lib/models/fusion_progress_ui_state.dart | 7 ++-- .../sub_widgets/fusion_progress.dart | 42 +++++++------------ 2 files changed, 19 insertions(+), 30 deletions(-) diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index b6e05b602..67bb2f6ca 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -42,9 +42,10 @@ class FusionProgressUIState extends ChangeNotifier { return _succeeded; } - CashFusionStatus _connecting = CashFusionStatus.waiting; - CashFusionStatus get connecting => _connecting; - set connecting(CashFusionStatus state) { + ({CashFusionStatus status, String? info}) _connecting = + (status: CashFusionStatus.waiting, info: null); + ({CashFusionStatus status, String? info}) get connecting => _connecting; + set connecting(({CashFusionStatus status, String? info}) state) { _connecting = state; notifyListeners(); } diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart index a5edceafb..fa1820af5 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart @@ -46,50 +46,40 @@ class FusionProgress extends ConsumerWidget { _ProgressItem( iconAsset: Assets.svg.node, label: "Connecting to server", - status: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.connecting)), - info: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.connectionInfo))), + state: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.connecting))), const SizedBox( height: 12, ), _ProgressItem( iconAsset: Assets.svg.upFromLine, label: "Allocating outputs", - status: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.outputs)), - info: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.outputsInfo))), + state: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.outputs))), const SizedBox( height: 12, ), _ProgressItem( iconAsset: Assets.svg.peers, label: "Waiting for peers", - status: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.peers)), - info: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.peersInfo))), + state: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.peers))), const SizedBox( height: 12, ), _ProgressItem( iconAsset: Assets.svg.fusing, label: "Fusing", - status: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.fusing)), - info: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.fusingInfo))), + state: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.fusing))), const SizedBox( height: 12, ), _ProgressItem( iconAsset: Assets.svg.checkCircle, label: "Complete", - status: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.complete)), - info: ref.watch(fusionProgressUIStateProvider(walletId) - .select((value) => value.completeInfo))), + state: ref.watch(fusionProgressUIStateProvider(walletId) + .select((value) => value.complete))), ], ); } @@ -100,14 +90,12 @@ class _ProgressItem extends StatelessWidget { super.key, required this.iconAsset, required this.label, - required this.status, - this.info, + required this.state, }); final String iconAsset; final String label; - final CashFusionStatus status; - final String? info; + final ({CashFusionStatus status, String? info}) state; Widget _getIconForState(CashFusionStatus state, BuildContext context) { switch (state) { @@ -165,12 +153,12 @@ class _ProgressItem extends StatelessWidget { right: SizedBox( width: 20, height: 20, - child: _getIconForState(status, context), + child: _getIconForState(state.status, context), ), title: label, - subTitle: info != null + subTitle: state.info != null ? Text( - info!, + state.info!, style: STextStyles.w500_12(context).copyWith( color: Theme.of(context).extension<StackColors>()!.textError, ), From 974687e412c17d15d7c3629a3517419be9880277 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 11:15:31 -0500 Subject: [PATCH 233/379] refactor fusion state to remove instance variables for each step --- lib/models/fusion_progress_ui_state.dart | 97 ++++++------------- .../cashfusion/sub_widgets/fusion_dialog.dart | 7 ++ .../sub_widgets/fusion_progress.dart | 2 +- .../mixins/fusion_wallet_interface.dart | 81 ++++++++++------ 4 files changed, 86 insertions(+), 101 deletions(-) diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 67bb2f6ca..55079dda9 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -31,101 +31,62 @@ class FusionProgressUIState extends ChangeNotifier { return false; } - bool _succeeded = _connecting == CashFusionStatus.success; - _succeeded &= _outputs == CashFusionStatus.success; - _succeeded &= _peers == CashFusionStatus.success; - _succeeded &= _fusing == CashFusionStatus.success; - _succeeded &= _complete == CashFusionStatus.success; + bool _succeeded = _connecting.status == CashFusionStatus.success; + _succeeded &= _outputs.status == CashFusionStatus.success; + _succeeded &= _peers.status == CashFusionStatus.success; + _succeeded &= _fusing.status == CashFusionStatus.success; + _succeeded &= _complete.status == CashFusionStatus.success; _succeeded &= fusionState == CashFusionStatus.success; return _succeeded; } - ({CashFusionStatus status, String? info}) _connecting = - (status: CashFusionStatus.waiting, info: null); - ({CashFusionStatus status, String? info}) get connecting => _connecting; - set connecting(({CashFusionStatus status, String? info}) state) { + CashFusionState _connecting = + CashFusionState(status: CashFusionStatus.waiting, info: null); + CashFusionState get connecting => _connecting; + set connecting(CashFusionState state) { _connecting = state; notifyListeners(); } - CashFusionStatus _outputs = CashFusionStatus.waiting; - CashFusionStatus get outputs => _outputs; - set outputs(CashFusionStatus state) { + CashFusionState _outputs = + CashFusionState(status: CashFusionStatus.waiting, info: null); + CashFusionState get outputs => _outputs; + set outputs(CashFusionState state) { _outputs = state; notifyListeners(); } - CashFusionStatus _peers = CashFusionStatus.waiting; - CashFusionStatus get peers => _peers; - set peers(CashFusionStatus state) { + CashFusionState _peers = + CashFusionState(status: CashFusionStatus.waiting, info: null); + CashFusionState get peers => _peers; + set peers(CashFusionState state) { _peers = state; notifyListeners(); } - CashFusionStatus _fusing = CashFusionStatus.waiting; - CashFusionStatus get fusing => _fusing; - set fusing(CashFusionStatus state) { + CashFusionState _fusing = + CashFusionState(status: CashFusionStatus.waiting, info: null); + CashFusionState get fusing => _fusing; + set fusing(CashFusionState state) { _fusing = state; notifyListeners(); } - CashFusionStatus _complete = CashFusionStatus.waiting; - CashFusionStatus get complete => _complete; - set complete(CashFusionStatus state) { + CashFusionState _complete = + CashFusionState(status: CashFusionStatus.waiting, info: null); + CashFusionState get complete => _complete; + set complete(CashFusionState state) { _complete = state; notifyListeners(); } - CashFusionStatus _fusionStatus = CashFusionStatus.waiting; - CashFusionStatus get fusionState => _fusionStatus; - set fusionState(CashFusionStatus fusionStatus) { + CashFusionState _fusionStatus = + CashFusionState(status: CashFusionStatus.waiting, info: null); + CashFusionState get fusionState => _fusionStatus; + set fusionState(CashFusionState fusionStatus) { _fusionStatus = fusionStatus; notifyListeners(); } - - // Instance variables for info labels on fusion progress steps. - // - // "Connecting to server" - String? _connectionInfo; - String? get connectionInfo => _connectionInfo; - set connectionInfo(String? fusionInfo) { - _connectionInfo = fusionInfo; - notifyListeners(); - } - - // "Allocating outputs" - String? _outputsInfo; - String? get outputsInfo => _outputsInfo; - set outputsInfo(String? fusionInfo) { - _outputsInfo = fusionInfo; - notifyListeners(); - } - - // "Waiting for peers" - String? _peersInfo; - String? get peersInfo => _peersInfo; - set peersInfo(String? fusionInfo) { - _peersInfo = fusionInfo; - notifyListeners(); - } - - // "Fusing" - String? _fusingInfo; - String? get fusingInfo => _fusingInfo; - set fusingInfo(String? fusionInfo) { - _fusingInfo = fusionInfo; - notifyListeners(); - } - - // "Complete" - // - // Should show txId if successful. - String? _completeInfo; - String? get completeInfo => _completeInfo; - set completeInfo(String? fusionInfo) { - _completeInfo = fusionInfo; - notifyListeners(); - } } diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 8ca43f8f7..fdc577e96 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -7,6 +7,13 @@ import 'package:stackwallet/widgets/desktop/secondary_button.dart'; enum CashFusionStatus { waiting, running, success, failed } +class CashFusionState { + final CashFusionStatus status; + final String? info; + + CashFusionState({required this.status, this.info}); +} + class FusionDialog extends StatelessWidget { const FusionDialog({ Key? key, diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart index fa1820af5..797fd5761 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart @@ -95,7 +95,7 @@ class _ProgressItem extends StatelessWidget { final String iconAsset; final String label; - final ({CashFusionStatus status, String? info}) state; + final CashFusionState state; Widget _getIconForState(CashFusionStatus state, BuildContext context) { switch (state) { diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 699c41439..ce7759b5f 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -156,68 +156,85 @@ mixin FusionWalletInterface { void _updateStatus({required fusion.FusionStatus status, String? info}) { switch (status) { case fusion.FusionStatus.connecting: - _uiState?.connecting = CashFusionStatus.running; + _uiState?.connecting = + CashFusionState(status: CashFusionStatus.running, info: info); break; case fusion.FusionStatus.setup: - _uiState?.connecting = CashFusionStatus.success; - _uiState?.outputs = CashFusionStatus.running; + _uiState?.connecting = + CashFusionState(status: CashFusionStatus.success, info: info); + _uiState?.outputs = + CashFusionState(status: CashFusionStatus.running, info: info); break; case fusion.FusionStatus.waiting: - _uiState?.outputs = CashFusionStatus.success; - _uiState?.peers = CashFusionStatus.running; + _uiState?.outputs = + CashFusionState(status: CashFusionStatus.success, info: info); + _uiState?.peers = + CashFusionState(status: CashFusionStatus.running, info: info); break; case fusion.FusionStatus.running: - _uiState?.peers = CashFusionStatus.success; - _uiState?.fusing = CashFusionStatus.running; + _uiState?.peers = + CashFusionState(status: CashFusionStatus.success, info: info); + _uiState?.fusing = + CashFusionState(status: CashFusionStatus.running, info: info); break; case fusion.FusionStatus.complete: - _uiState?.fusing = CashFusionStatus.success; - _uiState?.complete = CashFusionStatus.success; + _uiState?.fusing = + CashFusionState(status: CashFusionStatus.success, info: info); + _uiState?.complete = + CashFusionState(status: CashFusionStatus.success, info: info); break; case fusion.FusionStatus.failed: // _uiState?.fusing = CashFusionStatus.failed; - _uiState?.complete = CashFusionStatus.failed; + _uiState?.complete = + CashFusionState(status: CashFusionStatus.failed, info: info); failCurrentUiState(info); break; case fusion.FusionStatus.exception: - _uiState?.complete = CashFusionStatus.failed; + _uiState?.complete = + CashFusionState(status: CashFusionStatus.failed, info: info); failCurrentUiState(info); break; case fusion.FusionStatus.reset: - _uiState?.outputs = CashFusionStatus.waiting; - _uiState?.peers = CashFusionStatus.waiting; - _uiState?.connecting = CashFusionStatus.waiting; - _uiState?.fusing = CashFusionStatus.waiting; - _uiState?.complete = CashFusionStatus.waiting; - _uiState?.fusionState = CashFusionStatus.waiting; + _uiState?.outputs = + CashFusionState(status: CashFusionStatus.waiting, info: info); + _uiState?.peers = + CashFusionState(status: CashFusionStatus.waiting, info: info); + _uiState?.connecting = + CashFusionState(status: CashFusionStatus.waiting, info: info); + _uiState?.fusing = + CashFusionState(status: CashFusionStatus.waiting, info: info); + _uiState?.complete = + CashFusionState(status: CashFusionStatus.waiting, info: info); + _uiState?.fusionState = + CashFusionState(status: CashFusionStatus.waiting, info: info); break; } } void failCurrentUiState(String? info) { // Check each _uiState value to see if it is running. If so, set it to failed. - if (_uiState?.connecting == CashFusionStatus.running) { - _uiState?.connecting = CashFusionStatus.failed; - _uiState?.connectionInfo = info; + if (_uiState?.connecting.status == CashFusionStatus.running) { + _uiState?.connecting = + CashFusionState(status: CashFusionStatus.failed, info: info); } - if (_uiState?.outputs == CashFusionStatus.running) { - _uiState?.outputs = CashFusionStatus.failed; - _uiState?.outputsInfo = info; + if (_uiState?.outputs.status == CashFusionStatus.running) { + _uiState?.outputs = + CashFusionState(status: CashFusionStatus.failed, info: info); } - if (_uiState?.peers == CashFusionStatus.running) { - _uiState?.peers = CashFusionStatus.failed; - _uiState?.connectionInfo = info; + if (_uiState?.peers.status == CashFusionStatus.running) { + _uiState?.peers = + CashFusionState(status: CashFusionStatus.failed, info: info); } - if (_uiState?.fusing == CashFusionStatus.running) { - _uiState?.fusing = CashFusionStatus.failed; - _uiState?.fusingInfo = info; + if (_uiState?.fusing.status == CashFusionStatus.running) { + _uiState?.fusing = + CashFusionState(status: CashFusionStatus.failed, info: info); } - if (_uiState?.complete == CashFusionStatus.running) { - _uiState?.complete = CashFusionStatus.failed; - _uiState?.completeInfo = info; + if (_uiState?.complete.status == CashFusionStatus.running) { + _uiState?.complete = + CashFusionState(status: CashFusionStatus.failed, info: info); } } From c96f2476fab228721443cd9d75780463bb8dbf4a Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 11:15:50 -0500 Subject: [PATCH 234/379] only show info messages on errors --- .../mixins/fusion_wallet_interface.dart | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index ce7759b5f..e18ac80d4 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -156,32 +156,34 @@ mixin FusionWalletInterface { void _updateStatus({required fusion.FusionStatus status, String? info}) { switch (status) { case fusion.FusionStatus.connecting: - _uiState?.connecting = - CashFusionState(status: CashFusionStatus.running, info: info); + _uiState?.connecting = CashFusionState( + status: CashFusionStatus.running, + info: + null); // We only want to show error messages for failed states. break; case fusion.FusionStatus.setup: _uiState?.connecting = - CashFusionState(status: CashFusionStatus.success, info: info); + CashFusionState(status: CashFusionStatus.success, info: null); _uiState?.outputs = - CashFusionState(status: CashFusionStatus.running, info: info); + CashFusionState(status: CashFusionStatus.running, info: null); break; case fusion.FusionStatus.waiting: _uiState?.outputs = - CashFusionState(status: CashFusionStatus.success, info: info); + CashFusionState(status: CashFusionStatus.success, info: null); _uiState?.peers = - CashFusionState(status: CashFusionStatus.running, info: info); + CashFusionState(status: CashFusionStatus.running, info: null); break; case fusion.FusionStatus.running: _uiState?.peers = - CashFusionState(status: CashFusionStatus.success, info: info); + CashFusionState(status: CashFusionStatus.success, info: null); _uiState?.fusing = - CashFusionState(status: CashFusionStatus.running, info: info); + CashFusionState(status: CashFusionStatus.running, info: null); break; case fusion.FusionStatus.complete: _uiState?.fusing = - CashFusionState(status: CashFusionStatus.success, info: info); + CashFusionState(status: CashFusionStatus.success, info: null); _uiState?.complete = - CashFusionState(status: CashFusionStatus.success, info: info); + CashFusionState(status: CashFusionStatus.success, info: null); break; case fusion.FusionStatus.failed: // _uiState?.fusing = CashFusionStatus.failed; From 853016cd17ad1a70fd0a3e2f18185b155991ebfc Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 11:16:17 -0500 Subject: [PATCH 235/379] do not set fusing nor complete to failed, just fail current ui state --- lib/services/mixins/fusion_wallet_interface.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index e18ac80d4..6ec09bd48 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -187,15 +187,15 @@ mixin FusionWalletInterface { break; case fusion.FusionStatus.failed: // _uiState?.fusing = CashFusionStatus.failed; - _uiState?.complete = - CashFusionState(status: CashFusionStatus.failed, info: info); + // _uiState?.complete = + // CashFusionState(status: CashFusionStatus.failed, info: info); failCurrentUiState(info); break; case fusion.FusionStatus.exception: - _uiState?.complete = - CashFusionState(status: CashFusionStatus.failed, info: info); + // _uiState?.complete = + // CashFusionState(status: CashFusionStatus.failed, info: info); failCurrentUiState(info); break; From 094668cc0c4af5b4744277a4395a111ec7185e8a Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 11:18:43 -0500 Subject: [PATCH 236/379] fix state comparisons --- lib/models/fusion_progress_ui_state.dart | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 55079dda9..84c8a1699 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -9,19 +9,19 @@ class FusionProgressUIState extends ChangeNotifier { return false; } - bool _done = (_connecting == CashFusionStatus.success) || - (_connecting == CashFusionStatus.failed); - _done &= (_outputs == CashFusionStatus.success) || - (_outputs == CashFusionStatus.failed); - _done &= (_peers == CashFusionStatus.success) || - (_peers == CashFusionStatus.failed); - _done &= (_fusing == CashFusionStatus.success) || - (_fusing == CashFusionStatus.failed); - _done &= (_complete == CashFusionStatus.success) || - (_complete == CashFusionStatus.failed); + bool _done = (_connecting.status == CashFusionStatus.success) || + (_connecting.status == CashFusionStatus.failed); + _done &= (_outputs.status == CashFusionStatus.success) || + (_outputs.status == CashFusionStatus.failed); + _done &= (_peers.status == CashFusionStatus.success) || + (_peers.status == CashFusionStatus.failed); + _done &= (_fusing.status == CashFusionStatus.success) || + (_fusing.status == CashFusionStatus.failed); + _done &= (_complete.status == CashFusionStatus.success) || + (_complete.status == CashFusionStatus.failed); - _done &= (fusionState == CashFusionStatus.success) || - (fusionState == CashFusionStatus.failed); + _done &= (fusionState.status == CashFusionStatus.success) || + (fusionState.status == CashFusionStatus.failed); return _done; } @@ -37,7 +37,7 @@ class FusionProgressUIState extends ChangeNotifier { _succeeded &= _fusing.status == CashFusionStatus.success; _succeeded &= _complete.status == CashFusionStatus.success; - _succeeded &= fusionState == CashFusionStatus.success; + _succeeded &= fusionState.status == CashFusionStatus.success; return _succeeded; } From 8f848a4d704c0ffbbd70a9bbaecb0737489b3bd0 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 11:19:12 -0500 Subject: [PATCH 237/379] break, don't set more than one running state to failed (esp. commplete) --- lib/services/mixins/fusion_wallet_interface.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 6ec09bd48..112753b12 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -221,22 +221,27 @@ mixin FusionWalletInterface { if (_uiState?.connecting.status == CashFusionStatus.running) { _uiState?.connecting = CashFusionState(status: CashFusionStatus.failed, info: info); + return; } if (_uiState?.outputs.status == CashFusionStatus.running) { _uiState?.outputs = CashFusionState(status: CashFusionStatus.failed, info: info); + return; } if (_uiState?.peers.status == CashFusionStatus.running) { _uiState?.peers = CashFusionState(status: CashFusionStatus.failed, info: info); + return; } if (_uiState?.fusing.status == CashFusionStatus.running) { _uiState?.fusing = CashFusionState(status: CashFusionStatus.failed, info: info); + return; } if (_uiState?.complete.status == CashFusionStatus.running) { _uiState?.complete = CashFusionState(status: CashFusionStatus.failed, info: info); + return; } } From 87baa840d3405ca29c83e5d144b5bf4d669f9e05 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 12:22:12 -0500 Subject: [PATCH 238/379] loop continuously if roundCount set to 0 --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 8052be203..b02aa8100 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 8052be203d9bf3af1170420177b98c92c481f884 +Subproject commit b02aa81007df3ce3492571f93e32cd07cc5a6028 From 2556eff69f15ee2014bfc4b4653eaa4b6d6be1c6 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 12:24:36 -0500 Subject: [PATCH 239/379] support less than 0 rounds --- lib/services/mixins/fusion_wallet_interface.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 112753b12..9e035204d 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -406,11 +406,9 @@ mixin FusionWalletInterface { serverHost: fusionInfo.host, serverPort: fusionInfo.port, serverSsl: fusionInfo.ssl, + roundCount: fusionInfo.rounds, ); - // TODO use as required. Zero indicates continuous - final roundCount = fusionInfo.rounds; - // Instantiate a Fusion object with custom parameters. final mainFusionObject = fusion.Fusion(serverParams); From 2562305d7cdc564ef6f709b736ccfa0ab370a7b7 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 12:54:23 -0600 Subject: [PATCH 240/379] json encoding fix --- lib/services/mixins/fusion_wallet_interface.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 9e035204d..053e183b2 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -54,12 +54,12 @@ class FusionInfo { } String toJsonString() { - return { + return jsonEncode({ 'host': host, 'port': port, 'ssl': ssl, 'rounds': rounds, - }.toString(); + }); } @override From 9d01f0beaa9b817aecd095fdda5292893e1e9078 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 14:33:46 -0600 Subject: [PATCH 241/379] json encoding fix 2 --- lib/utilities/prefs.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/utilities/prefs.dart b/lib/utilities/prefs.dart index 4dcd9a65d..6fe9689ab 100644 --- a/lib/utilities/prefs.dart +++ b/lib/utilities/prefs.dart @@ -958,10 +958,10 @@ class Prefs extends ChangeNotifier { key: "fusionServerInfo", ) as String?; - if (saved == null) { + try { + return FusionInfo.fromJsonString(saved!); + } catch (_) { return FusionInfo.DEFAULTS; - } else { - return FusionInfo.fromJsonString(saved); } } } From 65882b66e1c5145f569c62af152322096481e167 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 14:34:15 -0600 Subject: [PATCH 242/379] testing --- .../global_settings_view/hidden_settings.dart | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/pages/settings_views/global_settings_view/hidden_settings.dart b/lib/pages/settings_views/global_settings_view/hidden_settings.dart index d2aaf4535..075018b13 100644 --- a/lib/pages/settings_views/global_settings_view/hidden_settings.dart +++ b/lib/pages/settings_views/global_settings_view/hidden_settings.dart @@ -11,6 +11,7 @@ import 'dart:async'; import 'dart:typed_data'; +import 'package:bitbox/bitbox.dart' as bb; import 'package:bitcoindart/bitcoindart.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -478,20 +479,26 @@ class HiddenSettings extends StatelessWidget { final p2pkh = P2PKH(data: pd, network: bitcoincash); - final addr = p2pkh.data.address!; + // final addr = p2pkh.data.address!; + + final addr = bb.Address.toLegacyAddress( + "bitcoincash:qp352c2skpdxwzzd090mec3v37au5dmfwgwfw686sz", + ); final scripthash = AddressUtils.convertToScriptHash( addr, bitcoincash); - final hist = await e.getHistory( - scripthash: scripthash); - - Util.printJson(hist, "HISTORY for $address"); final utxos = await e.getUTXOs(scripthash: scripthash); Util.printJson(utxos, "UTXOS for $address"); + + final hist = await e.getTransaction( + txHash: utxos.first["tx_hash"] as String, + ); + + Util.printJson(hist, "HISTORY for $address"); } catch (e, s) { print("$e\n$s"); } From b544cc3096afe04bc018ae4195eeb405b630f94d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 14:34:49 -0600 Subject: [PATCH 243/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index b02aa8100..43bf651b9 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit b02aa81007df3ce3492571f93e32cd07cc5a6028 +Subproject commit 43bf651b9c739d7689faff4c6bf14ed64b5b5fcb From fb64c00d9cfb31972b996c21353aed47a224c425 Mon Sep 17 00:00:00 2001 From: Jonald Fyookball <jonaldfyookball@outlook.com> Date: Sat, 26 Aug 2023 19:19:25 -0400 Subject: [PATCH 244/379] Add cashtokens.dart for initial class implementation. --- .../coins/bitcoincash/cashtokens.dart | 345 ++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 lib/services/coins/bitcoincash/cashtokens.dart diff --git a/lib/services/coins/bitcoincash/cashtokens.dart b/lib/services/coins/bitcoincash/cashtokens.dart new file mode 100644 index 000000000..aaddb8c8a --- /dev/null +++ b/lib/services/coins/bitcoincash/cashtokens.dart @@ -0,0 +1,345 @@ +import 'dart:typed_data'; +import 'package:hex/hex.dart'; +import 'package:convert/convert.dart'; + +// The Structure enum +enum Structure { + HasAmount, + HasNFT, + HasCommitmentLength, +} + +// The Capability enum +enum Capability { + NoCapability, + Mutable, + Minting, +} + +// Used as a "custom tuple" +class CompactSizeResult { + final int amount; + final int bytesRead; + + CompactSizeResult({required this.amount, required this.bytesRead}); +} + + +class ParsedOutput { + List<int>? script_pub_key; + TokenOutputData? token_data; + ParsedOutput({this.script_pub_key, this.token_data}); +} + +class TokenOutputData { + Uint8List? id; + int? amount; + Uint8List? commitment; + Uint8List? bitfield; // A byte (Uint8List of length 1) + + // Constructor + TokenOutputData({ + this.id, + this.amount, + this.commitment, + this.bitfield, + }); + + int getCapability() { + if (bitfield != null) { + return bitfield![0] & 0x0f; + } + return 0; + } + + bool hasCommitmentLength() { + if (bitfield != null) { + return (bitfield![0] & 0x40) != 0; + } + return false; + } + + bool hasAmount() { + if (bitfield != null) { + return (bitfield![0] & 0x10) != 0; + } + return false; + } + + bool hasNFT() { + if (bitfield != null) { + return (bitfield![0] & 0x20) != 0; + } + return false; + } + + bool isMintingNFT() { + return hasNFT() && getCapability() == Capability.Minting.index; + } + + bool isMutableNFT() { + return hasNFT() && getCapability() == Capability.Mutable.index; + } + + bool isImmutableNFT() { + return hasNFT() && getCapability() == Capability.NoCapability.index; + } + + bool isValidBitfield() { + if (bitfield == null) { + return false; + } + + int s = bitfield![0] & 0xf0; + if (s >= 0x80 || s == 0x00) { + return false; + } + if (bitfield![0] & 0x0f > 2) { + return false; + } + if (!hasNFT() && !hasAmount()) { + return false; + } + if (!hasNFT() && (bitfield![0] & 0x0f) != 0) { + return false; + } + if (!hasNFT() && hasCommitmentLength()) { + return false; + } + return true; + } + + + + int deserialize(Uint8List buffer, {int cursor = 0, bool strict = false}) { + try { + + this.id = buffer.sublist(cursor, cursor + 32); + cursor += 32; + + + this.bitfield = Uint8List.fromList([buffer[cursor]]); + cursor += 1; + + if (this.hasCommitmentLength()) { + + // Read the first byte to determine the length of the commitment data + int commitmentLength = buffer[cursor]; + + // Move cursor to the next byte + cursor += 1; + + // Read 'commitmentLength' bytes for the commitment data + this.commitment = buffer.sublist(cursor, cursor + commitmentLength); + + // Adjust the cursor by the length of the commitment data + cursor += commitmentLength; + } else { + this.commitment = null; + } + + + if (this.hasAmount()) { + // Use readCompactSize that returns CompactSizeResult + CompactSizeResult result = readCompactSize(buffer, cursor, strict: strict); + this.amount = result.amount; + cursor += result.bytesRead; + } else { + this.amount = 0; + } + + + if (!this.isValidBitfield() || + (this.hasAmount() && this.amount == 0) || + (this.amount! < 0 || this.amount! > (1 << 63) - 1) || + (this.hasCommitmentLength() && this.commitment!.isEmpty) || + (this.amount! == 0 && !this.hasNFT()) + ) { + throw Exception('Unable to parse token data or token data is invalid'); + } + + return cursor; // Return the number of bytes read + + } catch (e) { + throw Exception('Deserialization failed: $e'); + } + } + + + // Serialize method + Uint8List serialize() { + var buffer = BytesBuilder(); + + // write ID and bitfield + buffer.add(this.id!); + buffer.addByte(this.bitfield![0]); + + // Write optional fields + if (this.hasCommitmentLength()) { + buffer.add(this.commitment!); + } + + if (this.hasAmount()) { + List<int> compactSizeBytes = writeCompactSize(this.amount!); + buffer.add(compactSizeBytes); + } + + return buffer.toBytes(); + } + +} //END OF OUTPUTDATA CLASS + +final List<int> PREFIX_BYTE = [0xef]; + +ParsedOutput wrap_spk(TokenOutputData? token_data, Uint8List script_pub_key) { + ParsedOutput parsedOutput = ParsedOutput(); + + if (token_data == null) { + parsedOutput.script_pub_key = script_pub_key; + return parsedOutput; + } + + final buf = BytesBuilder(); + + buf.add(PREFIX_BYTE); + buf.add(token_data.serialize()); + buf.add(script_pub_key); + + parsedOutput.script_pub_key = buf.toBytes(); + parsedOutput.token_data = token_data; + + return parsedOutput; +} + + + + +ParsedOutput unwrap_spk(Uint8List wrapped_spk) { + ParsedOutput parsedOutput = ParsedOutput(); + + + if (wrapped_spk.isEmpty || wrapped_spk[0] != PREFIX_BYTE[0]) { + parsedOutput.script_pub_key = wrapped_spk; + return parsedOutput; + } + + + int read_cursor = 1; // Start after the PREFIX_BYTE + TokenOutputData token_data = TokenOutputData(); + + Uint8List wrapped_spk_without_prefix_byte; + try { + // Deserialize updates read_cursor by the number of bytes read + + wrapped_spk_without_prefix_byte= wrapped_spk.sublist(read_cursor); + int bytesRead = token_data.deserialize(wrapped_spk_without_prefix_byte); + + + read_cursor += bytesRead; + parsedOutput.token_data = token_data; + parsedOutput.script_pub_key = wrapped_spk.sublist(read_cursor); + + } catch (e) { + // If unable to deserialize, return all bytes as the full scriptPubKey + parsedOutput.script_pub_key = wrapped_spk; + } + + return parsedOutput; +} + + +void testUnwrapSPK() { + + + // Example Hex format string + String var1 = "YOUR-SCRIPT-PUBKEY-AS-HEX-STRING-FOR-TESTING-GOES-HERE"; + // Convert the Hex string to Uint8List + Uint8List wrapped_spk = Uint8List.fromList(HEX.decode(var1)); + + // Call unwrap_spk + ParsedOutput parsedOutput = unwrap_spk(wrapped_spk); + + print("Parsed Output: $parsedOutput"); + + // Access token_data inside parsedOutput + TokenOutputData? tokenData = parsedOutput.token_data; + + // Check if tokenData is null + if (tokenData != null) { + // Print specific fields + if (tokenData.id != null) { + print("ID: ${hex.encode(tokenData.id!)}"); // hex is imported + } else { + print("ID: null"); + } + print ("amount of tokens"); + print (tokenData.amount); + print("Is it an NFT?: ${tokenData.hasNFT()}"); + } else { + print("Token data is null."); + } + +} //end function + + +// HELPER FUNCTIONS +CompactSizeResult readCompactSize(Uint8List buffer, int cursor, {bool strict = false}) { + + + int bytesRead = 0; // Variable to count bytes read + int val; + try { + val = buffer[cursor]; + cursor += 1; + bytesRead += 1; + int minVal; + if (val == 253) { + val = buffer.buffer.asByteData().getUint16(cursor, Endian.little); + cursor += 2; + bytesRead += 2; + minVal = 253; + } else if (val == 254) { + val = buffer.buffer.asByteData().getUint32(cursor, Endian.little); + cursor += 4; + bytesRead += 4; + minVal = 1 << 16; + } else if (val == 255) { + val = buffer.buffer.asByteData().getInt64(cursor, Endian.little); + cursor += 8; + bytesRead += 8; + minVal = 1 << 32; + } else { + minVal = 0; + } + if (strict && val < minVal) { + throw Exception("CompactSize is not minimally encoded"); + } + + return CompactSizeResult(amount: val, bytesRead: bytesRead); + } catch (e) { + throw Exception("attempt to read past end of buffer"); + } +} +Uint8List writeCompactSize(int size) { + var buffer = ByteData(9); // Maximum needed size for compact size is 9 bytes + if (size < 0) { + throw Exception("attempt to write size < 0"); + } else if (size < 253) { + return Uint8List.fromList([size]); + } else if (size < (1 << 16)) { + buffer.setUint8(0, 253); + buffer.setUint16(1, size, Endian.little); + return buffer.buffer.asUint8List(0, 3); + } else if (size < (1 << 32)) { + buffer.setUint8(0, 254); + buffer.setUint32(1, size, Endian.little); + return buffer.buffer.asUint8List(0, 5); + } else if (size < (1 << 64)) { + buffer.setUint8(0, 255); + buffer.setInt64(1, size, Endian.little); + return buffer.buffer.asUint8List(0, 9); + } else { + throw Exception("Size too large to represent as CompactSize"); + } +} + From 06b964a7282aca9a86c6ecf3a97bd397e06caae0 Mon Sep 17 00:00:00 2001 From: Jonald Fyookball <jonaldfyookball@outlook.com> Date: Thu, 31 Aug 2023 11:49:28 -0400 Subject: [PATCH 245/379] add more code comments --- .../coins/bitcoincash/cashtokens.dart | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/services/coins/bitcoincash/cashtokens.dart b/lib/services/coins/bitcoincash/cashtokens.dart index aaddb8c8a..b53f1e26c 100644 --- a/lib/services/coins/bitcoincash/cashtokens.dart +++ b/lib/services/coins/bitcoincash/cashtokens.dart @@ -16,7 +16,8 @@ enum Capability { Minting, } -// Used as a "custom tuple" +// Used as a "custom tuple" for the supporting functions of readCompactSize to return +// a convenient data structure. class CompactSizeResult { final int amount; final int bytesRead; @@ -25,12 +26,21 @@ class CompactSizeResult { } + +// This class is a data structure representing the entire output, comprised of both the +// normal Script pub key and the token data. We get this after we parse/unwrap the raw +// output. class ParsedOutput { List<int>? script_pub_key; TokenOutputData? token_data; ParsedOutput({this.script_pub_key, this.token_data}); } + +// This is equivalent to the Electron Cash python's "OutputData" in token.py. +// Named here specifically as "TokenOutputData" to reflect the fact that +// it is specifically for tokens, whereas the other class ParsedOutput represents +// the entire output, comprised of both the normal Script pub key and the token data. class TokenOutputData { Uint8List? id; int? amount; @@ -45,6 +55,8 @@ class TokenOutputData { this.bitfield, }); + + // Get the "capability", see Capability enum. int getCapability() { if (bitfield != null) { return bitfield![0] & 0x0f; @@ -52,6 +64,7 @@ class TokenOutputData { return 0; } + // functions to return attributes of the token bitfield. bool hasCommitmentLength() { if (bitfield != null) { return (bitfield![0] & 0x40) != 0; @@ -73,6 +86,8 @@ class TokenOutputData { return false; } + + // Functions to return specific attributes based on the Capability. bool isMintingNFT() { return hasNFT() && getCapability() == Capability.Minting.index; } @@ -85,6 +100,8 @@ class TokenOutputData { return hasNFT() && getCapability() == Capability.NoCapability.index; } + + // This function validates if the bitfield makes sense or violates known rules/logic. bool isValidBitfield() { if (bitfield == null) { return false; @@ -110,7 +127,8 @@ class TokenOutputData { } - + // The serialze and deserialize functions are the nuts and bolts of how we unpack + // and pack outputs. These are called by the wrap and unwrap functions. int deserialize(Uint8List buffer, {int cursor = 0, bool strict = false}) { try { @@ -189,8 +207,11 @@ class TokenOutputData { } //END OF OUTPUTDATA CLASS + +// The prefix byte is specified by the CashTokens spec. final List<int> PREFIX_BYTE = [0xef]; +// This function wraps a "normal" output together with token data. ParsedOutput wrap_spk(TokenOutputData? token_data, Uint8List script_pub_key) { ParsedOutput parsedOutput = ParsedOutput(); @@ -213,7 +234,11 @@ ParsedOutput wrap_spk(TokenOutputData? token_data, Uint8List script_pub_key) { - +// This function unwraps any output, either "normal" (containing no token data) +// or an output with token data. If no token data, just the output is returned, +// and if token data exists, both the output and token data are returned. +// Note that the data returend in both cases in of ParsedOutput type, which +// holds both the script pub key and token data. ParsedOutput unwrap_spk(Uint8List wrapped_spk) { ParsedOutput parsedOutput = ParsedOutput(); @@ -248,6 +273,8 @@ ParsedOutput unwrap_spk(Uint8List wrapped_spk) { } +// Just a testing function which can be called in standalone fashion. +// Replace "var1" with a hex string containing an output (script pub key) void testUnwrapSPK() { @@ -283,6 +310,10 @@ void testUnwrapSPK() { // HELPER FUNCTIONS + +//These are part of a "length value " scheme where the length (and endianness) are given first +// and inform the program of how many bytes to grab next. These are in turn used by the serialize +// and deserialize functions.- CompactSizeResult readCompactSize(Uint8List buffer, int cursor, {bool strict = false}) { From ee88cd8fb0098637e524669d696f5e324ab94716 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 14:53:18 -0600 Subject: [PATCH 246/379] move test function to a test --- .../coins/bitcoincash/cashtokens.dart | 37 ----------------- .../coins/bitcoincash/cashtokens_test.dart | 40 +++++++++++++++++++ 2 files changed, 40 insertions(+), 37 deletions(-) create mode 100644 test/services/coins/bitcoincash/cashtokens_test.dart diff --git a/lib/services/coins/bitcoincash/cashtokens.dart b/lib/services/coins/bitcoincash/cashtokens.dart index b53f1e26c..f19348620 100644 --- a/lib/services/coins/bitcoincash/cashtokens.dart +++ b/lib/services/coins/bitcoincash/cashtokens.dart @@ -272,43 +272,6 @@ ParsedOutput unwrap_spk(Uint8List wrapped_spk) { return parsedOutput; } - -// Just a testing function which can be called in standalone fashion. -// Replace "var1" with a hex string containing an output (script pub key) -void testUnwrapSPK() { - - - // Example Hex format string - String var1 = "YOUR-SCRIPT-PUBKEY-AS-HEX-STRING-FOR-TESTING-GOES-HERE"; - // Convert the Hex string to Uint8List - Uint8List wrapped_spk = Uint8List.fromList(HEX.decode(var1)); - - // Call unwrap_spk - ParsedOutput parsedOutput = unwrap_spk(wrapped_spk); - - print("Parsed Output: $parsedOutput"); - - // Access token_data inside parsedOutput - TokenOutputData? tokenData = parsedOutput.token_data; - - // Check if tokenData is null - if (tokenData != null) { - // Print specific fields - if (tokenData.id != null) { - print("ID: ${hex.encode(tokenData.id!)}"); // hex is imported - } else { - print("ID: null"); - } - print ("amount of tokens"); - print (tokenData.amount); - print("Is it an NFT?: ${tokenData.hasNFT()}"); - } else { - print("Token data is null."); - } - -} //end function - - // HELPER FUNCTIONS //These are part of a "length value " scheme where the length (and endianness) are given first diff --git a/test/services/coins/bitcoincash/cashtokens_test.dart b/test/services/coins/bitcoincash/cashtokens_test.dart new file mode 100644 index 000000000..4fb0d74de --- /dev/null +++ b/test/services/coins/bitcoincash/cashtokens_test.dart @@ -0,0 +1,40 @@ +import 'dart:typed_data'; + +import 'package:convert/convert.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:hex/hex.dart'; +import 'package:stackwallet/services/coins/bitcoincash/cashtokens.dart'; + +void main() { + // Just a testing function which can be called in standalone fashion. + // Replace "var1" with a hex string containing an output (script pub key) + test("testUnwrapSPK", () { + // Example Hex format string + String var1 = "YOUR-SCRIPT-PUBKEY-AS-HEX-STRING-FOR-TESTING-GOES-HERE"; + // Convert the Hex string to Uint8List + Uint8List wrapped_spk = Uint8List.fromList(HEX.decode(var1)); + + // Call unwrap_spk + ParsedOutput parsedOutput = unwrap_spk(wrapped_spk); + + print("Parsed Output: $parsedOutput"); + + // Access token_data inside parsedOutput + TokenOutputData? tokenData = parsedOutput.token_data; + + // Check if tokenData is null + if (tokenData != null) { + // Print specific fields + if (tokenData.id != null) { + print("ID: ${hex.encode(tokenData.id!)}"); // hex is imported + } else { + print("ID: null"); + } + print("amount of tokens"); + print(tokenData.amount); + print("Is it an NFT?: ${tokenData.hasNFT()}"); + } else { + print("Token data is null."); + } + }); +} From 24c9561257f6d89717a7a8313f253d966d723c88 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 14:55:07 -0600 Subject: [PATCH 247/379] auto format code --- .../coins/bitcoincash/cashtokens.dart | 48 +++++-------------- 1 file changed, 13 insertions(+), 35 deletions(-) diff --git a/lib/services/coins/bitcoincash/cashtokens.dart b/lib/services/coins/bitcoincash/cashtokens.dart index f19348620..d35d2838c 100644 --- a/lib/services/coins/bitcoincash/cashtokens.dart +++ b/lib/services/coins/bitcoincash/cashtokens.dart @@ -1,6 +1,4 @@ import 'dart:typed_data'; -import 'package:hex/hex.dart'; -import 'package:convert/convert.dart'; // The Structure enum enum Structure { @@ -25,8 +23,6 @@ class CompactSizeResult { CompactSizeResult({required this.amount, required this.bytesRead}); } - - // This class is a data structure representing the entire output, comprised of both the // normal Script pub key and the token data. We get this after we parse/unwrap the raw // output. @@ -36,7 +32,6 @@ class ParsedOutput { ParsedOutput({this.script_pub_key, this.token_data}); } - // This is equivalent to the Electron Cash python's "OutputData" in token.py. // Named here specifically as "TokenOutputData" to reflect the fact that // it is specifically for tokens, whereas the other class ParsedOutput represents @@ -55,7 +50,6 @@ class TokenOutputData { this.bitfield, }); - // Get the "capability", see Capability enum. int getCapability() { if (bitfield != null) { @@ -86,7 +80,6 @@ class TokenOutputData { return false; } - // Functions to return specific attributes based on the Capability. bool isMintingNFT() { return hasNFT() && getCapability() == Capability.Minting.index; @@ -100,7 +93,6 @@ class TokenOutputData { return hasNFT() && getCapability() == Capability.NoCapability.index; } - // This function validates if the bitfield makes sense or violates known rules/logic. bool isValidBitfield() { if (bitfield == null) { @@ -126,21 +118,17 @@ class TokenOutputData { return true; } - // The serialze and deserialize functions are the nuts and bolts of how we unpack // and pack outputs. These are called by the wrap and unwrap functions. int deserialize(Uint8List buffer, {int cursor = 0, bool strict = false}) { try { - this.id = buffer.sublist(cursor, cursor + 32); cursor += 32; - this.bitfield = Uint8List.fromList([buffer[cursor]]); cursor += 1; if (this.hasCommitmentLength()) { - // Read the first byte to determine the length of the commitment data int commitmentLength = buffer[cursor]; @@ -156,34 +144,30 @@ class TokenOutputData { this.commitment = null; } - if (this.hasAmount()) { // Use readCompactSize that returns CompactSizeResult - CompactSizeResult result = readCompactSize(buffer, cursor, strict: strict); + CompactSizeResult result = + readCompactSize(buffer, cursor, strict: strict); this.amount = result.amount; cursor += result.bytesRead; } else { this.amount = 0; } - if (!this.isValidBitfield() || (this.hasAmount() && this.amount == 0) || (this.amount! < 0 || this.amount! > (1 << 63) - 1) || (this.hasCommitmentLength() && this.commitment!.isEmpty) || - (this.amount! == 0 && !this.hasNFT()) - ) { + (this.amount! == 0 && !this.hasNFT())) { throw Exception('Unable to parse token data or token data is invalid'); } - return cursor; // Return the number of bytes read - + return cursor; // Return the number of bytes read } catch (e) { throw Exception('Deserialization failed: $e'); } } - // Serialize method Uint8List serialize() { var buffer = BytesBuilder(); @@ -204,9 +188,7 @@ class TokenOutputData { return buffer.toBytes(); } - -} //END OF OUTPUTDATA CLASS - +} //END OF OUTPUTDATA CLASS // The prefix byte is specified by the CashTokens spec. final List<int> PREFIX_BYTE = [0xef]; @@ -232,9 +214,7 @@ ParsedOutput wrap_spk(TokenOutputData? token_data, Uint8List script_pub_key) { return parsedOutput; } - - -// This function unwraps any output, either "normal" (containing no token data) +// This function unwraps any output, either "normal" (containing no token data) // or an output with token data. If no token data, just the output is returned, // and if token data exists, both the output and token data are returned. // Note that the data returend in both cases in of ParsedOutput type, which @@ -242,13 +222,11 @@ ParsedOutput wrap_spk(TokenOutputData? token_data, Uint8List script_pub_key) { ParsedOutput unwrap_spk(Uint8List wrapped_spk) { ParsedOutput parsedOutput = ParsedOutput(); - if (wrapped_spk.isEmpty || wrapped_spk[0] != PREFIX_BYTE[0]) { parsedOutput.script_pub_key = wrapped_spk; return parsedOutput; } - int read_cursor = 1; // Start after the PREFIX_BYTE TokenOutputData token_data = TokenOutputData(); @@ -256,14 +234,12 @@ ParsedOutput unwrap_spk(Uint8List wrapped_spk) { try { // Deserialize updates read_cursor by the number of bytes read - wrapped_spk_without_prefix_byte= wrapped_spk.sublist(read_cursor); + wrapped_spk_without_prefix_byte = wrapped_spk.sublist(read_cursor); int bytesRead = token_data.deserialize(wrapped_spk_without_prefix_byte); - read_cursor += bytesRead; parsedOutput.token_data = token_data; parsedOutput.script_pub_key = wrapped_spk.sublist(read_cursor); - } catch (e) { // If unable to deserialize, return all bytes as the full scriptPubKey parsedOutput.script_pub_key = wrapped_spk; @@ -277,9 +253,11 @@ ParsedOutput unwrap_spk(Uint8List wrapped_spk) { //These are part of a "length value " scheme where the length (and endianness) are given first // and inform the program of how many bytes to grab next. These are in turn used by the serialize // and deserialize functions.- -CompactSizeResult readCompactSize(Uint8List buffer, int cursor, {bool strict = false}) { - - +CompactSizeResult readCompactSize( + Uint8List buffer, + int cursor, { + bool strict = false, +}) { int bytesRead = 0; // Variable to count bytes read int val; try { @@ -314,6 +292,7 @@ CompactSizeResult readCompactSize(Uint8List buffer, int cursor, {bool strict = f throw Exception("attempt to read past end of buffer"); } } + Uint8List writeCompactSize(int size) { var buffer = ByteData(9); // Maximum needed size for compact size is 9 bytes if (size < 0) { @@ -336,4 +315,3 @@ Uint8List writeCompactSize(int size) { throw Exception("Size too large to represent as CompactSize"); } } - From 4db85cb5f1ed4c8287aeab8519838cf048266afe Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 14:58:14 -0600 Subject: [PATCH 248/379] use valid hex string so the hex parser doesn't throw and cause the test to explode --- test/services/coins/bitcoincash/cashtokens_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/services/coins/bitcoincash/cashtokens_test.dart b/test/services/coins/bitcoincash/cashtokens_test.dart index 4fb0d74de..be8a8b24b 100644 --- a/test/services/coins/bitcoincash/cashtokens_test.dart +++ b/test/services/coins/bitcoincash/cashtokens_test.dart @@ -10,7 +10,7 @@ void main() { // Replace "var1" with a hex string containing an output (script pub key) test("testUnwrapSPK", () { // Example Hex format string - String var1 = "YOUR-SCRIPT-PUBKEY-AS-HEX-STRING-FOR-TESTING-GOES-HERE"; + String var1 = "76a91463456150b05a67084d795fbce22c8fbbca37697288ac"; // Convert the Hex string to Uint8List Uint8List wrapped_spk = Uint8List.fromList(HEX.decode(var1)); From 0374907ecdbb5d03d4ba02b0db3ab9234b02715b Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 15:26:03 -0600 Subject: [PATCH 249/379] add extra check to prevent full failure in case of server indexing issue --- .../ethereum/ethereum_token_service.dart | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/services/ethereum/ethereum_token_service.dart b/lib/services/ethereum/ethereum_token_service.dart index a42867485..239d8770e 100644 --- a/lib/services/ethereum/ethereum_token_service.dart +++ b/lib/services/ethereum/ethereum_token_service.dart @@ -468,7 +468,7 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache { } final response2 = await EthereumAPI.getEthTokenTransactionsByTxids( - response.value!.map((e) => e.transactionHash).toList(), + response.value!.map((e) => e.transactionHash).toSet().toList(), ); if (response2.value == null) { @@ -477,14 +477,25 @@ class EthTokenWallet extends ChangeNotifier with EthTokenCache { } final List<Tuple2<EthTokenTxDto, EthTokenTxExtraDTO>> data = []; for (final tokenDto in response.value!) { - data.add( - Tuple2( - tokenDto, - response2.value!.firstWhere( - (e) => e.hash == tokenDto.transactionHash, + try { + final txExtra = response2.value!.firstWhere( + (e) => e.hash == tokenDto.transactionHash, + ); + data.add( + Tuple2( + tokenDto, + txExtra, ), - ), - ); + ); + } catch (_) { + // Server indexing failed for some reason. Instead of hard crashing or + // showing no transactions we just skip it here. Not ideal but better + // than nothing showing up + Logging.instance.log( + "Server error: Transaction ${tokenDto.transactionHash} not found.", + level: LogLevel.Error, + ); + } } final List<Tuple2<Transaction, Address?>> txnsData = []; From 157484a4c98732be9b4c1744d6d90c59dccc183e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 16:24:13 -0600 Subject: [PATCH 250/379] add fusion server default button --- lib/pages/cashfusion/cashfusion_view.dart | 34 +++++++++++++++---- .../cashfusion/desktop_cashfusion_view.dart | 28 ++++++++++++--- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 354b6377e..60c6ad09e 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -27,6 +27,7 @@ import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; @@ -157,13 +158,32 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { const SizedBox( height: 16, ), - Text( - "Server settings", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textDark3, - ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Server settings", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark3, + ), + ), + CustomTextButton( + text: "Default", + onTap: () { + const def = FusionInfo.DEFAULTS; + serverController.text = def.host; + portController.text = def.port.toString(); + fusionRoundController.text = + def.rounds.toString(); + _option = FusionOption.continuous; + setState(() { + _enableSSLCheckbox = def.ssl; + }); + }, + ), + ], ), const SizedBox( height: 12, diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index af2ec178e..b93548bb4 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -28,6 +28,7 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; @@ -277,10 +278,29 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - "Server settings", - style: - STextStyles.desktopTextExtraExtraSmall(context), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Server settings", + style: STextStyles.desktopTextExtraExtraSmall( + context), + ), + CustomTextButton( + text: "Default", + onTap: () { + const def = FusionInfo.DEFAULTS; + serverController.text = def.host; + portController.text = def.port.toString(); + fusionRoundController.text = + def.rounds.toString(); + _roundType = FusionOption.continuous; + setState(() { + _enableSSLCheckbox = def.ssl; + }); + }, + ), + ], ), const SizedBox( height: 12, From e1ee2ed28d10d00f59d2bd9fcbd5a96d0b947d67 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 17 Oct 2023 16:25:23 -0600 Subject: [PATCH 251/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 43bf651b9..0d634a48e 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 43bf651b9c739d7689faff4c6bf14ed64b5b5fcb +Subproject commit 0d634a48e180458456aa6bc822bb82098380d114 From e9f00582d8dc6f8318665973156a6441d45e22f0 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 22:16:50 -0500 Subject: [PATCH 252/379] add stop fn to interface and refactor fusion obj to be an instance var --- .../mixins/fusion_wallet_interface.dart | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 053e183b2..8979ecda6 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -124,6 +124,9 @@ mixin FusionWalletInterface { late final CachedElectrumX Function() _getWalletCachedElectrumX; late final Future<int> Function() _getChainHeight; + // Fusion object. + fusion.Fusion? _mainFusionObject; + /// Initializes the FusionWalletInterface mixin. /// /// This function must be called before any other functions in this mixin. @@ -410,10 +413,10 @@ mixin FusionWalletInterface { ); // Instantiate a Fusion object with custom parameters. - final mainFusionObject = fusion.Fusion(serverParams); + _mainFusionObject = fusion.Fusion(serverParams); // Pass wallet functions to the Fusion object - await mainFusionObject.initFusion( + await _mainFusionObject!.initFusion( getTransactionsByAddress: _getTransactionsByAddress, getUnusedReservedChangeAddresses: _getUnusedReservedChangeAddresses, getSocksProxyAddress: _getSocksProxyAddress, @@ -511,7 +514,7 @@ mixin FusionWalletInterface { } // Fuse UTXOs. - return await mainFusionObject.fuse( + return await _mainFusionObject!.fuse( inputsFromWallet: coinList, network: _coin.isTestNet ? fusion.Utilities.testNet : fusion.Utilities.mainNet, @@ -523,4 +526,12 @@ mixin FusionWalletInterface { throw UnimplementedError( "TODO refreshFusion eg look up number of fusion participants connected/coordinating"); } + + /// Stop the fusion process. + /// + /// This function is called when the user taps the "Cancel" button in the UI + /// or closes the fusion progress dialog. + Future<void>? stop() { + return _mainFusionObject?.stop(); + } } From ed2a637e5e4e6110ff6e9e696661949c17ab00e6 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 22:17:16 -0500 Subject: [PATCH 253/379] hook cancel buttons up to stop fn --- fusiondart | 2 +- .../cashfusion/fusion_progress_view.dart | 22 ++++++++++---- .../cashfusion/desktop_cashfusion_view.dart | 2 +- .../cashfusion/sub_widgets/fusion_dialog.dart | 30 +++++++++++++++---- 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/fusiondart b/fusiondart index 0d634a48e..1f98575c5 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 0d634a48e180458456aa6bc822bb82098380d114 +Subproject commit 1f98575c58d5b3144ac6e5e613311307c22e53b2 diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 544088b11..e0261e45b 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -9,14 +9,17 @@ */ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; -class FusionProgressView extends StatefulWidget { +class FusionProgressView extends ConsumerStatefulWidget { const FusionProgressView({ super.key, required this.walletId, @@ -27,14 +30,13 @@ class FusionProgressView extends StatefulWidget { final String walletId; @override - State<FusionProgressView> createState() => _FusionProgressViewState(); + ConsumerState<FusionProgressView> createState() => _FusionProgressViewState(); } -class _FusionProgressViewState extends State<FusionProgressView> { +class _FusionProgressViewState extends ConsumerState<FusionProgressView> { /// return true on will cancel, false if cancel cancelled Future<bool> _requestCancel() async { - // - + // TODO return false; } @@ -88,8 +90,16 @@ class _FusionProgressViewState extends State<FusionProgressView> { // TODO: various button states // tempt only show cancel button SecondaryButton( - label: "Cancel", + label: "Cancela", onPressed: () async { + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + await fusionWallet.stop(); + // TODO should this stop be unawaited? + if (await _requestCancel()) { if (mounted) { Navigator.of(context).pop(); diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index b93548bb4..1c0c22821 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -568,7 +568,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { context: context, barrierDismissible: false, builder: (context) { - return FusionDialog( + return FusionDialogView( walletId: widget.walletId, ); }, diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index fdc577e96..6e0399232 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -1,5 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; @@ -14,14 +17,19 @@ class CashFusionState { CashFusionState({required this.status, this.info}); } -class FusionDialog extends StatelessWidget { - const FusionDialog({ +class FusionDialogView extends ConsumerStatefulWidget { + const FusionDialogView({ Key? key, required this.walletId, }) : super(key: key); final String walletId; + @override + ConsumerState<FusionDialogView> createState() => _FusionDialogViewState(); +} + +class _FusionDialogViewState extends ConsumerState<FusionDialogView> { @override Widget build(BuildContext context) { return DesktopDialog( @@ -59,7 +67,7 @@ class FusionDialog extends StatelessWidget { height: 20, ), FusionProgress( - walletId: walletId, + walletId: widget.walletId, ), const SizedBox( height: 12, @@ -72,8 +80,20 @@ class FusionDialog extends StatelessWidget { buttonHeight: ButtonHeight.m, enabled: true, label: "Cancel", - onPressed: () { - Navigator.of(context).pop(true); + onPressed: () async { + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + await fusionWallet.stop(); + // TODO should this stop be unawaited? + + // if (await _requestCancel()) { + if (mounted) { + Navigator.of(context).pop(); + } + // } }, ), ], From 9d4cdb31bd9384bdb30901e0e785969f99dfaec4 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 22:23:27 -0500 Subject: [PATCH 254/379] stop fusion on cashfusion view disposal WIP --- fusiondart | 2 +- lib/pages/cashfusion/cashfusion_view.dart | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 1f98575c5..0b6c2f931 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 1f98575c58d5b3144ac6e5e613311307c22e53b2 +Subproject commit 0b6c2f931932dbd07e6aacc2826b0ceb5332ba99 diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 60c6ad09e..2439890b9 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -85,6 +85,17 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { @override void dispose() { + // Stop the fusion process on dispose. + // + // Hack to stop fusion when a mobile user clicks back. + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + // We probably want to await this and showLoading while it stops. + unawaited(fusionWallet.stop()); + serverController.dispose(); portController.dispose(); fusionRoundController.dispose(); From 5809687116423476b4956ae01d97d2ce1bd19f5c Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 17 Oct 2023 22:38:51 -0500 Subject: [PATCH 255/379] hook back and close buttons up to fusion's stop --- lib/pages/cashfusion/cashfusion_view.dart | 32 ++++++++++++------- .../cashfusion/sub_widgets/fusion_dialog.dart | 22 ++++++++++++- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 2439890b9..9ec2171d7 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -85,17 +85,6 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { @override void dispose() { - // Stop the fusion process on dispose. - // - // Hack to stop fusion when a mobile user clicks back. - final fusionWallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface; - - // We probably want to await this and showLoading while it stops. - unawaited(fusionWallet.stop()); - serverController.dispose(); portController.dispose(); fusionRoundController.dispose(); @@ -116,7 +105,9 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { Theme.of(context).extension<StackColors>()!.background, appBar: AppBar( automaticallyImplyLeading: false, - leading: const AppBarBackButton(), + leading: AppBarBackButton(onPressed: () { + _stop(); + }), title: Text( "CashFusion", style: STextStyles.navBarTitle(context), @@ -457,4 +448,21 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { ), ); } + + /// Stops the fusion process. + /// + /// This is called when the user presses the back button. + void _stop() async { + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + await fusionWallet.stop(); + // TODO await successful cancellation and showLoading while it stops. + + if (mounted) { + Navigator.of(context).pop(); + } + } } diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 6e0399232..975bb6176 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -55,7 +55,9 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), ), DesktopDialogCloseButton( - onPressedOverride: () => Navigator.of(context).pop(true), + onPressedOverride: () { + _stop(); + }, ), ], ), @@ -107,4 +109,22 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), ); } + + /// Stops the fusion process. + /// + /// This is called when the user presses the back button. + void _stop() async { + print(12121212); + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + await fusionWallet.stop(); + // TODO await successful cancellation and showLoading while it stops. + + if (mounted) { + Navigator.of(context).pop(); + } + } } From d2791e005df02b2780aa67902900ce708a65c312 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 08:30:15 -0600 Subject: [PATCH 256/379] misleading text. Tor connection for the required parts of fusion messages happens in the background --- lib/pages/cashfusion/cashfusion_view.dart | 3 +-- .../cashfusion/desktop_cashfusion_view.dart | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 9ec2171d7..e2ec10d6f 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -148,8 +148,7 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { children: [ RoundedWhiteContainer( child: Text( - "CashFusion allows you to anonymize your BCH coins." - " You must be connected to the Tor network.", + "CashFusion allows you to anonymize your BCH coins.", style: STextStyles.w500_12(context).copyWith( color: Theme.of(context) .extension<StackColors>()! diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 1c0c22821..beb9c9647 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -260,8 +260,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { child: Row( children: [ Text( - "CashFusion allows you to anonymize your BCH coins." - "\nYou must be connected to the Tor network.", + "CashFusion allows you to anonymize your BCH coins.", style: STextStyles.desktopTextExtraExtraSmall(context), ), From 91baaa0f16f38bf4b55aa8c889d4e67f42a0cc27 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 09:02:25 -0600 Subject: [PATCH 257/379] show loading n cancel --- lib/pages/cashfusion/cashfusion_view.dart | 90 ++++++++-------- .../cashfusion/fusion_progress_view.dart | 67 +++++++++--- .../cashfusion/desktop_cashfusion_view.dart | 101 +++++++++--------- .../cashfusion/sub_widgets/fusion_dialog.dart | 90 ++++++++++------ .../mixins/fusion_wallet_interface.dart | 4 +- 5 files changed, 205 insertions(+), 147 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index e2ec10d6f..5b34381d4 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -60,6 +60,49 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { FusionOption _option = FusionOption.continuous; + Future<void> _startFusion() async { + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + try { + fusionWallet.uiState = ref.read( + fusionProgressUIStateProvider(widget.walletId), + ); + } catch (e) { + if (!e.toString().contains( + "FusionProgressUIState was already set for ${widget.walletId}")) { + rethrow; + } + } + + final int rounds = _option == FusionOption.continuous + ? 0 + : int.parse(fusionRoundController.text); + + final newInfo = FusionInfo( + host: serverController.text, + port: int.parse(portController.text), + ssl: _enableSSLCheckbox, + rounds: rounds, + ); + + // update user prefs (persistent) + ref.read(prefsChangeNotifierProvider).fusionServerInfo = newInfo; + + unawaited( + fusionWallet.fuse( + fusionInfo: newInfo, + ), + ); + + await Navigator.of(context).pushNamed( + FusionProgressView.routeName, + arguments: widget.walletId, + ); + } + @override void initState() { serverController = TextEditingController(); @@ -388,52 +431,7 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { PrimaryButton( label: "Start", enabled: _enableStartButton, - onPressed: () async { - final fusionWallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface; - - try { - fusionWallet.uiState = ref.read( - fusionProgressUIStateProvider( - widget.walletId), - ); - } catch (e) { - if (!e.toString().contains( - "FusionProgressUIState was already set for ${widget.walletId}")) { - rethrow; - } - } - - final int rounds = - _option == FusionOption.continuous - ? 0 - : int.parse(fusionRoundController.text); - - final newInfo = FusionInfo( - host: serverController.text, - port: int.parse(portController.text), - ssl: _enableSSLCheckbox, - rounds: rounds, - ); - - // update user prefs (persistent) - ref - .read(prefsChangeNotifierProvider) - .fusionServerInfo = newInfo; - - unawaited( - fusionWallet.fuse( - fusionInfo: newInfo, - ), - ); - - await Navigator.of(context).pushNamed( - FusionProgressView.routeName, - arguments: widget.walletId, - ); - }, + onPressed: _startFusion, ), ], ), diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index e0261e45b..c51225f21 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -14,10 +14,14 @@ import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/show_loading.dart'; import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/stack_dialog.dart'; class FusionProgressView extends ConsumerStatefulWidget { const FusionProgressView({ @@ -34,17 +38,56 @@ class FusionProgressView extends ConsumerStatefulWidget { } class _FusionProgressViewState extends ConsumerState<FusionProgressView> { - /// return true on will cancel, false if cancel cancelled - Future<bool> _requestCancel() async { - // TODO - return false; + Future<bool> _requestAndProcessCancel() async { + final shouldCancel = await showDialog<bool?>( + context: context, + barrierDismissible: false, + builder: (_) => StackDialog( + title: "Cancel fusion?", + leftButton: SecondaryButton( + label: "No", + buttonHeight: ButtonHeight.l, + onPressed: () { + Navigator.of(context).pop(false); + }, + ), + rightButton: PrimaryButton( + label: "Yes", + buttonHeight: ButtonHeight.l, + onPressed: () { + Navigator.of(context).pop(true); + }, + ), + ), + ); + + if (shouldCancel == true && mounted) { + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + await showLoading( + whileFuture: Future.wait([ + fusionWallet.stop(), + Future<void>.delayed(const Duration(seconds: 2)), + ]), + context: context, + isDesktop: Util.isDesktop, + message: "Stopping fusion", + ); + + return true; + } else { + return false; + } } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { - return await _requestCancel(); + return await _requestAndProcessCancel(); }, child: Background( child: SafeArea( @@ -55,7 +98,7 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { automaticallyImplyLeading: false, leading: AppBarBackButton( onPressed: () async { - if (await _requestCancel()) { + if (await _requestAndProcessCancel()) { if (mounted) { Navigator.of(context).pop(); } @@ -90,17 +133,9 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { // TODO: various button states // tempt only show cancel button SecondaryButton( - label: "Cancela", + label: "Cancel", onPressed: () async { - final fusionWallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface; - - await fusionWallet.stop(); - // TODO should this stop be unawaited? - - if (await _requestCancel()) { + if (await _requestAndProcessCancel()) { if (mounted) { Navigator.of(context).pop(); } diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index beb9c9647..7a2abc6a5 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -64,6 +64,55 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { FusionOption _roundType = FusionOption.continuous; + Future<void> _startFusion() async { + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + try { + fusionWallet.uiState = ref.read( + fusionProgressUIStateProvider(widget.walletId), + ); + } catch (e) { + if (!e.toString().contains( + "FusionProgressUIState was already set for ${widget.walletId}")) { + rethrow; + } + } + + final int rounds = _roundType == FusionOption.continuous + ? 0 + : int.parse(fusionRoundController.text); + + final newInfo = FusionInfo( + host: serverController.text, + port: int.parse(portController.text), + ssl: _enableSSLCheckbox, + rounds: rounds, + ); + + // update user prefs (persistent) + ref.read(prefsChangeNotifierProvider).fusionServerInfo = newInfo; + + unawaited( + fusionWallet.fuse( + fusionInfo: newInfo, + ), + ); + // unawaited(fusionWallet.stepThruUiStates()); + + await showDialog<void>( + context: context, + barrierDismissible: false, + builder: (context) { + return FusionDialogView( + walletId: widget.walletId, + ); + }, + ); + } + @override void initState() { serverController = TextEditingController(); @@ -522,57 +571,7 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { PrimaryButton( label: "Start", enabled: _enableStartButton, - onPressed: () async { - final fusionWallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface; - - try { - fusionWallet.uiState = ref.read( - fusionProgressUIStateProvider(widget.walletId), - ); - } catch (e) { - if (!e.toString().contains( - "FusionProgressUIState was already set for ${widget.walletId}")) { - rethrow; - } - } - - final int rounds = - _roundType == FusionOption.continuous - ? 0 - : int.parse(fusionRoundController.text); - - final newInfo = FusionInfo( - host: serverController.text, - port: int.parse(portController.text), - ssl: _enableSSLCheckbox, - rounds: rounds, - ); - - // update user prefs (persistent) - ref - .read(prefsChangeNotifierProvider) - .fusionServerInfo = newInfo; - - unawaited( - fusionWallet.fuse( - fusionInfo: newInfo, - ), - ); - // unawaited(fusionWallet.stepThruUiStates()); - - await showDialog<void>( - context: context, - barrierDismissible: false, - builder: (context) { - return FusionDialogView( - walletId: widget.walletId, - ); - }, - ); - }, + onPressed: _startFusion, ), ], ), diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 975bb6176..ff1a7a7bc 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -3,10 +3,13 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; +import 'package:stackwallet/utilities/show_loading.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/stack_dialog.dart'; enum CashFusionStatus { waiting, running, success, failed } @@ -30,6 +33,51 @@ class FusionDialogView extends ConsumerStatefulWidget { } class _FusionDialogViewState extends ConsumerState<FusionDialogView> { + Future<bool> _requestAndProcessCancel() async { + final shouldCancel = await showDialog<bool?>( + context: context, + barrierDismissible: false, + builder: (_) => StackDialog( + title: "Cancel fusion?", + leftButton: SecondaryButton( + label: "No", + buttonHeight: ButtonHeight.l, + onPressed: () { + Navigator.of(context).pop(false); + }, + ), + rightButton: PrimaryButton( + label: "Yes", + buttonHeight: ButtonHeight.l, + onPressed: () { + Navigator.of(context).pop(true); + }, + ), + ), + ); + + if (shouldCancel == true && mounted) { + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + await showLoading( + whileFuture: Future.wait([ + fusionWallet.stop(), + Future<void>.delayed(const Duration(seconds: 2)), + ]), + context: context, + isDesktop: true, + message: "Stopping fusion", + ); + + return true; + } else { + return false; + } + } + @override Widget build(BuildContext context) { return DesktopDialog( @@ -55,8 +103,12 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), ), DesktopDialogCloseButton( - onPressedOverride: () { - _stop(); + onPressedOverride: () async { + if (await _requestAndProcessCancel()) { + if (mounted) { + Navigator.of(context).pop(); + } + } }, ), ], @@ -83,19 +135,11 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { enabled: true, label: "Cancel", onPressed: () async { - final fusionWallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface; - - await fusionWallet.stop(); - // TODO should this stop be unawaited? - - // if (await _requestCancel()) { - if (mounted) { - Navigator.of(context).pop(); + if (await _requestAndProcessCancel()) { + if (mounted) { + Navigator.of(context).pop(); + } } - // } }, ), ], @@ -109,22 +153,4 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), ); } - - /// Stops the fusion process. - /// - /// This is called when the user presses the back button. - void _stop() async { - print(12121212); - final fusionWallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface; - - await fusionWallet.stop(); - // TODO await successful cancellation and showLoading while it stops. - - if (mounted) { - Navigator.of(context).pop(); - } - } } diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 8979ecda6..7d4841b5b 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -531,7 +531,7 @@ mixin FusionWalletInterface { /// /// This function is called when the user taps the "Cancel" button in the UI /// or closes the fusion progress dialog. - Future<void>? stop() { - return _mainFusionObject?.stop(); + Future<void> stop() async { + await _mainFusionObject?.stop(); } } From 2d04e9d857f8b3044ef2e38cc4f1f63a2adf45f9 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 18 Oct 2023 11:27:25 -0500 Subject: [PATCH 258/379] use a DesktopDialog WIP, it doesn't look exactly right... --- .../cashfusion/sub_widgets/fusion_dialog.dart | 69 ++++++++++++++----- 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index ff1a7a7bc..794135e20 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -9,7 +9,6 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; -import 'package:stackwallet/widgets/stack_dialog.dart'; enum CashFusionStatus { waiting, running, success, failed } @@ -37,21 +36,59 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { final shouldCancel = await showDialog<bool?>( context: context, barrierDismissible: false, - builder: (_) => StackDialog( - title: "Cancel fusion?", - leftButton: SecondaryButton( - label: "No", - buttonHeight: ButtonHeight.l, - onPressed: () { - Navigator.of(context).pop(false); - }, - ), - rightButton: PrimaryButton( - label: "Yes", - buttonHeight: ButtonHeight.l, - onPressed: () { - Navigator.of(context).pop(true); - }, + builder: (_) => DesktopDialog( + maxWidth: 580, + maxHeight: double.infinity, + child: Padding( + padding: const EdgeInsets.only( + left: 32, + right: 32, + top: 0, + bottom: 32, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Cancel fusion?", + style: STextStyles.desktopH3(context), + ), + DesktopDialogCloseButton( + onPressedOverride: () => Navigator.of(context).pop(true), + ), + ], + ), + const SizedBox(height: 20), + Text( + "Do you really want to cancel the fusion process?", + style: STextStyles.smallMed14(context), + ), + const SizedBox(height: 40), + Row( + children: [ + Expanded( + child: SecondaryButton( + label: "No", + onPressed: () { + Navigator.of(context).pop(false); + }, + ), + ), + const SizedBox(width: 8), + Expanded( + child: PrimaryButton( + label: "Yes", + onPressed: () { + Navigator.of(context).pop(true); + }, + ), + ), + ], + ), + ], + ), ), ), ); From 05ab819f69652a35e1d1a070cd8b0246d628fabb Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 18 Oct 2023 11:31:59 -0500 Subject: [PATCH 259/379] don't pad the close button so far away from the corner of the dialog --- .../cashfusion/sub_widgets/fusion_dialog.dart | 62 +++++++++++-------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 794135e20..9b6e5b5be 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -42,7 +42,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { child: Padding( padding: const EdgeInsets.only( left: 32, - right: 32, + right: 0, top: 0, bottom: 32, ), @@ -60,32 +60,44 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), ], ), - const SizedBox(height: 20), - Text( - "Do you really want to cancel the fusion process?", - style: STextStyles.smallMed14(context), - ), - const SizedBox(height: 40), - Row( - children: [ - Expanded( - child: SecondaryButton( - label: "No", - onPressed: () { - Navigator.of(context).pop(false); - }, + Padding( + padding: const EdgeInsets.only( + left: 0, + right: 32, + top: 0, + bottom: 0, + ), + child: Column( + children: [ + const SizedBox(height: 20), + Text( + "Do you really want to cancel the fusion process?", + style: STextStyles.smallMed14(context), ), - ), - const SizedBox(width: 8), - Expanded( - child: PrimaryButton( - label: "Yes", - onPressed: () { - Navigator.of(context).pop(true); - }, + const SizedBox(height: 40), + Row( + children: [ + Expanded( + child: SecondaryButton( + label: "No", + onPressed: () { + Navigator.of(context).pop(false); + }, + ), + ), + const SizedBox(width: 8), + Expanded( + child: PrimaryButton( + label: "Yes", + onPressed: () { + Navigator.of(context).pop(true); + }, + ), + ), + ], ), - ), - ], + ], + ), ), ], ), From ad80a84990ea247603c0c90c2f775a4c206a41a7 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 10:34:29 -0600 Subject: [PATCH 260/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 0b6c2f931..3fc8f55ae 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 0b6c2f931932dbd07e6aacc2826b0ceb5332ba99 +Subproject commit 3fc8f55ae58e87bc7282eedb7c7ba60dde67610a From 827fcb0cc82cef50e278277f74df5eb257666848 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 18 Oct 2023 11:36:14 -0500 Subject: [PATCH 261/379] increase button spacing and use standard size extAlign: TextAlign.left not workign as expected --- .../cashfusion/sub_widgets/fusion_dialog.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 9b6e5b5be..82495a185 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -73,6 +73,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { Text( "Do you really want to cancel the fusion process?", style: STextStyles.smallMed14(context), + textAlign: TextAlign.left, ), const SizedBox(height: 40), Row( @@ -80,15 +81,17 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { Expanded( child: SecondaryButton( label: "No", + buttonHeight: ButtonHeight.l, onPressed: () { Navigator.of(context).pop(false); }, ), ), - const SizedBox(width: 8), + const SizedBox(width: 16), Expanded( child: PrimaryButton( label: "Yes", + buttonHeight: ButtonHeight.l, onPressed: () { Navigator.of(context).pop(true); }, From 4f87c4d943cc8cea6c891530faa348a17cf4c254 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 18 Oct 2023 11:39:45 -0500 Subject: [PATCH 262/379] align close d ialog text to left --- .../cashfusion/sub_widgets/fusion_dialog.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 82495a185..040a1a0ff 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -68,6 +68,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { bottom: 0, ), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 20), Text( From 72c045a8fcdf4e49b2e48bbc90e545b10f945c1c Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 18 Oct 2023 11:40:00 -0500 Subject: [PATCH 263/379] less spacing between dialog title and message --- .../cashfusion/sub_widgets/fusion_dialog.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 040a1a0ff..2f4411366 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -70,7 +70,6 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const SizedBox(height: 20), Text( "Do you really want to cancel the fusion process?", style: STextStyles.smallMed14(context), From e771fb383ce5bc96e550dc64750e08af7726ad88 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 10:56:20 -0600 Subject: [PATCH 264/379] duplicate index error fix --- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 7d241ce1d..e9dd38d54 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -249,7 +249,7 @@ class BitcoinCashWallet extends CoinServiceAPI DerivePathTypeExt.primaryFor(coin), ); nextIndex++; - await db.putAddress(address); + await db.updateOrPutAddresses([address]); // check if it has been used before adding if (await _isUnused(address.value)) { From 5359980b54f937a67d3a0e443939800635b18413 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 18 Oct 2023 12:29:54 -0500 Subject: [PATCH 265/379] No such mempool or blockchain transaction --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 3fc8f55ae..8cc895256 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 3fc8f55ae58e87bc7282eedb7c7ba60dde67610a +Subproject commit 8cc89525694bdc64e4c0110a63c1a825d8d79e84 From 2439163ef528150d250776b9cba611d2aa7a903d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 12:11:52 -0600 Subject: [PATCH 266/379] don't cancel fusion on dialog closed --- .../cashfusion/sub_widgets/fusion_dialog.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 2f4411366..a693bac44 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -56,7 +56,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { style: STextStyles.desktopH3(context), ), DesktopDialogCloseButton( - onPressedOverride: () => Navigator.of(context).pop(true), + onPressedOverride: () => Navigator.of(context).pop(false), ), ], ), From 9908fe0c4f10446f7accb15a8b26b81818004fa4 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 12:19:28 -0600 Subject: [PATCH 267/379] flexible width button and proper left and right padding --- .../cashfusion/sub_widgets/fusion_dialog.dart | 101 +++++++++--------- 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index a693bac44..0d7e8f92b 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -135,54 +135,53 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { return DesktopDialog( maxHeight: 600, child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.only( - top: 10, - left: 20, - bottom: 20, - right: 10, - ), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.only(left: 10.0), - child: Text( - "Fusion progress", - style: STextStyles.desktopH2(context), - ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only(left: 32), + child: Text( + "Fusion progress", + style: STextStyles.desktopH2(context), ), - DesktopDialogCloseButton( - onPressedOverride: () async { - if (await _requestAndProcessCancel()) { - if (mounted) { - Navigator.of(context).pop(); - } + ), + DesktopDialogCloseButton( + onPressedOverride: () async { + if (await _requestAndProcessCancel()) { + if (mounted) { + Navigator.of(context).pop(); } - }, - ), - ], + } + }, + ), + ], + ), + Padding( + padding: const EdgeInsets.only( + top: 20, + left: 32, + right: 32, + bottom: 32, ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 10.0), - child: Column( - children: [ - const SizedBox( - height: 20, - ), - FusionProgress( - walletId: widget.walletId, - ), - const SizedBox( - height: 12, - ), - Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - SecondaryButton( - width: 248, + child: Column( + children: [ + FusionProgress( + walletId: widget.walletId, + ), + const SizedBox( + height: 12, + ), + Row( + children: [ + // spacer can be replaced with a button inside an expanded if a second button is wanted here + const Spacer(), + const SizedBox( + width: 16, + ), + Expanded( + child: SecondaryButton( buttonHeight: ButtonHeight.m, enabled: true, label: "Cancel", @@ -194,13 +193,13 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { } }, ), - ], - ), - ], - ), + ), + ], + ), + ], ), - ], - ), + ), + ], ), ), ); From 7a59f6020eea7b16a24142774d7b6900a001f965 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 12:44:05 -0600 Subject: [PATCH 268/379] do fusion runs with a new set of updated wallet UTXOs --- .../coins/bitcoincash/bitcoincash_wallet.dart | 1 + .../mixins/fusion_wallet_interface.dart | 134 ++++++++++-------- 2 files changed, 73 insertions(+), 62 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index e9dd38d54..e4a0125e0 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -142,6 +142,7 @@ class BitcoinCashWallet extends CoinServiceAPI getWalletCachedElectrumX: () => cachedElectrumXClient, getNextUnusedChangeAddress: _getUnusedChangeAddresses, getChainHeight: () async => chainHeight, + updateWalletUTXOS: _updateUTXOs, mnemonic: mnemonicString, mnemonicPassphrase: mnemonicPassphrase, network: _network, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 7d4841b5b..b1fa0f33d 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -123,9 +123,11 @@ mixin FusionWalletInterface { _getNextUnusedChangeAddresses; late final CachedElectrumX Function() _getWalletCachedElectrumX; late final Future<int> Function() _getChainHeight; + late final Future<void> Function() _updateWalletUTXOS; // Fusion object. fusion.Fusion? _mainFusionObject; + bool _stopRequested = false; /// Initializes the FusionWalletInterface mixin. /// @@ -138,6 +140,7 @@ mixin FusionWalletInterface { getNextUnusedChangeAddress, required CachedElectrumX Function() getWalletCachedElectrumX, required Future<int> Function() getChainHeight, + required Future<void> Function() updateWalletUTXOS, required Future<String?> mnemonic, required Future<String?> mnemonicPassphrase, required btcdart.NetworkType network, @@ -150,6 +153,7 @@ mixin FusionWalletInterface { _torService = FusionTorService.sharedInstance; _getWalletCachedElectrumX = getWalletCachedElectrumX; _getChainHeight = getChainHeight; + _updateWalletUTXOS = updateWalletUTXOS; _mnemonic = mnemonic; _mnemonicPassphrase = mnemonicPassphrase; _network = network; @@ -409,7 +413,6 @@ mixin FusionWalletInterface { serverHost: fusionInfo.host, serverPort: fusionInfo.port, serverSsl: fusionInfo.ssl, - roundCount: fusionInfo.rounds, ); // Instantiate a Fusion object with custom parameters. @@ -453,78 +456,84 @@ mixin FusionWalletInterface { }, ); - // Add unfrozen stack UTXOs. - final List<UTXO> walletUtxos = await _db - .getUTXOs(_walletId) - .filter() - .isBlockedEqualTo(false) - .and() - .addressIsNotNull() - .findAll(); - final List<fusion.UtxoDTO> coinList = []; + int fuzeCount = fusionInfo.rounds; + _stopRequested = false; - // Loop through UTXOs, checking and adding valid ones. - for (final utxo in walletUtxos) { - final String addressString = utxo.address!; - final List<String> possibleAddresses = [addressString]; + while (fuzeCount > 0 && !_stopRequested) { + fuzeCount--; - if (bitbox.Address.detectFormat(addressString) == - bitbox.Address.formatCashAddr) { - possibleAddresses.add(bitbox.Address.toLegacyAddress(addressString)); - } else { - possibleAddresses.add(bitbox.Address.toCashAddress(addressString)); - } + // refresh wallet utxos + await _updateWalletUTXOS(); - // Fetch address to get pubkey - final addr = await _db - .getAddresses(_walletId) + // Add unfrozen stack UTXOs. + final List<UTXO> walletUtxos = await _db + .getUTXOs(_walletId) .filter() - .anyOf<String, QueryBuilder<Address, Address, QAfterFilterCondition>>( - possibleAddresses, (q, e) => q.valueEqualTo(e)) + .isBlockedEqualTo(false) .and() - .group((q) => q - .subTypeEqualTo(AddressSubType.change) - .or() - .subTypeEqualTo(AddressSubType.receiving)) - .and() - .typeEqualTo(AddressType.p2pkh) - .findFirst(); + .addressIsNotNull() + .findAll(); - // depending on the address type in the query above this can be null - if (addr == null) { - // A utxo object should always have a non null address. - // If non found then just ignore the UTXO (aka don't fuse it) - Logging.instance.log( - "Ignoring utxo=$utxo for address=\"$addressString\" while selecting UTXOs for Fusion", - level: LogLevel.Info, + final List<fusion.UtxoDTO> coinList = []; + // Loop through UTXOs, checking and adding valid ones. + for (final utxo in walletUtxos) { + final String addressString = utxo.address!; + final List<String> possibleAddresses = [addressString]; + + if (bitbox.Address.detectFormat(addressString) == + bitbox.Address.formatCashAddr) { + possibleAddresses.add(bitbox.Address.toLegacyAddress(addressString)); + } else { + possibleAddresses.add(bitbox.Address.toCashAddress(addressString)); + } + + // Fetch address to get pubkey + final addr = await _db + .getAddresses(_walletId) + .filter() + .anyOf<String, + QueryBuilder<Address, Address, QAfterFilterCondition>>( + possibleAddresses, (q, e) => q.valueEqualTo(e)) + .and() + .group((q) => q + .subTypeEqualTo(AddressSubType.change) + .or() + .subTypeEqualTo(AddressSubType.receiving)) + .and() + .typeEqualTo(AddressType.p2pkh) + .findFirst(); + + // depending on the address type in the query above this can be null + if (addr == null) { + // A utxo object should always have a non null address. + // If non found then just ignore the UTXO (aka don't fuse it) + Logging.instance.log( + "Ignoring utxo=$utxo for address=\"$addressString\" while selecting UTXOs for Fusion", + level: LogLevel.Info, + ); + continue; + } + + final dto = fusion.UtxoDTO( + txid: utxo.txid, + vout: utxo.vout, + value: utxo.value, + address: utxo.address!, + pubKey: addr.publicKey, ); - continue; + + // Add UTXO to coinList. + coinList.add(dto); } - final dto = fusion.UtxoDTO( - txid: utxo.txid, - vout: utxo.vout, - value: utxo.value, - address: utxo.address!, - pubKey: addr.publicKey, + // Fuse UTXOs. + await _mainFusionObject!.fuse( + inputsFromWallet: coinList, + network: _coin.isTestNet + ? fusion.Utilities.testNet + : fusion.Utilities.mainNet, ); - - // Add UTXO to coinList. - coinList.add(dto); } - - // Fuse UTXOs. - return await _mainFusionObject!.fuse( - inputsFromWallet: coinList, - network: - _coin.isTestNet ? fusion.Utilities.testNet : fusion.Utilities.mainNet, - ); - } - - Future<void> refreshFusion() { - // TODO - throw UnimplementedError( - "TODO refreshFusion eg look up number of fusion participants connected/coordinating"); } /// Stop the fusion process. @@ -532,6 +541,7 @@ mixin FusionWalletInterface { /// This function is called when the user taps the "Cancel" button in the UI /// or closes the fusion progress dialog. Future<void> stop() async { + _stopRequested = true; await _mainFusionObject?.stop(); } } From ef08f526da186f12ee063b8b4b25238c8038b0aa Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 12:44:15 -0600 Subject: [PATCH 269/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 8cc895256..b7426f976 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 8cc89525694bdc64e4c0110a63c1a825d8d79e84 +Subproject commit b7426f976d02926cd14da6944f8b918e7ad391cd From 085ac707465fcabab19546593af250613f9dc434 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 13:10:19 -0600 Subject: [PATCH 270/379] try again on fuze fail if while condition is still valid --- .../mixins/fusion_wallet_interface.dart | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index b1fa0f33d..b70d99c03 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -527,12 +527,20 @@ mixin FusionWalletInterface { } // Fuse UTXOs. - await _mainFusionObject!.fuse( - inputsFromWallet: coinList, - network: _coin.isTestNet - ? fusion.Utilities.testNet - : fusion.Utilities.mainNet, - ); + try { + await _mainFusionObject!.fuse( + inputsFromWallet: coinList, + network: _coin.isTestNet + ? fusion.Utilities.testNet + : fusion.Utilities.mainNet, + ); + } catch (e, s) { + Logging.instance.log( + "$e\n$s", + level: LogLevel.Error, + ); + // just continue on attempt failure + } } } From 31bee9519e2641af75e7aa203569fb433d58307e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 13:10:35 -0600 Subject: [PATCH 271/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index b7426f976..b93220d2f 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit b7426f976d02926cd14da6944f8b918e7ad391cd +Subproject commit b93220d2f133ac076e7ebe7f433bd6f248721e16 From 2e83d57ad951ea47dd029a3f460d7c32e73258e3 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 13:25:07 -0600 Subject: [PATCH 272/379] freeze/block utxos containing cash tokens --- .../coins/bitcoincash/bitcoincash_wallet.dart | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index e4a0125e0..abf8ab4e6 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -31,6 +31,7 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart' import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/models/signing_data.dart'; +import 'package:stackwallet/services/coins/bitcoincash/cashtokens.dart' as ct; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/refresh_percent_changed_event.dart'; @@ -52,6 +53,7 @@ import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart'; +import 'package:stackwallet/utilities/extensions/impl/string.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; @@ -1724,24 +1726,48 @@ class BitcoinCashWallet extends CoinServiceAPI final outputs = txn["vout"] as List; + String? scriptPubKey; String? utxoOwnerAddress; // get UTXO owner address for (final output in outputs) { if (output["n"] == vout) { + scriptPubKey = output["scriptPubKey"]?["hex"] as String?; utxoOwnerAddress = output["scriptPubKey"]?["addresses"]?[0] as String? ?? output["scriptPubKey"]?["address"] as String?; } } + bool blocked = false; + String? blockedReason; + + if (scriptPubKey != null) { + // check for cash tokens + try { + final ctOutput = ct.unwrap_spk(scriptPubKey.toUint8ListFromHex); + if (ctOutput.token_data != null) { + // found a token! + blocked = true; + blockedReason = "Cash token detected on output"; + } + } catch (e, s) { + // Probably doesn't contain a cash token so just log failure + Logging.instance.log( + "Script pub key \"$scriptPubKey\" cash token" + " parsing check failed: $e\n$s", + level: LogLevel.Warning, + ); + } + } + final utxo = isar_models.UTXO( walletId: walletId, txid: txn["txid"] as String, vout: vout, value: jsonUTXO["value"] as int, name: "", - isBlocked: false, - blockedReason: null, + isBlocked: blocked, + blockedReason: blockedReason, isCoinbase: txn["is_coinbase"] as bool? ?? false, blockHash: txn["blockhash"] as String?, blockHeight: jsonUTXO["height"] as int?, From be3f82e07045f1a2f28fa5aabe9360acdd67e08e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 13:58:56 -0600 Subject: [PATCH 273/379] "see all" token txns fix --- .../token_transaction_list_widget.dart | 4 ++-- lib/pages/token_view/token_view.dart | 5 ++++- .../transaction_views/all_transactions_view.dart | 16 +++++++++++----- .../wallet_view/desktop_token_view.dart | 5 ++++- lib/route_generator.dart | 12 ++++++++++++ 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/lib/pages/token_view/sub_widgets/token_transaction_list_widget.dart b/lib/pages/token_view/sub_widgets/token_transaction_list_widget.dart index 68f5c76b8..e460fbe53 100644 --- a/lib/pages/token_view/sub_widgets/token_transaction_list_widget.dart +++ b/lib/pages/token_view/sub_widgets/token_transaction_list_widget.dart @@ -225,8 +225,8 @@ class _TransactionsListState extends ConsumerState<TokenTransactionsList> { _hasLoaded = true; } if (!_hasLoaded) { - return Column( - children: const [ + return const Column( + children: [ Spacer(), Center( child: LoadingIndicator( diff --git a/lib/pages/token_view/token_view.dart b/lib/pages/token_view/token_view.dart index 8cff2fcfc..54f0efe58 100644 --- a/lib/pages/token_view/token_view.dart +++ b/lib/pages/token_view/token_view.dart @@ -191,7 +191,10 @@ class _TokenViewState extends ConsumerState<TokenView> { onTap: () { Navigator.of(context).pushNamed( AllTransactionsView.routeName, - arguments: widget.walletId, + arguments: ( + walletId: widget.walletId, + isTokens: true, + ), ); }, ), diff --git a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart index 32cd8fb30..002376ca3 100644 --- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart +++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart @@ -17,6 +17,7 @@ import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart' import 'package:stackwallet/models/isar/models/contact_entry.dart'; import 'package:stackwallet/models/transaction_filter.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/pages/token_view/token_view.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_search_filter_view.dart'; @@ -50,11 +51,13 @@ class AllTransactionsView extends ConsumerStatefulWidget { const AllTransactionsView({ Key? key, required this.walletId, + this.isTokens = false, }) : super(key: key); static const String routeName = "/allTransactions"; final String walletId; + final bool isTokens; @override ConsumerState<AllTransactionsView> createState() => @@ -445,12 +448,12 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> { ), if (isDesktop && ref.watch(transactionFilterProvider.state).state != null) - Padding( - padding: const EdgeInsets.symmetric( + const Padding( + padding: EdgeInsets.symmetric( vertical: 8, ), child: Row( - children: const [ + children: [ TransactionFilterOptionBar(), ], ), @@ -472,8 +475,11 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> { // debugPrint("Consumer build called"); return FutureBuilder( - future: ref.watch( - managerProvider.select((value) => value.transactions)), + future: widget.isTokens + ? ref.watch(tokenServiceProvider + .select((value) => value!.transactions)) + : ref.watch(managerProvider + .select((value) => value.transactions)), builder: (_, AsyncSnapshot<List<Transaction>> snapshot) { if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) { diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_token_view.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_token_view.dart index 18edc2bff..b03b67959 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_token_view.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_token_view.dart @@ -218,7 +218,10 @@ class _DesktopTokenViewState extends ConsumerState<DesktopTokenView> { onTap: () { Navigator.of(context).pushNamed( AllTransactionsView.routeName, - arguments: widget.walletId, + arguments: ( + walletId: widget.walletId, + isTokens: true, + ), ); }, ), diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 14affaaf1..468ee5f11 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -1260,6 +1260,18 @@ class RouteGenerator { return _routeError("${settings.name} invalid args: ${args.toString()}"); case AllTransactionsView.routeName: + if (args is ({String walletId, bool isTokens})) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => AllTransactionsView( + walletId: args.walletId, + isTokens: args.isTokens, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } if (args is String) { return getRoute( shouldUseMaterialRoute: useMaterialPageRoute, From b0338aa76ad80846cc696ea57f024af201a06b22 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 14:46:57 -0600 Subject: [PATCH 274/379] quick and dirty SLP check --- lib/services/coins/bitcoincash/bch_utils.dart | 29 +++++++++++++++++++ .../coins/bitcoincash/bch_utils_test.dart | 25 ++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 lib/services/coins/bitcoincash/bch_utils.dart create mode 100644 test/services/coins/bitcoincash/bch_utils_test.dart diff --git a/lib/services/coins/bitcoincash/bch_utils.dart b/lib/services/coins/bitcoincash/bch_utils.dart new file mode 100644 index 000000000..296ecbdab --- /dev/null +++ b/lib/services/coins/bitcoincash/bch_utils.dart @@ -0,0 +1,29 @@ +import 'dart:typed_data'; + +import 'package:bitcoindart/src/utils/constants/op.dart' as op; +import 'package:bitcoindart/src/utils/script.dart' as bscript; + +abstract final class BchUtils { + static bool isSLP(Uint8List scriptPubKey) { + const id = [83, 76, 80, 0]; // 'SLP\x00' + final decompiled = bscript.decompile(scriptPubKey); + + if (decompiled != null && + decompiled.length > 1 && + decompiled.first == op.OPS["OP_RETURN"]) { + final _id = decompiled[1]; + + if (_id is List<int> && _id.length == id.length) { + for (int i = 0; i < id.length; i++) { + if (_id[i] != id[i]) { + return false; + } + } + // lists match! + return true; + } + } + + return false; + } +} diff --git a/test/services/coins/bitcoincash/bch_utils_test.dart b/test/services/coins/bitcoincash/bch_utils_test.dart new file mode 100644 index 000000000..c25aee4fa --- /dev/null +++ b/test/services/coins/bitcoincash/bch_utils_test.dart @@ -0,0 +1,25 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:stackwallet/services/coins/bitcoincash/bch_utils.dart'; +import 'package:stackwallet/utilities/extensions/impl/string.dart'; + +void main() { + test("script pub key check for SLP is true", () { + expect( + BchUtils.isSLP( + "6a04534c500001010747454e45534953044d5430320f4d757461626c652054657374" + "2030321668747470733a2f2f46756c6c537461636b2e63617368200e9a18" + "8911ec0f2ac10cc9425b457d10ba14151a64eb4640f95ed7dab9e8f62601" + "004c00080000000000000001" + .toUint8ListFromHex), + true, + ); + }); + + test("script pub key check for SLP is not true", () { + expect( + BchUtils.isSLP("76a914a78bb9aa1b54c859b5fe72e6f6f576248b3231c888ac" + .toUint8ListFromHex), + false, + ); + }); +} From a1941959337ecf2d25e7431d2def0fc3e369a576 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 14:51:53 -0600 Subject: [PATCH 275/379] use SLP check when fetching UTXOs --- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index abf8ab4e6..05aa2c593 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -31,6 +31,7 @@ import 'package:stackwallet/models/isar/models/blockchain_data/address.dart' import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/models/signing_data.dart'; +import 'package:stackwallet/services/coins/bitcoincash/bch_utils.dart'; import 'package:stackwallet/services/coins/bitcoincash/cashtokens.dart' as ct; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; @@ -1748,7 +1749,7 @@ class BitcoinCashWallet extends CoinServiceAPI if (ctOutput.token_data != null) { // found a token! blocked = true; - blockedReason = "Cash token detected on output"; + blockedReason = "Cash token output detected"; } } catch (e, s) { // Probably doesn't contain a cash token so just log failure @@ -1758,6 +1759,12 @@ class BitcoinCashWallet extends CoinServiceAPI level: LogLevel.Warning, ); } + + // check for SLP tokens if not already blocked + if (!blocked && BchUtils.isSLP(scriptPubKey.toUint8ListFromHex)) { + blocked = true; + blockedReason = "SLP token output detected"; + } } final utxo = isar_models.UTXO( From 1d011afa5700f8dd18a46e63c431cc20d6406acb Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 18 Oct 2023 16:09:01 -0500 Subject: [PATCH 276/379] fuzeCount logic change --- lib/services/mixins/fusion_wallet_interface.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index b70d99c03..fe49fa7c6 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -456,11 +456,17 @@ mixin FusionWalletInterface { }, ); - int fuzeCount = fusionInfo.rounds; + int fuzeCount = 0; _stopRequested = false; - while (fuzeCount > 0 && !_stopRequested) { - fuzeCount--; + while (!_stopRequested) { + if (fusionInfo.rounds > 0) { + if (fuzeCount >= fusionInfo.rounds) { + _stopRequested = true; + } + } + + fuzeCount++; // refresh wallet utxos await _updateWalletUTXOS(); From 8e3e1db3cd02e51bb1ae0fdb6b808539f077e741 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 15:50:14 -0600 Subject: [PATCH 277/379] WIP txn V2 --- .../blockchain_data/v2/transaction_v2.dart | 240 ++++++++++++++++++ lib/services/mixins/electrum_x_parsing.dart | 5 +- 2 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 lib/models/isar/models/blockchain_data/v2/transaction_v2.dart diff --git a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart new file mode 100644 index 000000000..a77cacdea --- /dev/null +++ b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart @@ -0,0 +1,240 @@ +import 'package:decimal/decimal.dart'; + +class TransactionV2 { + final String hash; + final String txid; + + final int size; + final int lockTime; + + final DateTime? blockTime; + final String? blockHash; + + final List<InputV2> inputs; + final List<OutputV2> outputs; + + TransactionV2({ + required this.blockHash, + required this.hash, + required this.txid, + required this.lockTime, + required this.size, + required this.blockTime, + required this.inputs, + required this.outputs, + }); + + static TransactionV2 fromElectrumXJson(Map<String, dynamic> json) { + try { + final inputs = (json["vin"] as List).map( + (e) => InputV2.fromElectrumXJson( + Map<String, dynamic>.from(e as Map), + ), + ); + final outputs = (json["vout"] as List).map( + (e) => OutputV2.fromElectrumXJson( + Map<String, dynamic>.from(e as Map), + ), + ); + + final blockTimeUnix = json["blocktime"] as int?; + DateTime? blockTime; + if (blockTimeUnix != null) { + blockTime = DateTime.fromMillisecondsSinceEpoch( + blockTimeUnix * 1000, + isUtc: true, + ); + } + + return TransactionV2( + blockHash: json["blockhash"] as String?, + hash: json["hash"] as String, + txid: json["txid"] as String, + lockTime: json["locktime"] as int, + size: json["size"] as int, + blockTime: blockTime, + inputs: List.unmodifiable(inputs), + outputs: List.unmodifiable(outputs), + ); + } catch (e) { + throw Exception( + "Failed to parse TransactionV2 for txid=${json["txid"]}: $e", + ); + } + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is TransactionV2 && + other.hash == hash && + other.txid == txid && + other.size == size && + other.lockTime == lockTime && + other.blockTime == blockTime && + other.blockHash == blockHash && + _listEquals(other.inputs, inputs) && + _listEquals(other.outputs, outputs); + } + + @override + int get hashCode => Object.hash( + hash, + txid, + size, + lockTime, + blockTime, + blockHash, + inputs, + outputs, + ); + + @override + String toString() { + return 'TransactionV2(\n' + ' hash: $hash,\n' + ' txid: $txid,\n' + ' size: $size,\n' + ' lockTime: $lockTime,\n' + ' blockTime: $blockTime,\n' + ' blockHash: $blockHash,\n' + ' inputs: $inputs,\n' + ' outputs: $outputs,\n' + ')'; + } +} + +class InputV2 { + final String scriptSigHex; + final int sequence; + final String txid; + final int vout; + + InputV2({ + required this.scriptSigHex, + required this.sequence, + required this.txid, + required this.vout, + }); + + static InputV2 fromElectrumXJson(Map<String, dynamic> json) { + try { + return InputV2( + scriptSigHex: json["scriptSig"]["hex"] as String, + sequence: json["sequence"] as int, + txid: json["txid"] as String, + vout: json["vout"] as int); + } catch (e) { + throw Exception("Failed to parse InputV2 from $json"); + } + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is InputV2 && + other.scriptSigHex == scriptSigHex && + other.sequence == sequence && + other.txid == txid && + other.vout == vout; + } + + @override + int get hashCode => Object.hash( + scriptSigHex, + sequence, + txid, + vout, + ); + + @override + String toString() { + return 'InputV2(\n' + ' scriptSigHex: $scriptSigHex,\n' + ' sequence: $sequence,\n' + ' txid: $txid,\n' + ' vout: $vout,\n' + ')'; + } +} + +class OutputV2 { + final String scriptPubKeyHex; + final String valueStringSats; + + BigInt get value => BigInt.parse(valueStringSats); + + OutputV2({ + required this.scriptPubKeyHex, + required this.valueStringSats, + }); + + // TODO: move this to a subclass based on coin since we don't know if the value will be sats or a decimal amount + // For now assume 8 decimal places + @Deprecated("See TODO and comments") + static OutputV2 fromElectrumXJson(Map<String, dynamic> json) { + try { + final temp = Decimal.parse(json["value"].toString()); + if (temp < Decimal.zero) { + throw Exception("Negative value found"); + } + + final String valueStringSats; + if (temp.isInteger) { + valueStringSats = temp.toString(); + } else { + valueStringSats = temp.shift(8).toBigInt().toString(); + } + + return OutputV2( + scriptPubKeyHex: json["scriptPubKey"]["hex"] as String, + valueStringSats: valueStringSats, + ); + } catch (e) { + throw Exception("Failed to parse OutputV2 from $json"); + } + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is OutputV2 && + other.scriptPubKeyHex == scriptPubKeyHex && + other.valueStringSats == valueStringSats; + } + + @override + int get hashCode => Object.hash( + scriptPubKeyHex, + valueStringSats, + ); + + @override + String toString() { + return 'OutputV2(\n' + ' scriptPubKeyHex: $scriptPubKeyHex,\n' + ' value: $value,\n' + ')'; + } +} + +bool _listEquals<T, U>(List<T> a, List<U> b) { + if (T != U) { + return false; + } + + if (a.length != b.length) { + return false; + } + + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + } + + return true; +} diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index 224073574..c811b2e36 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -12,6 +12,7 @@ import 'dart:convert'; import 'package:bip47/src/util.dart'; import 'package:decimal/decimal.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/utilities/amount/amount.dart'; @@ -24,13 +25,15 @@ class TT with ElectrumXParsing { } mixin ElectrumXParsing { - Future<dynamic> parseBchTx( + Future<TransactionV2> parseBchTx( Map<String, dynamic> json, [ String? debugTitle, ]) async { print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); util.Util.printJson(json, debugTitle); print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + + return TransactionV2.fromElectrumXJson(json); } Future<Tuple2<Transaction, Address>> parseTransaction( From 649dac33b37ae02368baafede35ceddf3a8f60fa Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 18 Oct 2023 16:12:33 -0600 Subject: [PATCH 278/379] fuzeCount logic refactor --- .../mixins/fusion_wallet_interface.dart | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index fe49fa7c6..277e7fd85 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -128,6 +128,7 @@ mixin FusionWalletInterface { // Fusion object. fusion.Fusion? _mainFusionObject; bool _stopRequested = false; + int _currentFuseCount = 0; /// Initializes the FusionWalletInterface mixin. /// @@ -456,17 +457,23 @@ mixin FusionWalletInterface { }, ); - int fuzeCount = 0; + // reset count and flag + _currentFuseCount = 0; _stopRequested = false; - while (!_stopRequested) { - if (fusionInfo.rounds > 0) { - if (fuzeCount >= fusionInfo.rounds) { - _stopRequested = true; - } + bool shouldFuzeAgain() { + if (fusionInfo.rounds <= 0) { + // ignore count if continuous + return !_stopRequested; + } else { + // not continuous + // check to make sure we aren't doing more fusions than requested + return !_stopRequested && _currentFuseCount < fusionInfo.rounds; } + } - fuzeCount++; + while (shouldFuzeAgain()) { + _currentFuseCount++; // refresh wallet utxos await _updateWalletUTXOS(); From 993914636bfc7ca2327ac279365f047914b1bdac Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 19 Oct 2023 08:35:41 -0600 Subject: [PATCH 279/379] organise classes into separate files --- .../models/blockchain_data/v2/input_v2.dart | 54 ++++++++ .../models/blockchain_data/v2/output_v2.dart | 62 +++++++++ .../blockchain_data/v2/transaction_v2.dart | 119 +----------------- 3 files changed, 118 insertions(+), 117 deletions(-) create mode 100644 lib/models/isar/models/blockchain_data/v2/input_v2.dart create mode 100644 lib/models/isar/models/blockchain_data/v2/output_v2.dart diff --git a/lib/models/isar/models/blockchain_data/v2/input_v2.dart b/lib/models/isar/models/blockchain_data/v2/input_v2.dart new file mode 100644 index 000000000..7880472b0 --- /dev/null +++ b/lib/models/isar/models/blockchain_data/v2/input_v2.dart @@ -0,0 +1,54 @@ +class InputV2 { + final String scriptSigHex; + final int sequence; + final String txid; + final int vout; + + InputV2({ + required this.scriptSigHex, + required this.sequence, + required this.txid, + required this.vout, + }); + + static InputV2 fromElectrumXJson(Map<String, dynamic> json) { + try { + return InputV2( + scriptSigHex: json["scriptSig"]["hex"] as String, + sequence: json["sequence"] as int, + txid: json["txid"] as String, + vout: json["vout"] as int); + } catch (e) { + throw Exception("Failed to parse InputV2 from $json"); + } + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is InputV2 && + other.scriptSigHex == scriptSigHex && + other.sequence == sequence && + other.txid == txid && + other.vout == vout; + } + + @override + int get hashCode => Object.hash( + scriptSigHex, + sequence, + txid, + vout, + ); + + @override + String toString() { + return 'InputV2(\n' + ' scriptSigHex: $scriptSigHex,\n' + ' sequence: $sequence,\n' + ' txid: $txid,\n' + ' vout: $vout,\n' + ')'; + } +} diff --git a/lib/models/isar/models/blockchain_data/v2/output_v2.dart b/lib/models/isar/models/blockchain_data/v2/output_v2.dart new file mode 100644 index 000000000..344b15cca --- /dev/null +++ b/lib/models/isar/models/blockchain_data/v2/output_v2.dart @@ -0,0 +1,62 @@ +import 'package:decimal/decimal.dart'; + +class OutputV2 { + final String scriptPubKeyHex; + final String valueStringSats; + + BigInt get value => BigInt.parse(valueStringSats); + + OutputV2({ + required this.scriptPubKeyHex, + required this.valueStringSats, + }); + + // TODO: move this to a subclass based on coin since we don't know if the value will be sats or a decimal amount + // For now assume 8 decimal places + @Deprecated("See TODO and comments") + static OutputV2 fromElectrumXJson(Map<String, dynamic> json) { + try { + final temp = Decimal.parse(json["value"].toString()); + if (temp < Decimal.zero) { + throw Exception("Negative value found"); + } + + final String valueStringSats; + if (temp.isInteger) { + valueStringSats = temp.toString(); + } else { + valueStringSats = temp.shift(8).toBigInt().toString(); + } + + return OutputV2( + scriptPubKeyHex: json["scriptPubKey"]["hex"] as String, + valueStringSats: valueStringSats, + ); + } catch (e) { + throw Exception("Failed to parse OutputV2 from $json"); + } + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is OutputV2 && + other.scriptPubKeyHex == scriptPubKeyHex && + other.valueStringSats == valueStringSats; + } + + @override + int get hashCode => Object.hash( + scriptPubKeyHex, + valueStringSats, + ); + + @override + String toString() { + return 'OutputV2(\n' + ' scriptPubKeyHex: $scriptPubKeyHex,\n' + ' value: $value,\n' + ')'; + } +} diff --git a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart index a77cacdea..3c8cc4fde 100644 --- a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart @@ -1,4 +1,5 @@ -import 'package:decimal/decimal.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/input_v2.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/output_v2.dart'; class TransactionV2 { final String hash; @@ -105,122 +106,6 @@ class TransactionV2 { } } -class InputV2 { - final String scriptSigHex; - final int sequence; - final String txid; - final int vout; - - InputV2({ - required this.scriptSigHex, - required this.sequence, - required this.txid, - required this.vout, - }); - - static InputV2 fromElectrumXJson(Map<String, dynamic> json) { - try { - return InputV2( - scriptSigHex: json["scriptSig"]["hex"] as String, - sequence: json["sequence"] as int, - txid: json["txid"] as String, - vout: json["vout"] as int); - } catch (e) { - throw Exception("Failed to parse InputV2 from $json"); - } - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is InputV2 && - other.scriptSigHex == scriptSigHex && - other.sequence == sequence && - other.txid == txid && - other.vout == vout; - } - - @override - int get hashCode => Object.hash( - scriptSigHex, - sequence, - txid, - vout, - ); - - @override - String toString() { - return 'InputV2(\n' - ' scriptSigHex: $scriptSigHex,\n' - ' sequence: $sequence,\n' - ' txid: $txid,\n' - ' vout: $vout,\n' - ')'; - } -} - -class OutputV2 { - final String scriptPubKeyHex; - final String valueStringSats; - - BigInt get value => BigInt.parse(valueStringSats); - - OutputV2({ - required this.scriptPubKeyHex, - required this.valueStringSats, - }); - - // TODO: move this to a subclass based on coin since we don't know if the value will be sats or a decimal amount - // For now assume 8 decimal places - @Deprecated("See TODO and comments") - static OutputV2 fromElectrumXJson(Map<String, dynamic> json) { - try { - final temp = Decimal.parse(json["value"].toString()); - if (temp < Decimal.zero) { - throw Exception("Negative value found"); - } - - final String valueStringSats; - if (temp.isInteger) { - valueStringSats = temp.toString(); - } else { - valueStringSats = temp.shift(8).toBigInt().toString(); - } - - return OutputV2( - scriptPubKeyHex: json["scriptPubKey"]["hex"] as String, - valueStringSats: valueStringSats, - ); - } catch (e) { - throw Exception("Failed to parse OutputV2 from $json"); - } - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is OutputV2 && - other.scriptPubKeyHex == scriptPubKeyHex && - other.valueStringSats == valueStringSats; - } - - @override - int get hashCode => Object.hash( - scriptPubKeyHex, - valueStringSats, - ); - - @override - String toString() { - return 'OutputV2(\n' - ' scriptPubKeyHex: $scriptPubKeyHex,\n' - ' value: $value,\n' - ')'; - } -} - bool _listEquals<T, U>(List<T> a, List<U> b) { if (T != U) { return false; From e88676cf4003f675e38581b6d4c99b491a0675d8 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 12:06:26 -0500 Subject: [PATCH 280/379] add fusionRoundsCompleted and fusionRoundsFailed to fusion uiState and update fusiondart ref for minor null assertion->optional --- fusiondart | 2 +- lib/models/fusion_progress_ui_state.dart | 38 ++++++++++++++++- .../mixins/fusion_wallet_interface.dart | 42 ++++++++++++++++--- 3 files changed, 74 insertions(+), 8 deletions(-) diff --git a/fusiondart b/fusiondart index b93220d2f..cad52f0ee 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit b93220d2f133ac076e7ebe7f433bd6f248721e16 +Subproject commit cad52f0ee123c30cd881482817b4e078f1472d8b diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 84c8a1699..11aef7e6c 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -2,7 +2,14 @@ import 'package:flutter/cupertino.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; class FusionProgressUIState extends ChangeNotifier { - bool _ableToConnect = true; // set to true for now + /// Whether we are able to connect to the server. + bool _ableToConnect = false; + + // _ableToConnect setter. + set ableToConnect(bool ableToConnect) { + _ableToConnect = ableToConnect; + notifyListeners(); + } bool get done { if (!_ableToConnect) { @@ -89,4 +96,33 @@ class FusionProgressUIState extends ChangeNotifier { _fusionStatus = fusionStatus; notifyListeners(); } + + /// An int storing the number of successfully completed fusion rounds. + int _fusionRoundsCompleted = 0; + int get fusionRoundsCompleted => _fusionRoundsCompleted; + set fusionRoundsCompleted(int fusionRoundsCompleted) { + _fusionRoundsCompleted = fusionRoundsCompleted; + notifyListeners(); + } + + /// A helper for incrementing the number of successfully completed fusion rounds. + void incrementFusionRoundsCompleted() { + _fusionRoundsCompleted++; + _fusionRoundsFailed = 0; // Reset failed round count on success. + notifyListeners(); + } + + /// An int storing the number of failed fusion rounds. + int _fusionRoundsFailed = 0; + int get fusionRoundsFailed => _fusionRoundsFailed; + set fusionRoundsFailed(int fusionRoundsFailed) { + _fusionRoundsFailed = fusionRoundsFailed; + notifyListeners(); + } + + /// A helper for incrementing the number of failed fusion rounds. + void incrementFusionRoundsFailed() { + _fusionRoundsFailed++; + notifyListeners(); + } } diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 277e7fd85..fe47b3fe9 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -128,7 +128,15 @@ mixin FusionWalletInterface { // Fusion object. fusion.Fusion? _mainFusionObject; bool _stopRequested = false; - int _currentFuseCount = 0; + + /// An int storing the number of successfully completed fusion rounds. + int _completedFuseCount = 0; + + /// An int storing the number of failed fusion rounds. + int _failedFuseCount = 0; + + /// The maximum number of consecutive failed fusion rounds before stopping. + int get maxFailedFuseCount => 5; /// Initializes the FusionWalletInterface mixin. /// @@ -457,8 +465,11 @@ mixin FusionWalletInterface { }, ); - // reset count and flag - _currentFuseCount = 0; + // Reset internal and UI counts and flag. + _completedFuseCount = 0; + _uiState?.fusionRoundsCompleted = 0; + _failedFuseCount = 0; + _uiState?.fusionRoundsFailed = 0; _stopRequested = false; bool shouldFuzeAgain() { @@ -468,13 +479,11 @@ mixin FusionWalletInterface { } else { // not continuous // check to make sure we aren't doing more fusions than requested - return !_stopRequested && _currentFuseCount < fusionInfo.rounds; + return !_stopRequested && _completedFuseCount < fusionInfo.rounds; } } while (shouldFuzeAgain()) { - _currentFuseCount++; - // refresh wallet utxos await _updateWalletUTXOS(); @@ -553,6 +562,27 @@ mixin FusionWalletInterface { level: LogLevel.Error, ); // just continue on attempt failure + + // Increment the number of failed fusion rounds. + _failedFuseCount++; + + // Do the same for the UI state. + _uiState?.incrementFusionRoundsFailed(); + + // If we fail 5 times in a row, stop trying. + if (_failedFuseCount >= maxFailedFuseCount) { + _stopRequested = true; + } + } finally { + // Increment the number of successfully completed fusion rounds. + _completedFuseCount++; + + // Do the same for the UI state. This also resets the failed count (for + // the UI state only). + _uiState?.incrementFusionRoundsCompleted(); + + // Also reset the failed count here. + _failedFuseCount = 0; } } } From 94fd8bc0ec985133a0ef10ef90e1e9e29af1056b Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 12:16:12 -0500 Subject: [PATCH 281/379] add flag to show try again button --- lib/models/fusion_progress_ui_state.dart | 11 +++++++++++ lib/services/mixins/fusion_wallet_interface.dart | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 11aef7e6c..60217b2d6 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -109,6 +109,7 @@ class FusionProgressUIState extends ChangeNotifier { void incrementFusionRoundsCompleted() { _fusionRoundsCompleted++; _fusionRoundsFailed = 0; // Reset failed round count on success. + _maxConsecutiveFusionRoundsFailed = false; // Reset failed flag on success. notifyListeners(); } @@ -125,4 +126,14 @@ class FusionProgressUIState extends ChangeNotifier { _fusionRoundsFailed++; notifyListeners(); } + + /// A flag indicating that fusion has stopped because the maximum number of + /// consecutive failed fusion rounds has been reached. + bool _maxConsecutiveFusionRoundsFailed = false; + bool get maxConsecutiveFusionRoundsFailed => + _maxConsecutiveFusionRoundsFailed; + set maxConsecutiveFusionRoundsFailed(bool maxConsecutiveFusionRoundsFailed) { + _maxConsecutiveFusionRoundsFailed = maxConsecutiveFusionRoundsFailed; + notifyListeners(); + } } diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index fe47b3fe9..6bcb86817 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -569,9 +569,10 @@ mixin FusionWalletInterface { // Do the same for the UI state. _uiState?.incrementFusionRoundsFailed(); - // If we fail 5 times in a row, stop trying. + // If we fail too many times in a row, stop trying. if (_failedFuseCount >= maxFailedFuseCount) { _stopRequested = true; + _uiState?.maxConsecutiveFusionRoundsFailed = true; } } finally { // Increment the number of successfully completed fusion rounds. From 45737084fddf72f8788a81a6c069d519069fecd1 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 19 Oct 2023 11:08:14 -0600 Subject: [PATCH 282/379] WIP txV2 for bch for now --- .../models/blockchain_data/v2/input_v2.dart | 112 ++++++++++++---- .../models/blockchain_data/v2/output_v2.dart | 98 ++++++++++---- .../blockchain_data/v2/transaction_v2.dart | 122 +++++------------- .../global_settings_view/hidden_settings.dart | 28 ++-- lib/services/mixins/electrum_x_parsing.dart | 87 ++++++++++++- 5 files changed, 296 insertions(+), 151 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/v2/input_v2.dart b/lib/models/isar/models/blockchain_data/v2/input_v2.dart index 7880472b0..f604b75af 100644 --- a/lib/models/isar/models/blockchain_data/v2/input_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/input_v2.dart @@ -1,28 +1,84 @@ -class InputV2 { - final String scriptSigHex; - final int sequence; - final String txid; - final int vout; +import 'package:isar/isar.dart'; - InputV2({ - required this.scriptSigHex, - required this.sequence, - required this.txid, - required this.vout, - }); +part 'input_v2.g.dart'; - static InputV2 fromElectrumXJson(Map<String, dynamic> json) { - try { - return InputV2( - scriptSigHex: json["scriptSig"]["hex"] as String, - sequence: json["sequence"] as int, - txid: json["txid"] as String, - vout: json["vout"] as int); - } catch (e) { - throw Exception("Failed to parse InputV2 from $json"); - } +@Embedded() +class OutpointV2 { + late final String txid; + late final int vout; + + OutpointV2(); + + static OutpointV2 isarCantDoRequiredInDefaultConstructor({ + required String txid, + required int vout, + }) => + OutpointV2() + ..vout = vout + ..txid = txid; + + @override + String toString() { + return 'OutpointV2(\n' + ' txid: $txid,\n' + ' vout: $vout,\n' + ')'; } + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is OutpointV2 && other.txid == txid && other.vout == vout; + } + + @override + int get hashCode { + return Object.hash( + txid.hashCode, + vout.hashCode, + ); + } +} + +@Embedded() +class InputV2 { + late final String? scriptSigHex; + late final int? sequence; + late final OutpointV2? outpoint; + late final List<String> addresses; + late final String valueStringSats; + + late final String? coinbase; + + late final String? witness; + late final String? innerRedeemScriptAsm; + + @ignore + BigInt get value => BigInt.parse(valueStringSats); + + InputV2(); + + static InputV2 isarCantDoRequiredInDefaultConstructor({ + required String? scriptSigHex, + required int? sequence, + required OutpointV2? outpoint, + required List<String> addresses, + required String valueStringSats, + required String? witness, + required String? innerRedeemScriptAsm, + required String? coinbase, + }) => + InputV2() + ..scriptSigHex = scriptSigHex + ..sequence = sequence + ..sequence = sequence + ..addresses = List.unmodifiable(addresses) + ..valueStringSats = valueStringSats + ..witness = witness + ..innerRedeemScriptAsm = innerRedeemScriptAsm + ..coinbase = coinbase; + @override bool operator ==(Object other) { if (identical(this, other)) return true; @@ -30,16 +86,14 @@ class InputV2 { return other is InputV2 && other.scriptSigHex == scriptSigHex && other.sequence == sequence && - other.txid == txid && - other.vout == vout; + other.outpoint == outpoint; } @override int get hashCode => Object.hash( scriptSigHex, sequence, - txid, - vout, + outpoint, ); @override @@ -47,8 +101,12 @@ class InputV2 { return 'InputV2(\n' ' scriptSigHex: $scriptSigHex,\n' ' sequence: $sequence,\n' - ' txid: $txid,\n' - ' vout: $vout,\n' + ' outpoint: $outpoint,\n' + ' addresses: $addresses,\n' + ' valueStringSats: $valueStringSats,\n' + ' coinbase: $coinbase,\n' + ' witness: $witness,\n' + ' innerRedeemScriptAsm: $innerRedeemScriptAsm,\n' ')'; } } diff --git a/lib/models/isar/models/blockchain_data/v2/output_v2.dart b/lib/models/isar/models/blockchain_data/v2/output_v2.dart index 344b15cca..b65dc4b23 100644 --- a/lib/models/isar/models/blockchain_data/v2/output_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/output_v2.dart @@ -1,48 +1,83 @@ import 'package:decimal/decimal.dart'; +import 'package:isar/isar.dart'; +part 'output_v2.g.dart'; + +@Embedded() class OutputV2 { - final String scriptPubKeyHex; - final String valueStringSats; + late final String scriptPubKeyHex; + late final String valueStringSats; + late final List<String> addresses; + @ignore BigInt get value => BigInt.parse(valueStringSats); - OutputV2({ - required this.scriptPubKeyHex, - required this.valueStringSats, - }); + OutputV2(); - // TODO: move this to a subclass based on coin since we don't know if the value will be sats or a decimal amount - // For now assume 8 decimal places - @Deprecated("See TODO and comments") - static OutputV2 fromElectrumXJson(Map<String, dynamic> json) { + static OutputV2 isarCantDoRequiredInDefaultConstructor({ + required String scriptPubKeyHex, + required String valueStringSats, + required List<String> addresses, + }) => + OutputV2() + ..scriptPubKeyHex = scriptPubKeyHex + ..valueStringSats = valueStringSats + ..addresses = List.unmodifiable(addresses); + + static OutputV2 fromElectrumXJson( + Map<String, dynamic> json, { + required int decimalPlaces, + }) { try { - final temp = Decimal.parse(json["value"].toString()); - if (temp < Decimal.zero) { - throw Exception("Negative value found"); + List<String> addresses = []; + + if (json["scriptPubKey"]?["addresses"] is List) { + for (final e in json["scriptPubKey"]["addresses"] as List) { + addresses.add(e as String); + } + } else if (json["scriptPubKey"]?["address"] is String) { + addresses.add(json["scriptPubKey"]?["address"] as String); } - final String valueStringSats; - if (temp.isInteger) { - valueStringSats = temp.toString(); - } else { - valueStringSats = temp.shift(8).toBigInt().toString(); - } - - return OutputV2( + return OutputV2.isarCantDoRequiredInDefaultConstructor( scriptPubKeyHex: json["scriptPubKey"]["hex"] as String, - valueStringSats: valueStringSats, + valueStringSats: parseOutputAmountString( + json["value"].toString(), + decimalPlaces: decimalPlaces, + ), + addresses: addresses, ); } catch (e) { throw Exception("Failed to parse OutputV2 from $json"); } } + static String parseOutputAmountString( + String amount, { + required int decimalPlaces, + }) { + final temp = Decimal.parse(amount); + if (temp < Decimal.zero) { + throw Exception("Negative value found"); + } + + final String valueStringSats; + if (temp.isInteger) { + valueStringSats = temp.toString(); + } else { + valueStringSats = temp.shift(decimalPlaces).toBigInt().toString(); + } + + return valueStringSats; + } + @override bool operator ==(Object other) { if (identical(this, other)) return true; return other is OutputV2 && other.scriptPubKeyHex == scriptPubKeyHex && + _listEquals(other.addresses, addresses) && other.valueStringSats == valueStringSats; } @@ -57,6 +92,25 @@ class OutputV2 { return 'OutputV2(\n' ' scriptPubKeyHex: $scriptPubKeyHex,\n' ' value: $value,\n' + ' addresses: $addresses,\n' ')'; } } + +bool _listEquals<T, U>(List<T> a, List<U> b) { + if (T != U) { + return false; + } + + if (a.length != b.length) { + return false; + } + + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + } + + return true; +} diff --git a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart index 3c8cc4fde..f98ca53ea 100644 --- a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart @@ -1,125 +1,67 @@ +import 'dart:math'; + +import 'package:isar/isar.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/v2/input_v2.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/v2/output_v2.dart'; +part 'transaction_v2.g.dart'; + +@Collection() class TransactionV2 { - final String hash; + final Id id = Isar.autoIncrement; + + @Index() + final String walletId; + + @Index(unique: true, composite: [CompositeIndex("walletId")]) final String txid; - final int size; - final int lockTime; + final String hash; - final DateTime? blockTime; + @Index() + late final int timestamp; + + final int? height; final String? blockHash; + final int version; final List<InputV2> inputs; final List<OutputV2> outputs; TransactionV2({ + required this.walletId, required this.blockHash, required this.hash, required this.txid, - required this.lockTime, - required this.size, - required this.blockTime, + required this.timestamp, + required this.height, required this.inputs, required this.outputs, + required this.version, }); - static TransactionV2 fromElectrumXJson(Map<String, dynamic> json) { - try { - final inputs = (json["vin"] as List).map( - (e) => InputV2.fromElectrumXJson( - Map<String, dynamic>.from(e as Map), - ), - ); - final outputs = (json["vout"] as List).map( - (e) => OutputV2.fromElectrumXJson( - Map<String, dynamic>.from(e as Map), - ), - ); - - final blockTimeUnix = json["blocktime"] as int?; - DateTime? blockTime; - if (blockTimeUnix != null) { - blockTime = DateTime.fromMillisecondsSinceEpoch( - blockTimeUnix * 1000, - isUtc: true, - ); - } - - return TransactionV2( - blockHash: json["blockhash"] as String?, - hash: json["hash"] as String, - txid: json["txid"] as String, - lockTime: json["locktime"] as int, - size: json["size"] as int, - blockTime: blockTime, - inputs: List.unmodifiable(inputs), - outputs: List.unmodifiable(outputs), - ); - } catch (e) { - throw Exception( - "Failed to parse TransactionV2 for txid=${json["txid"]}: $e", - ); - } + int getConfirmations(int currentChainHeight) { + if (height == null || height! <= 0) return 0; + return max(0, currentChainHeight - (height! - 1)); } - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is TransactionV2 && - other.hash == hash && - other.txid == txid && - other.size == size && - other.lockTime == lockTime && - other.blockTime == blockTime && - other.blockHash == blockHash && - _listEquals(other.inputs, inputs) && - _listEquals(other.outputs, outputs); + bool isConfirmed(int currentChainHeight, int minimumConfirms) { + final confirmations = getConfirmations(currentChainHeight); + return confirmations >= minimumConfirms; } - @override - int get hashCode => Object.hash( - hash, - txid, - size, - lockTime, - blockTime, - blockHash, - inputs, - outputs, - ); - @override String toString() { return 'TransactionV2(\n' + ' walletId: $walletId,\n' ' hash: $hash,\n' ' txid: $txid,\n' - ' size: $size,\n' - ' lockTime: $lockTime,\n' - ' blockTime: $blockTime,\n' + ' timestamp: $timestamp,\n' + ' height: $height,\n' ' blockHash: $blockHash,\n' + ' version: $version,\n' ' inputs: $inputs,\n' ' outputs: $outputs,\n' ')'; } } - -bool _listEquals<T, U>(List<T> a, List<U> b) { - if (T != U) { - return false; - } - - if (a.length != b.length) { - return false; - } - - for (int i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - return false; - } - } - - return true; -} diff --git a/lib/pages/settings_views/global_settings_view/hidden_settings.dart b/lib/pages/settings_views/global_settings_view/hidden_settings.dart index 075018b13..2f34a89a9 100644 --- a/lib/pages/settings_views/global_settings_view/hidden_settings.dart +++ b/lib/pages/settings_views/global_settings_view/hidden_settings.dart @@ -18,6 +18,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:stackwallet/db/hive/db.dart'; +import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/providers/global/debug_service_provider.dart'; @@ -379,6 +380,9 @@ class HiddenSettings extends StatelessWidget { failovers: [], ); + final ce = + CachedElectrumX(electrumXClient: e); + final txids = [ "", // cashTokenTxid "6a0444358bc41913c5b04a8dc06896053184b3641bc62502d18f954865b6ce1e", // normalTxid @@ -400,15 +404,23 @@ class HiddenSettings extends StatelessWidget { // // await e.getTransaction(txHash: txids[2]); // // await p.parseBchTx(json3); // - final json4 = - await e.getTransaction(txHash: txids[3]); - await p.parseBchTx( - json4, "SLP TOKEN SEND TXID:"); + await p.getTransaction( + txids[3], + Coin.bitcoincash, + "lol", + ce, + "SLP TOKEN SEND TXID:"); + await p.getTransaction( + "009d31380d2dbfb5c91500c861d55b531a8b762b0abb19353db884548dbac8b6", + Coin.bitcoincash, + "lol", + ce, + "COINBASE TXID:"); - final json5 = - await e.getTransaction(txHash: txids[4]); - await p.parseBchTx( - json5, "SLP TOKEN GENESIS TXID:"); + // final json5 = + // await e.getTransaction(txHash: txids[4]); + // await p.parseBchTx( + // json5, "SLP TOKEN GENESIS TXID:"); } catch (e, s) { print("$e\n$s"); } diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index c811b2e36..5fe38dfe3 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -12,6 +12,9 @@ import 'dart:convert'; import 'package:bip47/src/util.dart'; import 'package:decimal/decimal.dart'; +import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/input_v2.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/output_v2.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; @@ -25,15 +28,91 @@ class TT with ElectrumXParsing { } mixin ElectrumXParsing { - Future<TransactionV2> parseBchTx( - Map<String, dynamic> json, [ + Future<TransactionV2> getTransaction( + String txHash, + Coin coin, + String walletId, + CachedElectrumX cachedElectrumX, [ String? debugTitle, ]) async { + final jsonTx = await cachedElectrumX.getTransaction( + txHash: txHash, + coin: coin, + ); print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - util.Util.printJson(json, debugTitle); + util.Util.printJson(jsonTx, debugTitle); print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); - return TransactionV2.fromElectrumXJson(json); + // parse inputs + final List<InputV2> inputs = []; + for (final jsonInput in jsonTx["vin"] as List) { + final map = Map<String, dynamic>.from(jsonInput as Map); + + final List<String> addresses = []; + String valueStringSats = "0"; + OutpointV2? outpoint; + + final coinbase = map["coinbase"] as String?; + + if (coinbase == null) { + final txid = map["txid"] as String; + final vout = map["vout"] as int; + + final inputTx = + await cachedElectrumX.getTransaction(txHash: txid, coin: coin); + + final prevOutJson = Map<String, dynamic>.from( + (inputTx["vout"] as List).firstWhere((e) => e["n"] == vout) as Map); + + final prevOut = OutputV2.fromElectrumXJson( + prevOutJson, + decimalPlaces: coin.decimals, + ); + + outpoint = OutpointV2.isarCantDoRequiredInDefaultConstructor( + txid: txid, + vout: vout, + ); + valueStringSats = prevOut.valueStringSats; + addresses.addAll(prevOut.addresses); + } + + final input = InputV2.isarCantDoRequiredInDefaultConstructor( + scriptSigHex: map["scriptSig"]?["hex"] as String?, + sequence: map["sequence"] as int?, + outpoint: outpoint, + valueStringSats: valueStringSats, + addresses: addresses, + witness: map["witness"] as String?, + coinbase: coinbase, + innerRedeemScriptAsm: map["innerRedeemscriptAsm"] as String?, + ); + + inputs.add(input); + } + + // parse outputs + final List<OutputV2> outputs = []; + for (final outputJson in jsonTx["vout"] as List) { + final output = OutputV2.fromElectrumXJson( + Map<String, dynamic>.from(outputJson as Map), + decimalPlaces: coin.decimals, + ); + outputs.add(output); + } + + return TransactionV2( + walletId: walletId, + blockHash: jsonTx["blockhash"] as String?, + hash: jsonTx["hash"] as String, + txid: jsonTx["txid"] as String, + height: jsonTx["height"] as int?, + version: jsonTx["version"] as int, + timestamp: jsonTx["blocktime"] as int? ?? + DateTime.timestamp().millisecondsSinceEpoch ~/ 1000, + inputs: List.unmodifiable(inputs), + outputs: List.unmodifiable(outputs), + ); } Future<Tuple2<Transaction, Address>> parseTransaction( From 4a619d68ad28b6e271a2fc3f8fa15a13b8a3acc9 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 19 Oct 2023 11:26:14 -0600 Subject: [PATCH 283/379] build runner --- .../models/blockchain_data/v2/input_v2.g.dart | 1616 ++++++++++++++ .../blockchain_data/v2/output_v2.g.dart | 659 ++++++ .../blockchain_data/v2/transaction_v2.g.dart | 1986 +++++++++++++++++ test/cached_electrumx_test.mocks.dart | 236 +- test/electrumx_test.mocks.dart | 186 +- .../pages/send_view/send_view_test.mocks.dart | 1390 ++++++------ ...d_address_book_view_screen_test.mocks.dart | 5 + ..._entry_details_view_screen_test.mocks.dart | 5 + ...ess_book_entry_view_screen_test.mocks.dart | 5 + .../exchange/exchange_view_test.mocks.dart | 376 ++-- .../lockscreen_view_screen_test.mocks.dart | 5 + .../main_view_screen_testA_test.mocks.dart | 5 + .../main_view_screen_testB_test.mocks.dart | 5 + .../main_view_screen_testC_test.mocks.dart | 5 + .../backup_key_view_screen_test.mocks.dart | 5 + ...up_key_warning_view_screen_test.mocks.dart | 5 + .../create_pin_view_screen_test.mocks.dart | 5 + ...restore_wallet_view_screen_test.mocks.dart | 5 + ...ify_backup_key_view_screen_test.mocks.dart | 5 + .../currency_view_screen_test.mocks.dart | 5 + ...dd_custom_node_view_screen_test.mocks.dart | 5 + .../node_details_view_screen_test.mocks.dart | 5 + .../wallet_backup_view_screen_test.mocks.dart | 5 + ...rescan_warning_view_screen_test.mocks.dart | 5 + ...elete_mnemonic_view_screen_test.mocks.dart | 5 + ...allet_settings_view_screen_test.mocks.dart | 5 + .../settings_view_screen_test.mocks.dart | 5 + ...search_results_view_screen_test.mocks.dart | 5 + .../confirm_send_view_screen_test.mocks.dart | 5 + .../receive_view_screen_test.mocks.dart | 5 + .../send_view_screen_test.mocks.dart | 5 + .../wallet_view_screen_test.mocks.dart | 5 + .../coins/firo/firo_wallet_test.mocks.dart | 27 + .../managed_favorite_test.mocks.dart | 1406 ++++++------ .../node_options_sheet_test.mocks.dart | 320 +-- .../table_view/table_view_row_test.mocks.dart | 1154 +++++----- .../transaction_card_test.mocks.dart | 1414 ++++++------ test/widget_tests/wallet_card_test.mocks.dart | 751 ++++--- ...et_info_row_balance_future_test.mocks.dart | 1206 +++++----- .../wallet_info_row_test.mocks.dart | 1268 ++++++----- 40 files changed, 9534 insertions(+), 4586 deletions(-) create mode 100644 lib/models/isar/models/blockchain_data/v2/input_v2.g.dart create mode 100644 lib/models/isar/models/blockchain_data/v2/output_v2.g.dart create mode 100644 lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart diff --git a/lib/models/isar/models/blockchain_data/v2/input_v2.g.dart b/lib/models/isar/models/blockchain_data/v2/input_v2.g.dart new file mode 100644 index 000000000..b18575a12 --- /dev/null +++ b/lib/models/isar/models/blockchain_data/v2/input_v2.g.dart @@ -0,0 +1,1616 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'input_v2.dart'; + +// ************************************************************************** +// IsarEmbeddedGenerator +// ************************************************************************** + +// coverage:ignore-file +// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters + +const OutpointV2Schema = Schema( + name: r'OutpointV2', + id: 5327663686922028778, + properties: { + r'hashCode': PropertySchema( + id: 0, + name: r'hashCode', + type: IsarType.long, + ), + r'txid': PropertySchema( + id: 1, + name: r'txid', + type: IsarType.string, + ), + r'vout': PropertySchema( + id: 2, + name: r'vout', + type: IsarType.long, + ) + }, + estimateSize: _outpointV2EstimateSize, + serialize: _outpointV2Serialize, + deserialize: _outpointV2Deserialize, + deserializeProp: _outpointV2DeserializeProp, +); + +int _outpointV2EstimateSize( + OutpointV2 object, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + var bytesCount = offsets.last; + bytesCount += 3 + object.txid.length * 3; + return bytesCount; +} + +void _outpointV2Serialize( + OutpointV2 object, + IsarWriter writer, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + writer.writeLong(offsets[0], object.hashCode); + writer.writeString(offsets[1], object.txid); + writer.writeLong(offsets[2], object.vout); +} + +OutpointV2 _outpointV2Deserialize( + Id id, + IsarReader reader, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + final object = OutpointV2(); + object.txid = reader.readString(offsets[1]); + object.vout = reader.readLong(offsets[2]); + return object; +} + +P _outpointV2DeserializeProp<P>( + IsarReader reader, + int propertyId, + int offset, + Map<Type, List<int>> allOffsets, +) { + switch (propertyId) { + case 0: + return (reader.readLong(offset)) as P; + case 1: + return (reader.readString(offset)) as P; + case 2: + return (reader.readLong(offset)) as P; + default: + throw IsarError('Unknown property with id $propertyId'); + } +} + +extension OutpointV2QueryFilter + on QueryBuilder<OutpointV2, OutpointV2, QFilterCondition> { + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> hashCodeEqualTo( + int value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'hashCode', + value: value, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> + hashCodeGreaterThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'hashCode', + value: value, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> hashCodeLessThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'hashCode', + value: value, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> hashCodeBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'hashCode', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> txidEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> txidGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> txidLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> txidBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'txid', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> txidStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> txidEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> txidContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> txidMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'txid', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> txidIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'txid', + value: '', + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> txidIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'txid', + value: '', + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> voutEqualTo( + int value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'vout', + value: value, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> voutGreaterThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'vout', + value: value, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> voutLessThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'vout', + value: value, + )); + }); + } + + QueryBuilder<OutpointV2, OutpointV2, QAfterFilterCondition> voutBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'vout', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } +} + +extension OutpointV2QueryObject + on QueryBuilder<OutpointV2, OutpointV2, QFilterCondition> {} + +// coverage:ignore-file +// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters + +const InputV2Schema = Schema( + name: r'InputV2', + id: 1518255311272544045, + properties: { + r'addresses': PropertySchema( + id: 0, + name: r'addresses', + type: IsarType.stringList, + ), + r'coinbase': PropertySchema( + id: 1, + name: r'coinbase', + type: IsarType.string, + ), + r'hashCode': PropertySchema( + id: 2, + name: r'hashCode', + type: IsarType.long, + ), + r'innerRedeemScriptAsm': PropertySchema( + id: 3, + name: r'innerRedeemScriptAsm', + type: IsarType.string, + ), + r'outpoint': PropertySchema( + id: 4, + name: r'outpoint', + type: IsarType.object, + target: r'OutpointV2', + ), + r'scriptSigHex': PropertySchema( + id: 5, + name: r'scriptSigHex', + type: IsarType.string, + ), + r'sequence': PropertySchema( + id: 6, + name: r'sequence', + type: IsarType.long, + ), + r'valueStringSats': PropertySchema( + id: 7, + name: r'valueStringSats', + type: IsarType.string, + ), + r'witness': PropertySchema( + id: 8, + name: r'witness', + type: IsarType.string, + ) + }, + estimateSize: _inputV2EstimateSize, + serialize: _inputV2Serialize, + deserialize: _inputV2Deserialize, + deserializeProp: _inputV2DeserializeProp, +); + +int _inputV2EstimateSize( + InputV2 object, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + var bytesCount = offsets.last; + bytesCount += 3 + object.addresses.length * 3; + { + for (var i = 0; i < object.addresses.length; i++) { + final value = object.addresses[i]; + bytesCount += value.length * 3; + } + } + { + final value = object.coinbase; + if (value != null) { + bytesCount += 3 + value.length * 3; + } + } + { + final value = object.innerRedeemScriptAsm; + if (value != null) { + bytesCount += 3 + value.length * 3; + } + } + { + final value = object.outpoint; + if (value != null) { + bytesCount += 3 + + OutpointV2Schema.estimateSize( + value, allOffsets[OutpointV2]!, allOffsets); + } + } + { + final value = object.scriptSigHex; + if (value != null) { + bytesCount += 3 + value.length * 3; + } + } + bytesCount += 3 + object.valueStringSats.length * 3; + { + final value = object.witness; + if (value != null) { + bytesCount += 3 + value.length * 3; + } + } + return bytesCount; +} + +void _inputV2Serialize( + InputV2 object, + IsarWriter writer, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + writer.writeStringList(offsets[0], object.addresses); + writer.writeString(offsets[1], object.coinbase); + writer.writeLong(offsets[2], object.hashCode); + writer.writeString(offsets[3], object.innerRedeemScriptAsm); + writer.writeObject<OutpointV2>( + offsets[4], + allOffsets, + OutpointV2Schema.serialize, + object.outpoint, + ); + writer.writeString(offsets[5], object.scriptSigHex); + writer.writeLong(offsets[6], object.sequence); + writer.writeString(offsets[7], object.valueStringSats); + writer.writeString(offsets[8], object.witness); +} + +InputV2 _inputV2Deserialize( + Id id, + IsarReader reader, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + final object = InputV2(); + object.addresses = reader.readStringList(offsets[0]) ?? []; + object.coinbase = reader.readStringOrNull(offsets[1]); + object.innerRedeemScriptAsm = reader.readStringOrNull(offsets[3]); + object.outpoint = reader.readObjectOrNull<OutpointV2>( + offsets[4], + OutpointV2Schema.deserialize, + allOffsets, + ); + object.scriptSigHex = reader.readStringOrNull(offsets[5]); + object.sequence = reader.readLongOrNull(offsets[6]); + object.valueStringSats = reader.readString(offsets[7]); + object.witness = reader.readStringOrNull(offsets[8]); + return object; +} + +P _inputV2DeserializeProp<P>( + IsarReader reader, + int propertyId, + int offset, + Map<Type, List<int>> allOffsets, +) { + switch (propertyId) { + case 0: + return (reader.readStringList(offset) ?? []) as P; + case 1: + return (reader.readStringOrNull(offset)) as P; + case 2: + return (reader.readLong(offset)) as P; + case 3: + return (reader.readStringOrNull(offset)) as P; + case 4: + return (reader.readObjectOrNull<OutpointV2>( + offset, + OutpointV2Schema.deserialize, + allOffsets, + )) as P; + case 5: + return (reader.readStringOrNull(offset)) as P; + case 6: + return (reader.readLongOrNull(offset)) as P; + case 7: + return (reader.readString(offset)) as P; + case 8: + return (reader.readStringOrNull(offset)) as P; + default: + throw IsarError('Unknown property with id $propertyId'); + } +} + +extension InputV2QueryFilter + on QueryBuilder<InputV2, InputV2, QFilterCondition> { + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> addressesElementEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + addressesElementGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + addressesElementLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> addressesElementBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'addresses', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + addressesElementStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + addressesElementEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + addressesElementContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> addressesElementMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'addresses', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + addressesElementIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'addresses', + value: '', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + addressesElementIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'addresses', + value: '', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> addressesLengthEqualTo( + int length) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + length, + true, + length, + true, + ); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> addressesIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + 0, + true, + 0, + true, + ); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> addressesIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + 0, + false, + 999999, + true, + ); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> addressesLengthLessThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + 0, + true, + length, + include, + ); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + addressesLengthGreaterThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + length, + include, + 999999, + true, + ); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> addressesLengthBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + lower, + includeLower, + upper, + includeUpper, + ); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'coinbase', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'coinbase', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseEqualTo( + String? value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'coinbase', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseGreaterThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'coinbase', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseLessThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'coinbase', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseBetween( + String? lower, + String? upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'coinbase', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'coinbase', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'coinbase', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'coinbase', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'coinbase', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'coinbase', + value: '', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> coinbaseIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'coinbase', + value: '', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> hashCodeEqualTo( + int value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'hashCode', + value: value, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> hashCodeGreaterThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'hashCode', + value: value, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> hashCodeLessThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'hashCode', + value: value, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> hashCodeBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'hashCode', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'innerRedeemScriptAsm', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'innerRedeemScriptAsm', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmEqualTo( + String? value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'innerRedeemScriptAsm', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmGreaterThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'innerRedeemScriptAsm', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmLessThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'innerRedeemScriptAsm', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmBetween( + String? lower, + String? upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'innerRedeemScriptAsm', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'innerRedeemScriptAsm', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'innerRedeemScriptAsm', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'innerRedeemScriptAsm', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'innerRedeemScriptAsm', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'innerRedeemScriptAsm', + value: '', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + innerRedeemScriptAsmIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'innerRedeemScriptAsm', + value: '', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> outpointIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'outpoint', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> outpointIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'outpoint', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> scriptSigHexIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'scriptSigHex', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + scriptSigHexIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'scriptSigHex', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> scriptSigHexEqualTo( + String? value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'scriptSigHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> scriptSigHexGreaterThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'scriptSigHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> scriptSigHexLessThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'scriptSigHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> scriptSigHexBetween( + String? lower, + String? upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'scriptSigHex', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> scriptSigHexStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'scriptSigHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> scriptSigHexEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'scriptSigHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> scriptSigHexContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'scriptSigHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> scriptSigHexMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'scriptSigHex', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> scriptSigHexIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'scriptSigHex', + value: '', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + scriptSigHexIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'scriptSigHex', + value: '', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> sequenceIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'sequence', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> sequenceIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'sequence', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> sequenceEqualTo( + int? value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'sequence', + value: value, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> sequenceGreaterThan( + int? value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'sequence', + value: value, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> sequenceLessThan( + int? value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'sequence', + value: value, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> sequenceBetween( + int? lower, + int? upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'sequence', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> valueStringSatsEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + valueStringSatsGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> valueStringSatsLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> valueStringSatsBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'valueStringSats', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + valueStringSatsStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> valueStringSatsEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> valueStringSatsContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> valueStringSatsMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'valueStringSats', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + valueStringSatsIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'valueStringSats', + value: '', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> + valueStringSatsIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'valueStringSats', + value: '', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'witness', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'witness', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessEqualTo( + String? value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'witness', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessGreaterThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'witness', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessLessThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'witness', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessBetween( + String? lower, + String? upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'witness', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'witness', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'witness', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessContains( + String value, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'witness', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'witness', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'witness', + value: '', + )); + }); + } + + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'witness', + value: '', + )); + }); + } +} + +extension InputV2QueryObject + on QueryBuilder<InputV2, InputV2, QFilterCondition> { + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> outpoint( + FilterQuery<OutpointV2> q) { + return QueryBuilder.apply(this, (query) { + return query.object(q, r'outpoint'); + }); + } +} diff --git a/lib/models/isar/models/blockchain_data/v2/output_v2.g.dart b/lib/models/isar/models/blockchain_data/v2/output_v2.g.dart new file mode 100644 index 000000000..98cc61620 --- /dev/null +++ b/lib/models/isar/models/blockchain_data/v2/output_v2.g.dart @@ -0,0 +1,659 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'output_v2.dart'; + +// ************************************************************************** +// IsarEmbeddedGenerator +// ************************************************************************** + +// coverage:ignore-file +// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters + +const OutputV2Schema = Schema( + name: r'OutputV2', + id: -6134367361914065515, + properties: { + r'addresses': PropertySchema( + id: 0, + name: r'addresses', + type: IsarType.stringList, + ), + r'hashCode': PropertySchema( + id: 1, + name: r'hashCode', + type: IsarType.long, + ), + r'scriptPubKeyHex': PropertySchema( + id: 2, + name: r'scriptPubKeyHex', + type: IsarType.string, + ), + r'valueStringSats': PropertySchema( + id: 3, + name: r'valueStringSats', + type: IsarType.string, + ) + }, + estimateSize: _outputV2EstimateSize, + serialize: _outputV2Serialize, + deserialize: _outputV2Deserialize, + deserializeProp: _outputV2DeserializeProp, +); + +int _outputV2EstimateSize( + OutputV2 object, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + var bytesCount = offsets.last; + bytesCount += 3 + object.addresses.length * 3; + { + for (var i = 0; i < object.addresses.length; i++) { + final value = object.addresses[i]; + bytesCount += value.length * 3; + } + } + bytesCount += 3 + object.scriptPubKeyHex.length * 3; + bytesCount += 3 + object.valueStringSats.length * 3; + return bytesCount; +} + +void _outputV2Serialize( + OutputV2 object, + IsarWriter writer, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + writer.writeStringList(offsets[0], object.addresses); + writer.writeLong(offsets[1], object.hashCode); + writer.writeString(offsets[2], object.scriptPubKeyHex); + writer.writeString(offsets[3], object.valueStringSats); +} + +OutputV2 _outputV2Deserialize( + Id id, + IsarReader reader, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + final object = OutputV2(); + object.addresses = reader.readStringList(offsets[0]) ?? []; + object.scriptPubKeyHex = reader.readString(offsets[2]); + object.valueStringSats = reader.readString(offsets[3]); + return object; +} + +P _outputV2DeserializeProp<P>( + IsarReader reader, + int propertyId, + int offset, + Map<Type, List<int>> allOffsets, +) { + switch (propertyId) { + case 0: + return (reader.readStringList(offset) ?? []) as P; + case 1: + return (reader.readLong(offset)) as P; + case 2: + return (reader.readString(offset)) as P; + case 3: + return (reader.readString(offset)) as P; + default: + throw IsarError('Unknown property with id $propertyId'); + } +} + +extension OutputV2QueryFilter + on QueryBuilder<OutputV2, OutputV2, QFilterCondition> { + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesElementEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesElementGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesElementLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesElementBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'addresses', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesElementStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesElementEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesElementContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'addresses', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesElementMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'addresses', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesElementIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'addresses', + value: '', + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesElementIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'addresses', + value: '', + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesLengthEqualTo(int length) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + length, + true, + length, + true, + ); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> addressesIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + 0, + true, + 0, + true, + ); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + 0, + false, + 999999, + true, + ); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesLengthLessThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + 0, + true, + length, + include, + ); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesLengthGreaterThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + length, + include, + 999999, + true, + ); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + addressesLengthBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'addresses', + lower, + includeLower, + upper, + includeUpper, + ); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> hashCodeEqualTo( + int value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'hashCode', + value: value, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> hashCodeGreaterThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'hashCode', + value: value, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> hashCodeLessThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'hashCode', + value: value, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> hashCodeBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'hashCode', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + scriptPubKeyHexEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'scriptPubKeyHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + scriptPubKeyHexGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'scriptPubKeyHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + scriptPubKeyHexLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'scriptPubKeyHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + scriptPubKeyHexBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'scriptPubKeyHex', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + scriptPubKeyHexStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'scriptPubKeyHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + scriptPubKeyHexEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'scriptPubKeyHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + scriptPubKeyHexContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'scriptPubKeyHex', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + scriptPubKeyHexMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'scriptPubKeyHex', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + scriptPubKeyHexIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'scriptPubKeyHex', + value: '', + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + scriptPubKeyHexIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'scriptPubKeyHex', + value: '', + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + valueStringSatsEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + valueStringSatsGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + valueStringSatsLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + valueStringSatsBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'valueStringSats', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + valueStringSatsStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + valueStringSatsEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + valueStringSatsContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'valueStringSats', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + valueStringSatsMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'valueStringSats', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + valueStringSatsIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'valueStringSats', + value: '', + )); + }); + } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> + valueStringSatsIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'valueStringSats', + value: '', + )); + }); + } +} + +extension OutputV2QueryObject + on QueryBuilder<OutputV2, OutputV2, QFilterCondition> {} diff --git a/lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart b/lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart new file mode 100644 index 000000000..38772d24e --- /dev/null +++ b/lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart @@ -0,0 +1,1986 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'transaction_v2.dart'; + +// ************************************************************************** +// IsarCollectionGenerator +// ************************************************************************** + +// coverage:ignore-file +// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters + +extension GetTransactionV2Collection on Isar { + IsarCollection<TransactionV2> get transactionV2s => this.collection(); +} + +const TransactionV2Schema = CollectionSchema( + name: r'TransactionV2', + id: -4280912949179256257, + properties: { + r'blockHash': PropertySchema( + id: 0, + name: r'blockHash', + type: IsarType.string, + ), + r'hash': PropertySchema( + id: 1, + name: r'hash', + type: IsarType.string, + ), + r'height': PropertySchema( + id: 2, + name: r'height', + type: IsarType.long, + ), + r'inputs': PropertySchema( + id: 3, + name: r'inputs', + type: IsarType.objectList, + target: r'InputV2', + ), + r'outputs': PropertySchema( + id: 4, + name: r'outputs', + type: IsarType.objectList, + target: r'OutputV2', + ), + r'timestamp': PropertySchema( + id: 5, + name: r'timestamp', + type: IsarType.long, + ), + r'txid': PropertySchema( + id: 6, + name: r'txid', + type: IsarType.string, + ), + r'version': PropertySchema( + id: 7, + name: r'version', + type: IsarType.long, + ), + r'walletId': PropertySchema( + id: 8, + name: r'walletId', + type: IsarType.string, + ) + }, + estimateSize: _transactionV2EstimateSize, + serialize: _transactionV2Serialize, + deserialize: _transactionV2Deserialize, + deserializeProp: _transactionV2DeserializeProp, + idName: r'id', + indexes: { + r'walletId': IndexSchema( + id: -1783113319798776304, + name: r'walletId', + unique: false, + replace: false, + properties: [ + IndexPropertySchema( + name: r'walletId', + type: IndexType.hash, + caseSensitive: true, + ) + ], + ), + r'txid_walletId': IndexSchema( + id: -2771771174176035985, + name: r'txid_walletId', + unique: true, + replace: false, + properties: [ + IndexPropertySchema( + name: r'txid', + type: IndexType.hash, + caseSensitive: true, + ), + IndexPropertySchema( + name: r'walletId', + type: IndexType.hash, + caseSensitive: true, + ) + ], + ), + r'timestamp': IndexSchema( + id: 1852253767416892198, + name: r'timestamp', + unique: false, + replace: false, + properties: [ + IndexPropertySchema( + name: r'timestamp', + type: IndexType.value, + caseSensitive: false, + ) + ], + ) + }, + links: {}, + embeddedSchemas: { + r'InputV2': InputV2Schema, + r'OutpointV2': OutpointV2Schema, + r'OutputV2': OutputV2Schema + }, + getId: _transactionV2GetId, + getLinks: _transactionV2GetLinks, + attach: _transactionV2Attach, + version: '3.0.5', +); + +int _transactionV2EstimateSize( + TransactionV2 object, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + var bytesCount = offsets.last; + { + final value = object.blockHash; + if (value != null) { + bytesCount += 3 + value.length * 3; + } + } + bytesCount += 3 + object.hash.length * 3; + bytesCount += 3 + object.inputs.length * 3; + { + final offsets = allOffsets[InputV2]!; + for (var i = 0; i < object.inputs.length; i++) { + final value = object.inputs[i]; + bytesCount += InputV2Schema.estimateSize(value, offsets, allOffsets); + } + } + bytesCount += 3 + object.outputs.length * 3; + { + final offsets = allOffsets[OutputV2]!; + for (var i = 0; i < object.outputs.length; i++) { + final value = object.outputs[i]; + bytesCount += OutputV2Schema.estimateSize(value, offsets, allOffsets); + } + } + bytesCount += 3 + object.txid.length * 3; + bytesCount += 3 + object.walletId.length * 3; + return bytesCount; +} + +void _transactionV2Serialize( + TransactionV2 object, + IsarWriter writer, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + writer.writeString(offsets[0], object.blockHash); + writer.writeString(offsets[1], object.hash); + writer.writeLong(offsets[2], object.height); + writer.writeObjectList<InputV2>( + offsets[3], + allOffsets, + InputV2Schema.serialize, + object.inputs, + ); + writer.writeObjectList<OutputV2>( + offsets[4], + allOffsets, + OutputV2Schema.serialize, + object.outputs, + ); + writer.writeLong(offsets[5], object.timestamp); + writer.writeString(offsets[6], object.txid); + writer.writeLong(offsets[7], object.version); + writer.writeString(offsets[8], object.walletId); +} + +TransactionV2 _transactionV2Deserialize( + Id id, + IsarReader reader, + List<int> offsets, + Map<Type, List<int>> allOffsets, +) { + final object = TransactionV2( + blockHash: reader.readStringOrNull(offsets[0]), + hash: reader.readString(offsets[1]), + height: reader.readLongOrNull(offsets[2]), + inputs: reader.readObjectList<InputV2>( + offsets[3], + InputV2Schema.deserialize, + allOffsets, + InputV2(), + ) ?? + [], + outputs: reader.readObjectList<OutputV2>( + offsets[4], + OutputV2Schema.deserialize, + allOffsets, + OutputV2(), + ) ?? + [], + timestamp: reader.readLong(offsets[5]), + txid: reader.readString(offsets[6]), + version: reader.readLong(offsets[7]), + walletId: reader.readString(offsets[8]), + ); + return object; +} + +P _transactionV2DeserializeProp<P>( + IsarReader reader, + int propertyId, + int offset, + Map<Type, List<int>> allOffsets, +) { + switch (propertyId) { + case 0: + return (reader.readStringOrNull(offset)) as P; + case 1: + return (reader.readString(offset)) as P; + case 2: + return (reader.readLongOrNull(offset)) as P; + case 3: + return (reader.readObjectList<InputV2>( + offset, + InputV2Schema.deserialize, + allOffsets, + InputV2(), + ) ?? + []) as P; + case 4: + return (reader.readObjectList<OutputV2>( + offset, + OutputV2Schema.deserialize, + allOffsets, + OutputV2(), + ) ?? + []) as P; + case 5: + return (reader.readLong(offset)) as P; + case 6: + return (reader.readString(offset)) as P; + case 7: + return (reader.readLong(offset)) as P; + case 8: + return (reader.readString(offset)) as P; + default: + throw IsarError('Unknown property with id $propertyId'); + } +} + +Id _transactionV2GetId(TransactionV2 object) { + return object.id; +} + +List<IsarLinkBase<dynamic>> _transactionV2GetLinks(TransactionV2 object) { + return []; +} + +void _transactionV2Attach( + IsarCollection<dynamic> col, Id id, TransactionV2 object) {} + +extension TransactionV2ByIndex on IsarCollection<TransactionV2> { + Future<TransactionV2?> getByTxidWalletId(String txid, String walletId) { + return getByIndex(r'txid_walletId', [txid, walletId]); + } + + TransactionV2? getByTxidWalletIdSync(String txid, String walletId) { + return getByIndexSync(r'txid_walletId', [txid, walletId]); + } + + Future<bool> deleteByTxidWalletId(String txid, String walletId) { + return deleteByIndex(r'txid_walletId', [txid, walletId]); + } + + bool deleteByTxidWalletIdSync(String txid, String walletId) { + return deleteByIndexSync(r'txid_walletId', [txid, walletId]); + } + + Future<List<TransactionV2?>> getAllByTxidWalletId( + List<String> txidValues, List<String> walletIdValues) { + final len = txidValues.length; + assert(walletIdValues.length == len, + 'All index values must have the same length'); + final values = <List<dynamic>>[]; + for (var i = 0; i < len; i++) { + values.add([txidValues[i], walletIdValues[i]]); + } + + return getAllByIndex(r'txid_walletId', values); + } + + List<TransactionV2?> getAllByTxidWalletIdSync( + List<String> txidValues, List<String> walletIdValues) { + final len = txidValues.length; + assert(walletIdValues.length == len, + 'All index values must have the same length'); + final values = <List<dynamic>>[]; + for (var i = 0; i < len; i++) { + values.add([txidValues[i], walletIdValues[i]]); + } + + return getAllByIndexSync(r'txid_walletId', values); + } + + Future<int> deleteAllByTxidWalletId( + List<String> txidValues, List<String> walletIdValues) { + final len = txidValues.length; + assert(walletIdValues.length == len, + 'All index values must have the same length'); + final values = <List<dynamic>>[]; + for (var i = 0; i < len; i++) { + values.add([txidValues[i], walletIdValues[i]]); + } + + return deleteAllByIndex(r'txid_walletId', values); + } + + int deleteAllByTxidWalletIdSync( + List<String> txidValues, List<String> walletIdValues) { + final len = txidValues.length; + assert(walletIdValues.length == len, + 'All index values must have the same length'); + final values = <List<dynamic>>[]; + for (var i = 0; i < len; i++) { + values.add([txidValues[i], walletIdValues[i]]); + } + + return deleteAllByIndexSync(r'txid_walletId', values); + } + + Future<Id> putByTxidWalletId(TransactionV2 object) { + return putByIndex(r'txid_walletId', object); + } + + Id putByTxidWalletIdSync(TransactionV2 object, {bool saveLinks = true}) { + return putByIndexSync(r'txid_walletId', object, saveLinks: saveLinks); + } + + Future<List<Id>> putAllByTxidWalletId(List<TransactionV2> objects) { + return putAllByIndex(r'txid_walletId', objects); + } + + List<Id> putAllByTxidWalletIdSync(List<TransactionV2> objects, + {bool saveLinks = true}) { + return putAllByIndexSync(r'txid_walletId', objects, saveLinks: saveLinks); + } +} + +extension TransactionV2QueryWhereSort + on QueryBuilder<TransactionV2, TransactionV2, QWhere> { + QueryBuilder<TransactionV2, TransactionV2, QAfterWhere> anyId() { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(const IdWhereClause.any()); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhere> anyTimestamp() { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause( + const IndexWhereClause.any(indexName: r'timestamp'), + ); + }); + } +} + +extension TransactionV2QueryWhere + on QueryBuilder<TransactionV2, TransactionV2, QWhereClause> { + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> idEqualTo( + Id id) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IdWhereClause.between( + lower: id, + upper: id, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> idNotEqualTo( + Id id) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: false), + ) + .addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: false), + ); + } else { + return query + .addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: false), + ) + .addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: false), + ); + } + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> idGreaterThan( + Id id, + {bool include = false}) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause( + IdWhereClause.greaterThan(lower: id, includeLower: include), + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> idLessThan( + Id id, + {bool include = false}) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause( + IdWhereClause.lessThan(upper: id, includeUpper: include), + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> idBetween( + Id lowerId, + Id upperId, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IdWhereClause.between( + lower: lowerId, + includeLower: includeLower, + upper: upperId, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> walletIdEqualTo( + String walletId) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'walletId', + value: [walletId], + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> + walletIdNotEqualTo(String walletId) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'walletId', + lower: [], + upper: [walletId], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'walletId', + lower: [walletId], + includeLower: false, + upper: [], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'walletId', + lower: [walletId], + includeLower: false, + upper: [], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'walletId', + lower: [], + upper: [walletId], + includeUpper: false, + )); + } + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> + txidEqualToAnyWalletId(String txid) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'txid_walletId', + value: [txid], + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> + txidNotEqualToAnyWalletId(String txid) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'txid_walletId', + lower: [], + upper: [txid], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'txid_walletId', + lower: [txid], + includeLower: false, + upper: [], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'txid_walletId', + lower: [txid], + includeLower: false, + upper: [], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'txid_walletId', + lower: [], + upper: [txid], + includeUpper: false, + )); + } + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> + txidWalletIdEqualTo(String txid, String walletId) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'txid_walletId', + value: [txid, walletId], + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> + txidEqualToWalletIdNotEqualTo(String txid, String walletId) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'txid_walletId', + lower: [txid], + upper: [txid, walletId], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'txid_walletId', + lower: [txid, walletId], + includeLower: false, + upper: [txid], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'txid_walletId', + lower: [txid, walletId], + includeLower: false, + upper: [txid], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'txid_walletId', + lower: [txid], + upper: [txid, walletId], + includeUpper: false, + )); + } + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> + timestampEqualTo(int timestamp) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.equalTo( + indexName: r'timestamp', + value: [timestamp], + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> + timestampNotEqualTo(int timestamp) { + return QueryBuilder.apply(this, (query) { + if (query.whereSort == Sort.asc) { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'timestamp', + lower: [], + upper: [timestamp], + includeUpper: false, + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'timestamp', + lower: [timestamp], + includeLower: false, + upper: [], + )); + } else { + return query + .addWhereClause(IndexWhereClause.between( + indexName: r'timestamp', + lower: [timestamp], + includeLower: false, + upper: [], + )) + .addWhereClause(IndexWhereClause.between( + indexName: r'timestamp', + lower: [], + upper: [timestamp], + includeUpper: false, + )); + } + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> + timestampGreaterThan( + int timestamp, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.between( + indexName: r'timestamp', + lower: [timestamp], + includeLower: include, + upper: [], + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> + timestampLessThan( + int timestamp, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.between( + indexName: r'timestamp', + lower: [], + upper: [timestamp], + includeUpper: include, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterWhereClause> + timestampBetween( + int lowerTimestamp, + int upperTimestamp, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addWhereClause(IndexWhereClause.between( + indexName: r'timestamp', + lower: [lowerTimestamp], + includeLower: includeLower, + upper: [upperTimestamp], + includeUpper: includeUpper, + )); + }); + } +} + +extension TransactionV2QueryFilter + on QueryBuilder<TransactionV2, TransactionV2, QFilterCondition> { + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'blockHash', + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'blockHash', + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashEqualTo( + String? value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'blockHash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashGreaterThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'blockHash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashLessThan( + String? value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'blockHash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashBetween( + String? lower, + String? upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'blockHash', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'blockHash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'blockHash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'blockHash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'blockHash', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'blockHash', + value: '', + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + blockHashIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'blockHash', + value: '', + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> hashEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'hash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + hashGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'hash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + hashLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'hash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> hashBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'hash', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + hashStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'hash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + hashEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'hash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + hashContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'hash', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> hashMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'hash', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + hashIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'hash', + value: '', + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + hashIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'hash', + value: '', + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + heightIsNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNull( + property: r'height', + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + heightIsNotNull() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(const FilterCondition.isNotNull( + property: r'height', + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + heightEqualTo(int? value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'height', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + heightGreaterThan( + int? value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'height', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + heightLessThan( + int? value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'height', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + heightBetween( + int? lower, + int? upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'height', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> idEqualTo( + Id value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'id', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + idGreaterThan( + Id value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'id', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> idLessThan( + Id value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'id', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> idBetween( + Id lower, + Id upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'id', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + inputsLengthEqualTo(int length) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'inputs', + length, + true, + length, + true, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + inputsIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'inputs', + 0, + true, + 0, + true, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + inputsIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'inputs', + 0, + false, + 999999, + true, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + inputsLengthLessThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'inputs', + 0, + true, + length, + include, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + inputsLengthGreaterThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'inputs', + length, + include, + 999999, + true, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + inputsLengthBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'inputs', + lower, + includeLower, + upper, + includeUpper, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + outputsLengthEqualTo(int length) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'outputs', + length, + true, + length, + true, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + outputsIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'outputs', + 0, + true, + 0, + true, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + outputsIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'outputs', + 0, + false, + 999999, + true, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + outputsLengthLessThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'outputs', + 0, + true, + length, + include, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + outputsLengthGreaterThan( + int length, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'outputs', + length, + include, + 999999, + true, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + outputsLengthBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.listLength( + r'outputs', + lower, + includeLower, + upper, + includeUpper, + ); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + timestampEqualTo(int value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'timestamp', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + timestampGreaterThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'timestamp', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + timestampLessThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'timestamp', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + timestampBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'timestamp', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> txidEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + txidGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + txidLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> txidBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'txid', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + txidStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + txidEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + txidContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'txid', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> txidMatches( + String pattern, + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'txid', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + txidIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'txid', + value: '', + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + txidIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'txid', + value: '', + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + versionEqualTo(int value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'version', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + versionGreaterThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'version', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + versionLessThan( + int value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'version', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + versionBetween( + int lower, + int upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'version', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + walletIdEqualTo( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + walletIdGreaterThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + walletIdLessThan( + String value, { + bool include = false, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + walletIdBetween( + String lower, + String upper, { + bool includeLower = true, + bool includeUpper = true, + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'walletId', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + walletIdStartsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.startsWith( + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + walletIdEndsWith( + String value, { + bool caseSensitive = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.endsWith( + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + walletIdContains(String value, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.contains( + property: r'walletId', + value: value, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + walletIdMatches(String pattern, {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.matches( + property: r'walletId', + wildcard: pattern, + caseSensitive: caseSensitive, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + walletIdIsEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'walletId', + value: '', + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + walletIdIsNotEmpty() { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + property: r'walletId', + value: '', + )); + }); + } +} + +extension TransactionV2QueryObject + on QueryBuilder<TransactionV2, TransactionV2, QFilterCondition> { + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + inputsElement(FilterQuery<InputV2> q) { + return QueryBuilder.apply(this, (query) { + return query.object(q, r'inputs'); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + outputsElement(FilterQuery<OutputV2> q) { + return QueryBuilder.apply(this, (query) { + return query.object(q, r'outputs'); + }); + } +} + +extension TransactionV2QueryLinks + on QueryBuilder<TransactionV2, TransactionV2, QFilterCondition> {} + +extension TransactionV2QuerySortBy + on QueryBuilder<TransactionV2, TransactionV2, QSortBy> { + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByBlockHash() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'blockHash', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> + sortByBlockHashDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'blockHash', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByHash() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'hash', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByHashDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'hash', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByHeight() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'height', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByHeightDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'height', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByTimestamp() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'timestamp', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> + sortByTimestampDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'timestamp', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByTxid() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'txid', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByTxidDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'txid', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByVersion() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'version', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByVersionDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'version', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByWalletId() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'walletId', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> + sortByWalletIdDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'walletId', Sort.desc); + }); + } +} + +extension TransactionV2QuerySortThenBy + on QueryBuilder<TransactionV2, TransactionV2, QSortThenBy> { + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByBlockHash() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'blockHash', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> + thenByBlockHashDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'blockHash', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByHash() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'hash', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByHashDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'hash', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByHeight() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'height', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByHeightDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'height', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenById() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'id', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByIdDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'id', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByTimestamp() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'timestamp', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> + thenByTimestampDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'timestamp', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByTxid() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'txid', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByTxidDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'txid', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByVersion() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'version', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByVersionDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'version', Sort.desc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByWalletId() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'walletId', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> + thenByWalletIdDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'walletId', Sort.desc); + }); + } +} + +extension TransactionV2QueryWhereDistinct + on QueryBuilder<TransactionV2, TransactionV2, QDistinct> { + QueryBuilder<TransactionV2, TransactionV2, QDistinct> distinctByBlockHash( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'blockHash', caseSensitive: caseSensitive); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QDistinct> distinctByHash( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'hash', caseSensitive: caseSensitive); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QDistinct> distinctByHeight() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'height'); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QDistinct> distinctByTimestamp() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'timestamp'); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QDistinct> distinctByTxid( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'txid', caseSensitive: caseSensitive); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QDistinct> distinctByVersion() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'version'); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QDistinct> distinctByWalletId( + {bool caseSensitive = true}) { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'walletId', caseSensitive: caseSensitive); + }); + } +} + +extension TransactionV2QueryProperty + on QueryBuilder<TransactionV2, TransactionV2, QQueryProperty> { + QueryBuilder<TransactionV2, int, QQueryOperations> idProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'id'); + }); + } + + QueryBuilder<TransactionV2, String?, QQueryOperations> blockHashProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'blockHash'); + }); + } + + QueryBuilder<TransactionV2, String, QQueryOperations> hashProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'hash'); + }); + } + + QueryBuilder<TransactionV2, int?, QQueryOperations> heightProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'height'); + }); + } + + QueryBuilder<TransactionV2, List<InputV2>, QQueryOperations> + inputsProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'inputs'); + }); + } + + QueryBuilder<TransactionV2, List<OutputV2>, QQueryOperations> + outputsProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'outputs'); + }); + } + + QueryBuilder<TransactionV2, int, QQueryOperations> timestampProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'timestamp'); + }); + } + + QueryBuilder<TransactionV2, String, QQueryOperations> txidProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'txid'); + }); + } + + QueryBuilder<TransactionV2, int, QQueryOperations> versionProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'version'); + }); + } + + QueryBuilder<TransactionV2, String, QQueryOperations> walletIdProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'walletId'); + }); + } +} diff --git a/test/cached_electrumx_test.mocks.dart b/test/cached_electrumx_test.mocks.dart index e44d745d9..468a8c90b 100644 --- a/test/cached_electrumx_test.mocks.dart +++ b/test/cached_electrumx_test.mocks.dart @@ -3,17 +3,19 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i4; -import 'dart:ui' as _i10; +import 'dart:async' as _i5; +import 'dart:ui' as _i11; import 'package:decimal/decimal.dart' as _i2; import 'package:mockito/mockito.dart' as _i1; -import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i3; -import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i8; -import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i7; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i9; -import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i6; -import 'package:stackwallet/utilities/prefs.dart' as _i5; +import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i4; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart' + as _i3; +import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i9; +import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i8; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i10; +import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i7; +import 'package:stackwallet/utilities/prefs.dart' as _i6; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -46,16 +48,26 @@ class _FakeDecimal_1 extends _i1.SmartFake implements _i2.Decimal { ); } +class _FakeFusionInfo_2 extends _i1.SmartFake implements _i3.FusionInfo { + _FakeFusionInfo_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [ElectrumX]. /// /// See the documentation for Mockito's code generation for more information. -class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { +class MockElectrumX extends _i1.Mock implements _i4.ElectrumX { MockElectrumX() { _i1.throwOnMissingStub(this); } @override - set failovers(List<_i3.ElectrumXNode>? _failovers) => super.noSuchMethod( + set failovers(List<_i4.ElectrumXNode>? _failovers) => super.noSuchMethod( Invocation.setter( #failovers, _failovers, @@ -100,7 +112,7 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { returnValue: false, ) as bool); @override - _i4.Future<dynamic> request({ + _i5.Future<dynamic> request({ required String? command, List<dynamic>? args = const [], String? requestID, @@ -119,10 +131,10 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { #requestTimeout: requestTimeout, }, ), - returnValue: _i4.Future<dynamic>.value(), - ) as _i4.Future<dynamic>); + returnValue: _i5.Future<dynamic>.value(), + ) as _i5.Future<dynamic>); @override - _i4.Future<List<Map<String, dynamic>>> batchRequest({ + _i5.Future<List<Map<String, dynamic>>> batchRequest({ required String? command, required Map<String, List<dynamic>>? args, Duration? requestTimeout = const Duration(seconds: 60), @@ -139,11 +151,11 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { #retries: retries, }, ), - returnValue: _i4.Future<List<Map<String, dynamic>>>.value( + returnValue: _i5.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i4.Future<List<Map<String, dynamic>>>); + ) as _i5.Future<List<Map<String, dynamic>>>); @override - _i4.Future<bool> ping({ + _i5.Future<bool> ping({ String? requestID, int? retryCount = 1, }) => @@ -156,10 +168,10 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { #retryCount: retryCount, }, ), - returnValue: _i4.Future<bool>.value(false), - ) as _i4.Future<bool>); + returnValue: _i5.Future<bool>.value(false), + ) as _i5.Future<bool>); @override - _i4.Future<Map<String, dynamic>> getBlockHeadTip({String? requestID}) => + _i5.Future<Map<String, dynamic>> getBlockHeadTip({String? requestID}) => (super.noSuchMethod( Invocation.method( #getBlockHeadTip, @@ -167,10 +179,10 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { {#requestID: requestID}, ), returnValue: - _i4.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i4.Future<Map<String, dynamic>>); + _i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i5.Future<Map<String, dynamic>>); @override - _i4.Future<Map<String, dynamic>> getServerFeatures({String? requestID}) => + _i5.Future<Map<String, dynamic>> getServerFeatures({String? requestID}) => (super.noSuchMethod( Invocation.method( #getServerFeatures, @@ -178,10 +190,10 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { {#requestID: requestID}, ), returnValue: - _i4.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i4.Future<Map<String, dynamic>>); + _i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i5.Future<Map<String, dynamic>>); @override - _i4.Future<String> broadcastTransaction({ + _i5.Future<String> broadcastTransaction({ required String? rawTx, String? requestID, }) => @@ -194,10 +206,10 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { #requestID: requestID, }, ), - returnValue: _i4.Future<String>.value(''), - ) as _i4.Future<String>); + returnValue: _i5.Future<String>.value(''), + ) as _i5.Future<String>); @override - _i4.Future<Map<String, dynamic>> getBalance({ + _i5.Future<Map<String, dynamic>> getBalance({ required String? scripthash, String? requestID, }) => @@ -211,10 +223,10 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { }, ), returnValue: - _i4.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i4.Future<Map<String, dynamic>>); + _i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i5.Future<Map<String, dynamic>>); @override - _i4.Future<List<Map<String, dynamic>>> getHistory({ + _i5.Future<List<Map<String, dynamic>>> getHistory({ required String? scripthash, String? requestID, }) => @@ -227,11 +239,11 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { #requestID: requestID, }, ), - returnValue: _i4.Future<List<Map<String, dynamic>>>.value( + returnValue: _i5.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i4.Future<List<Map<String, dynamic>>>); + ) as _i5.Future<List<Map<String, dynamic>>>); @override - _i4.Future<Map<String, List<Map<String, dynamic>>>> getBatchHistory( + _i5.Future<Map<String, List<Map<String, dynamic>>>> getBatchHistory( {required Map<String, List<dynamic>>? args}) => (super.noSuchMethod( Invocation.method( @@ -239,11 +251,11 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { [], {#args: args}, ), - returnValue: _i4.Future<Map<String, List<Map<String, dynamic>>>>.value( + returnValue: _i5.Future<Map<String, List<Map<String, dynamic>>>>.value( <String, List<Map<String, dynamic>>>{}), - ) as _i4.Future<Map<String, List<Map<String, dynamic>>>>); + ) as _i5.Future<Map<String, List<Map<String, dynamic>>>>); @override - _i4.Future<List<Map<String, dynamic>>> getUTXOs({ + _i5.Future<List<Map<String, dynamic>>> getUTXOs({ required String? scripthash, String? requestID, }) => @@ -256,11 +268,11 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { #requestID: requestID, }, ), - returnValue: _i4.Future<List<Map<String, dynamic>>>.value( + returnValue: _i5.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i4.Future<List<Map<String, dynamic>>>); + ) as _i5.Future<List<Map<String, dynamic>>>); @override - _i4.Future<Map<String, List<Map<String, dynamic>>>> getBatchUTXOs( + _i5.Future<Map<String, List<Map<String, dynamic>>>> getBatchUTXOs( {required Map<String, List<dynamic>>? args}) => (super.noSuchMethod( Invocation.method( @@ -268,11 +280,11 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { [], {#args: args}, ), - returnValue: _i4.Future<Map<String, List<Map<String, dynamic>>>>.value( + returnValue: _i5.Future<Map<String, List<Map<String, dynamic>>>>.value( <String, List<Map<String, dynamic>>>{}), - ) as _i4.Future<Map<String, List<Map<String, dynamic>>>>); + ) as _i5.Future<Map<String, List<Map<String, dynamic>>>>); @override - _i4.Future<Map<String, dynamic>> getTransaction({ + _i5.Future<Map<String, dynamic>> getTransaction({ required String? txHash, bool? verbose = true, String? requestID, @@ -288,10 +300,10 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { }, ), returnValue: - _i4.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i4.Future<Map<String, dynamic>>); + _i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i5.Future<Map<String, dynamic>>); @override - _i4.Future<Map<String, dynamic>> getAnonymitySet({ + _i5.Future<Map<String, dynamic>> getAnonymitySet({ String? groupId = r'1', String? blockhash = r'', String? requestID, @@ -307,10 +319,10 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { }, ), returnValue: - _i4.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i4.Future<Map<String, dynamic>>); + _i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i5.Future<Map<String, dynamic>>); @override - _i4.Future<dynamic> getMintData({ + _i5.Future<dynamic> getMintData({ dynamic mints, String? requestID, }) => @@ -323,10 +335,10 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { #requestID: requestID, }, ), - returnValue: _i4.Future<dynamic>.value(), - ) as _i4.Future<dynamic>); + returnValue: _i5.Future<dynamic>.value(), + ) as _i5.Future<dynamic>); @override - _i4.Future<Map<String, dynamic>> getUsedCoinSerials({ + _i5.Future<Map<String, dynamic>> getUsedCoinSerials({ String? requestID, required int? startNumber, }) => @@ -340,19 +352,19 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { }, ), returnValue: - _i4.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i4.Future<Map<String, dynamic>>); + _i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i5.Future<Map<String, dynamic>>); @override - _i4.Future<int> getLatestCoinId({String? requestID}) => (super.noSuchMethod( + _i5.Future<int> getLatestCoinId({String? requestID}) => (super.noSuchMethod( Invocation.method( #getLatestCoinId, [], {#requestID: requestID}, ), - returnValue: _i4.Future<int>.value(0), - ) as _i4.Future<int>); + returnValue: _i5.Future<int>.value(0), + ) as _i5.Future<int>); @override - _i4.Future<Map<String, dynamic>> getFeeRate({String? requestID}) => + _i5.Future<Map<String, dynamic>> getFeeRate({String? requestID}) => (super.noSuchMethod( Invocation.method( #getFeeRate, @@ -360,10 +372,10 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { {#requestID: requestID}, ), returnValue: - _i4.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i4.Future<Map<String, dynamic>>); + _i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i5.Future<Map<String, dynamic>>); @override - _i4.Future<_i2.Decimal> estimateFee({ + _i5.Future<_i2.Decimal> estimateFee({ String? requestID, required int? blocks, }) => @@ -376,7 +388,7 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { #blocks: blocks, }, ), - returnValue: _i4.Future<_i2.Decimal>.value(_FakeDecimal_1( + returnValue: _i5.Future<_i2.Decimal>.value(_FakeDecimal_1( this, Invocation.method( #estimateFee, @@ -387,15 +399,15 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { }, ), )), - ) as _i4.Future<_i2.Decimal>); + ) as _i5.Future<_i2.Decimal>); @override - _i4.Future<_i2.Decimal> relayFee({String? requestID}) => (super.noSuchMethod( + _i5.Future<_i2.Decimal> relayFee({String? requestID}) => (super.noSuchMethod( Invocation.method( #relayFee, [], {#requestID: requestID}, ), - returnValue: _i4.Future<_i2.Decimal>.value(_FakeDecimal_1( + returnValue: _i5.Future<_i2.Decimal>.value(_FakeDecimal_1( this, Invocation.method( #relayFee, @@ -403,13 +415,13 @@ class MockElectrumX extends _i1.Mock implements _i3.ElectrumX { {#requestID: requestID}, ), )), - ) as _i4.Future<_i2.Decimal>); + ) as _i5.Future<_i2.Decimal>); } /// A class which mocks [Prefs]. /// /// See the documentation for Mockito's code generation for more information. -class MockPrefs extends _i1.Mock implements _i5.Prefs { +class MockPrefs extends _i1.Mock implements _i6.Prefs { MockPrefs() { _i1.throwOnMissingStub(this); } @@ -465,12 +477,12 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override - _i6.SyncingType get syncType => (super.noSuchMethod( + _i7.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), - returnValue: _i6.SyncingType.currentWalletOnly, - ) as _i6.SyncingType); + returnValue: _i7.SyncingType.currentWalletOnly, + ) as _i7.SyncingType); @override - set syncType(_i6.SyncingType? syncType) => super.noSuchMethod( + set syncType(_i7.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( #syncType, syncType, @@ -629,12 +641,12 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override - _i7.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( + _i8.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), - returnValue: _i7.BackupFrequencyType.everyTenMinutes, - ) as _i7.BackupFrequencyType); + returnValue: _i8.BackupFrequencyType.everyTenMinutes, + ) as _i8.BackupFrequencyType); @override - set backupFrequencyType(_i7.BackupFrequencyType? backupFrequencyType) => + set backupFrequencyType(_i8.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( Invocation.setter( #backupFrequencyType, @@ -780,66 +792,82 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override + _i3.FusionInfo get fusionServerInfo => (super.noSuchMethod( + Invocation.getter(#fusionServerInfo), + returnValue: _FakeFusionInfo_2( + this, + Invocation.getter(#fusionServerInfo), + ), + ) as _i3.FusionInfo); + @override + set fusionServerInfo(_i3.FusionInfo? fusionServerInfo) => super.noSuchMethod( + Invocation.setter( + #fusionServerInfo, + fusionServerInfo, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i4.Future<void> init() => (super.noSuchMethod( + _i5.Future<void> init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); @override - _i4.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( + _i5.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( #incrementCurrentNotificationIndex, [], ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); @override - _i4.Future<bool> isExternalCallsSet() => (super.noSuchMethod( + _i5.Future<bool> isExternalCallsSet() => (super.noSuchMethod( Invocation.method( #isExternalCallsSet, [], ), - returnValue: _i4.Future<bool>.value(false), - ) as _i4.Future<bool>); + returnValue: _i5.Future<bool>.value(false), + ) as _i5.Future<bool>); @override - _i4.Future<void> saveUserID(String? userId) => (super.noSuchMethod( + _i5.Future<void> saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( #saveUserID, [userId], ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); @override - _i4.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( + _i5.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( #saveSignupEpoch, [signupEpoch], ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); @override - _i8.AmountUnit amountUnit(_i9.Coin? coin) => (super.noSuchMethod( + _i9.AmountUnit amountUnit(_i10.Coin? coin) => (super.noSuchMethod( Invocation.method( #amountUnit, [coin], ), - returnValue: _i8.AmountUnit.normal, - ) as _i8.AmountUnit); + returnValue: _i9.AmountUnit.normal, + ) as _i9.AmountUnit); @override void updateAmountUnit({ - required _i9.Coin? coin, - required _i8.AmountUnit? amountUnit, + required _i10.Coin? coin, + required _i9.AmountUnit? amountUnit, }) => super.noSuchMethod( Invocation.method( @@ -853,7 +881,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override - int maxDecimals(_i9.Coin? coin) => (super.noSuchMethod( + int maxDecimals(_i10.Coin? coin) => (super.noSuchMethod( Invocation.method( #maxDecimals, [coin], @@ -862,7 +890,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ) as int); @override void updateMaxDecimals({ - required _i9.Coin? coin, + required _i10.Coin? coin, required int? maxDecimals, }) => super.noSuchMethod( @@ -877,7 +905,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override - void addListener(_i10.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i11.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -885,7 +913,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override - void removeListener(_i10.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i11.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], diff --git a/test/electrumx_test.mocks.dart b/test/electrumx_test.mocks.dart index 557b983a6..8f683b2f1 100644 --- a/test/electrumx_test.mocks.dart +++ b/test/electrumx_test.mocks.dart @@ -3,21 +3,23 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i4; -import 'dart:io' as _i3; -import 'dart:ui' as _i10; +import 'dart:async' as _i5; +import 'dart:io' as _i4; +import 'dart:ui' as _i11; import 'package:mockito/mockito.dart' as _i1; import 'package:stackwallet/electrumx_rpc/rpc.dart' as _i2; import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart' - as _i12; -import 'package:stackwallet/services/tor_service.dart' as _i11; -import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i8; -import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i7; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i9; -import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i6; -import 'package:stackwallet/utilities/prefs.dart' as _i5; -import 'package:tor_ffi_plugin/tor_ffi_plugin.dart' as _i13; + as _i13; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart' + as _i3; +import 'package:stackwallet/services/tor_service.dart' as _i12; +import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i9; +import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i8; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i10; +import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i7; +import 'package:stackwallet/utilities/prefs.dart' as _i6; +import 'package:tor_ffi_plugin/tor_ffi_plugin.dart' as _i14; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -51,9 +53,19 @@ class _FakeJsonRPCResponse_1 extends _i1.SmartFake ); } -class _FakeInternetAddress_2 extends _i1.SmartFake - implements _i3.InternetAddress { - _FakeInternetAddress_2( +class _FakeFusionInfo_2 extends _i1.SmartFake implements _i3.FusionInfo { + _FakeFusionInfo_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeInternetAddress_3 extends _i1.SmartFake + implements _i4.InternetAddress { + _FakeInternetAddress_3( Object parent, Invocation parentInvocation, ) : super( @@ -94,7 +106,7 @@ class MockJsonRPC extends _i1.Mock implements _i2.JsonRPC { ), ) as Duration); @override - set proxyInfo(({_i3.InternetAddress host, int port})? _proxyInfo) => + set proxyInfo(({_i4.InternetAddress host, int port})? _proxyInfo) => super.noSuchMethod( Invocation.setter( #proxyInfo, @@ -103,7 +115,7 @@ class MockJsonRPC extends _i1.Mock implements _i2.JsonRPC { returnValueForMissingStub: null, ); @override - _i4.Future<_i2.JsonRPCResponse> request( + _i5.Future<_i2.JsonRPCResponse> request( String? jsonRpcRequest, Duration? requestTimeout, ) => @@ -116,7 +128,7 @@ class MockJsonRPC extends _i1.Mock implements _i2.JsonRPC { ], ), returnValue: - _i4.Future<_i2.JsonRPCResponse>.value(_FakeJsonRPCResponse_1( + _i5.Future<_i2.JsonRPCResponse>.value(_FakeJsonRPCResponse_1( this, Invocation.method( #request, @@ -126,32 +138,32 @@ class MockJsonRPC extends _i1.Mock implements _i2.JsonRPC { ], ), )), - ) as _i4.Future<_i2.JsonRPCResponse>); + ) as _i5.Future<_i2.JsonRPCResponse>); @override - _i4.Future<void> disconnect({required String? reason}) => (super.noSuchMethod( + _i5.Future<void> disconnect({required String? reason}) => (super.noSuchMethod( Invocation.method( #disconnect, [], {#reason: reason}, ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); @override - _i4.Future<void> connect() => (super.noSuchMethod( + _i5.Future<void> connect() => (super.noSuchMethod( Invocation.method( #connect, [], ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); } /// A class which mocks [Prefs]. /// /// See the documentation for Mockito's code generation for more information. -class MockPrefs extends _i1.Mock implements _i5.Prefs { +class MockPrefs extends _i1.Mock implements _i6.Prefs { MockPrefs() { _i1.throwOnMissingStub(this); } @@ -207,12 +219,12 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override - _i6.SyncingType get syncType => (super.noSuchMethod( + _i7.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), - returnValue: _i6.SyncingType.currentWalletOnly, - ) as _i6.SyncingType); + returnValue: _i7.SyncingType.currentWalletOnly, + ) as _i7.SyncingType); @override - set syncType(_i6.SyncingType? syncType) => super.noSuchMethod( + set syncType(_i7.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( #syncType, syncType, @@ -371,12 +383,12 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override - _i7.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( + _i8.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), - returnValue: _i7.BackupFrequencyType.everyTenMinutes, - ) as _i7.BackupFrequencyType); + returnValue: _i8.BackupFrequencyType.everyTenMinutes, + ) as _i8.BackupFrequencyType); @override - set backupFrequencyType(_i7.BackupFrequencyType? backupFrequencyType) => + set backupFrequencyType(_i8.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( Invocation.setter( #backupFrequencyType, @@ -522,66 +534,82 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override + _i3.FusionInfo get fusionServerInfo => (super.noSuchMethod( + Invocation.getter(#fusionServerInfo), + returnValue: _FakeFusionInfo_2( + this, + Invocation.getter(#fusionServerInfo), + ), + ) as _i3.FusionInfo); + @override + set fusionServerInfo(_i3.FusionInfo? fusionServerInfo) => super.noSuchMethod( + Invocation.setter( + #fusionServerInfo, + fusionServerInfo, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i4.Future<void> init() => (super.noSuchMethod( + _i5.Future<void> init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); @override - _i4.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( + _i5.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( #incrementCurrentNotificationIndex, [], ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); @override - _i4.Future<bool> isExternalCallsSet() => (super.noSuchMethod( + _i5.Future<bool> isExternalCallsSet() => (super.noSuchMethod( Invocation.method( #isExternalCallsSet, [], ), - returnValue: _i4.Future<bool>.value(false), - ) as _i4.Future<bool>); + returnValue: _i5.Future<bool>.value(false), + ) as _i5.Future<bool>); @override - _i4.Future<void> saveUserID(String? userId) => (super.noSuchMethod( + _i5.Future<void> saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( #saveUserID, [userId], ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); @override - _i4.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( + _i5.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( #saveSignupEpoch, [signupEpoch], ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); @override - _i8.AmountUnit amountUnit(_i9.Coin? coin) => (super.noSuchMethod( + _i9.AmountUnit amountUnit(_i10.Coin? coin) => (super.noSuchMethod( Invocation.method( #amountUnit, [coin], ), - returnValue: _i8.AmountUnit.normal, - ) as _i8.AmountUnit); + returnValue: _i9.AmountUnit.normal, + ) as _i9.AmountUnit); @override void updateAmountUnit({ - required _i9.Coin? coin, - required _i8.AmountUnit? amountUnit, + required _i10.Coin? coin, + required _i9.AmountUnit? amountUnit, }) => super.noSuchMethod( Invocation.method( @@ -595,7 +623,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override - int maxDecimals(_i9.Coin? coin) => (super.noSuchMethod( + int maxDecimals(_i10.Coin? coin) => (super.noSuchMethod( Invocation.method( #maxDecimals, [coin], @@ -604,7 +632,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { ) as int); @override void updateMaxDecimals({ - required _i9.Coin? coin, + required _i10.Coin? coin, required int? maxDecimals, }) => super.noSuchMethod( @@ -619,7 +647,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override - void addListener(_i10.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i11.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -627,7 +655,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { returnValueForMissingStub: null, ); @override - void removeListener(_i10.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i11.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -655,24 +683,24 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs { /// A class which mocks [TorService]. /// /// See the documentation for Mockito's code generation for more information. -class MockTorService extends _i1.Mock implements _i11.TorService { +class MockTorService extends _i1.Mock implements _i12.TorService { MockTorService() { _i1.throwOnMissingStub(this); } @override - _i12.TorConnectionStatus get status => (super.noSuchMethod( + _i13.TorConnectionStatus get status => (super.noSuchMethod( Invocation.getter(#status), - returnValue: _i12.TorConnectionStatus.disconnected, - ) as _i12.TorConnectionStatus); + returnValue: _i13.TorConnectionStatus.disconnected, + ) as _i13.TorConnectionStatus); @override - ({_i3.InternetAddress host, int port}) getProxyInfo() => (super.noSuchMethod( + ({_i4.InternetAddress host, int port}) getProxyInfo() => (super.noSuchMethod( Invocation.method( #getProxyInfo, [], ), returnValue: ( - host: _FakeInternetAddress_2( + host: _FakeInternetAddress_3( this, Invocation.method( #getProxyInfo, @@ -681,11 +709,11 @@ class MockTorService extends _i1.Mock implements _i11.TorService { ), port: 0 ), - ) as ({_i3.InternetAddress host, int port})); + ) as ({_i4.InternetAddress host, int port})); @override void init({ required String? torDataDirPath, - _i13.Tor? mockableOverride, + _i14.Tor? mockableOverride, }) => super.noSuchMethod( Invocation.method( @@ -699,21 +727,21 @@ class MockTorService extends _i1.Mock implements _i11.TorService { returnValueForMissingStub: null, ); @override - _i4.Future<void> start() => (super.noSuchMethod( + _i5.Future<void> start() => (super.noSuchMethod( Invocation.method( #start, [], ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); @override - _i4.Future<void> disable() => (super.noSuchMethod( + _i5.Future<void> disable() => (super.noSuchMethod( Invocation.method( #disable, [], ), - returnValue: _i4.Future<void>.value(), - returnValueForMissingStub: _i4.Future<void>.value(), - ) as _i4.Future<void>); + returnValue: _i5.Future<void>.value(), + returnValueForMissingStub: _i5.Future<void>.value(), + ) as _i5.Future<void>); } diff --git a/test/pages/send_view/send_view_test.mocks.dart b/test/pages/send_view/send_view_test.mocks.dart index d2d5de661..44ab4fc52 100644 --- a/test/pages/send_view/send_view_test.mocks.dart +++ b/test/pages/send_view/send_view_test.mocks.dart @@ -3,12 +3,12 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i24; -import 'dart:typed_data' as _i31; -import 'dart:ui' as _i26; +import 'dart:async' as _i26; +import 'dart:typed_data' as _i33; +import 'dart:ui' as _i28; -import 'package:bip32/bip32.dart' as _i17; -import 'package:bip47/bip47.dart' as _i19; +import 'package:bip32/bip32.dart' as _i18; +import 'package:bip47/bip47.dart' as _i20; import 'package:bitcoindart/bitcoindart.dart' as _i14; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -17,32 +17,36 @@ import 'package:stackwallet/db/isar/main_db.dart' as _i13; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i11; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i10; import 'package:stackwallet/models/balance.dart' as _i12; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i18; -import 'package:stackwallet/models/isar/stack_theme.dart' as _i34; -import 'package:stackwallet/models/node_model.dart' as _i27; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart' + as _i16; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i19; +import 'package:stackwallet/models/isar/stack_theme.dart' as _i36; +import 'package:stackwallet/models/node_model.dart' as _i29; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i9; -import 'package:stackwallet/models/signing_data.dart' as _i30; -import 'package:stackwallet/networking/http.dart' as _i20; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i28; -import 'package:stackwallet/services/coins/coin_service.dart' as _i21; +import 'package:stackwallet/models/signing_data.dart' as _i32; +import 'package:stackwallet/networking/http.dart' as _i21; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i30; +import 'package:stackwallet/services/coins/coin_service.dart' as _i23; import 'package:stackwallet/services/coins/manager.dart' as _i6; -import 'package:stackwallet/services/locale_service.dart' as _i32; +import 'package:stackwallet/services/locale_service.dart' as _i34; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart' + as _i22; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i8; -import 'package:stackwallet/services/wallets.dart' as _i22; +import 'package:stackwallet/services/wallets.dart' as _i24; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/themes/theme_service.dart' as _i33; +import 'package:stackwallet/themes/theme_service.dart' as _i35; import 'package:stackwallet/utilities/amount/amount.dart' as _i15; -import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i37; -import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i36; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i23; -import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i29; -import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i35; +import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i39; +import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i38; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i25; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i31; +import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i37; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' as _i7; -import 'package:stackwallet/utilities/prefs.dart' as _i25; -import 'package:tuple/tuple.dart' as _i16; +import 'package:stackwallet/utilities/prefs.dart' as _i27; +import 'package:tuple/tuple.dart' as _i17; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -201,9 +205,9 @@ class _FakeAmount_13 extends _i1.SmartFake implements _i15.Amount { ); } -class _FakeTuple2_14<T1, T2> extends _i1.SmartFake - implements _i16.Tuple2<T1, T2> { - _FakeTuple2_14( +class _FakeTransactionV2_14 extends _i1.SmartFake + implements _i16.TransactionV2 { + _FakeTransactionV2_14( Object parent, Invocation parentInvocation, ) : super( @@ -212,8 +216,9 @@ class _FakeTuple2_14<T1, T2> extends _i1.SmartFake ); } -class _FakeBIP32_15 extends _i1.SmartFake implements _i17.BIP32 { - _FakeBIP32_15( +class _FakeTuple2_15<T1, T2> extends _i1.SmartFake + implements _i17.Tuple2<T1, T2> { + _FakeTuple2_15( Object parent, Invocation parentInvocation, ) : super( @@ -222,8 +227,8 @@ class _FakeBIP32_15 extends _i1.SmartFake implements _i17.BIP32 { ); } -class _FakeAddress_16 extends _i1.SmartFake implements _i18.Address { - _FakeAddress_16( +class _FakeBIP32_16 extends _i1.SmartFake implements _i18.BIP32 { + _FakeBIP32_16( Object parent, Invocation parentInvocation, ) : super( @@ -232,8 +237,8 @@ class _FakeAddress_16 extends _i1.SmartFake implements _i18.Address { ); } -class _FakePaymentCode_17 extends _i1.SmartFake implements _i19.PaymentCode { - _FakePaymentCode_17( +class _FakeAddress_17 extends _i1.SmartFake implements _i19.Address { + _FakeAddress_17( Object parent, Invocation parentInvocation, ) : super( @@ -242,8 +247,8 @@ class _FakePaymentCode_17 extends _i1.SmartFake implements _i19.PaymentCode { ); } -class _FakeHTTP_18 extends _i1.SmartFake implements _i20.HTTP { - _FakeHTTP_18( +class _FakePaymentCode_18 extends _i1.SmartFake implements _i20.PaymentCode { + _FakePaymentCode_18( Object parent, Invocation parentInvocation, ) : super( @@ -252,9 +257,29 @@ class _FakeHTTP_18 extends _i1.SmartFake implements _i20.HTTP { ); } -class _FakeCoinServiceAPI_19 extends _i1.SmartFake - implements _i21.CoinServiceAPI { - _FakeCoinServiceAPI_19( +class _FakeHTTP_19 extends _i1.SmartFake implements _i21.HTTP { + _FakeHTTP_19( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeFusionInfo_20 extends _i1.SmartFake implements _i22.FusionInfo { + _FakeFusionInfo_20( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_21 extends _i1.SmartFake + implements _i23.CoinServiceAPI { + _FakeCoinServiceAPI_21( Object parent, Invocation parentInvocation, ) : super( @@ -266,7 +291,7 @@ class _FakeCoinServiceAPI_19 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i22.Wallets { +class MockWallets extends _i1.Mock implements _i24.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -333,7 +358,7 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i23.Coin? coin}) => + List<String> getWalletIdsFor({required _i25.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -343,20 +368,20 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValue: <String>[], ) as List<String>); @override - List<_i16.Tuple2<_i23.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> + List<_i17.Tuple2<_i25.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i16.Tuple2<_i23.Coin, + returnValue: <_i17.Tuple2<_i25.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>[], ) as List< - _i16.Tuple2<_i23.Coin, + _i17.Tuple2<_i25.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i23.Coin? coin) => + _i25.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -420,17 +445,17 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValueForMissingStub: null, ); @override - _i24.Future<void> load(_i25.Prefs? prefs) => (super.noSuchMethod( + _i26.Future<void> load(_i27.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> loadAfterStackRestore( - _i25.Prefs? prefs, + _i26.Future<void> loadAfterStackRestore( + _i27.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -441,11 +466,11 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { managers, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -453,7 +478,7 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -479,19 +504,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i24.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i26.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i24.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i26.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i24.Future<Map<String, _i2.WalletInfo>>); + ) as _i26.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i24.Future<bool> renameWallet({ + _i26.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -506,8 +531,8 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override Map<String, _i2.WalletInfo> fetchWalletsData() => (super.noSuchMethod( Invocation.method( @@ -517,10 +542,10 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: <String, _i2.WalletInfo>{}, ) as Map<String, _i2.WalletInfo>); @override - _i24.Future<void> addExistingStackWallet({ + _i26.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i23.Coin? coin, + required _i25.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -534,13 +559,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<String?> addNewWallet({ + _i26.Future<String?> addNewWallet({ required String? name, - required _i23.Coin? coin, + required _i25.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -553,46 +578,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i26.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i26.Future<List<String>>.value(<String>[]), + ) as _i26.Future<List<String>>); @override - _i24.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i26.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i26.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i26.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> moveFavorite({ + _i26.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -605,48 +630,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i26.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i26.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<bool> isMnemonicVerified({required String? walletId}) => + _i26.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> setMnemonicVerified({required String? walletId}) => + _i26.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<int> deleteWallet( + _i26.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -658,20 +683,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override - _i24.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i26.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -679,7 +704,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -721,33 +746,33 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { ), ) as _i7.SecureStorageInterface); @override - List<_i27.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i29.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i27.NodeModel>[], - ) as List<_i27.NodeModel>); + returnValue: <_i29.NodeModel>[], + ) as List<_i29.NodeModel>); @override - List<_i27.NodeModel> get nodes => (super.noSuchMethod( + List<_i29.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i27.NodeModel>[], - ) as List<_i27.NodeModel>); + returnValue: <_i29.NodeModel>[], + ) as List<_i29.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i24.Future<void> updateDefaults() => (super.noSuchMethod( + _i26.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> setPrimaryNodeFor({ - required _i23.Coin? coin, - required _i27.NodeModel? node, + _i26.Future<void> setPrimaryNodeFor({ + required _i25.Coin? coin, + required _i29.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -760,44 +785,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i27.NodeModel? getPrimaryNodeFor({required _i23.Coin? coin}) => + _i29.NodeModel? getPrimaryNodeFor({required _i25.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i27.NodeModel?); + )) as _i29.NodeModel?); @override - List<_i27.NodeModel> getNodesFor(_i23.Coin? coin) => (super.noSuchMethod( + List<_i29.NodeModel> getNodesFor(_i25.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i27.NodeModel>[], - ) as List<_i27.NodeModel>); + returnValue: <_i29.NodeModel>[], + ) as List<_i29.NodeModel>); @override - _i27.NodeModel? getNodeById({required String? id}) => + _i29.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i27.NodeModel?); + )) as _i29.NodeModel?); @override - List<_i27.NodeModel> failoverNodesFor({required _i23.Coin? coin}) => + List<_i29.NodeModel> failoverNodesFor({required _i25.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i27.NodeModel>[], - ) as List<_i27.NodeModel>); + returnValue: <_i29.NodeModel>[], + ) as List<_i29.NodeModel>); @override - _i24.Future<void> add( - _i27.NodeModel? node, + _i26.Future<void> add( + _i29.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -810,11 +835,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> delete( + _i26.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -826,11 +851,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> setEnabledState( + _i26.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -844,12 +869,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> edit( - _i27.NodeModel? editedNode, + _i26.Future<void> edit( + _i29.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -862,20 +887,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i26.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -883,7 +908,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -911,13 +936,13 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i24.Timer? _timer) => super.noSuchMethod( + set timer(_i26.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -994,74 +1019,74 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { returnValue: false, ) as bool); @override - _i23.Coin get coin => (super.noSuchMethod( + _i25.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i23.Coin.bitcoin, - ) as _i23.Coin); + returnValue: _i25.Coin.bitcoin, + ) as _i25.Coin); @override - _i24.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( + _i26.Future<List<_i19.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i24.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), - ) as _i24.Future<List<_i18.UTXO>>); + returnValue: _i26.Future<List<_i19.UTXO>>.value(<_i19.UTXO>[]), + ) as _i26.Future<List<_i19.UTXO>>); @override - _i24.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( + _i26.Future<List<_i19.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i24.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), - ) as _i24.Future<List<_i18.Transaction>>); + _i26.Future<List<_i19.Transaction>>.value(<_i19.Transaction>[]), + ) as _i26.Future<List<_i19.Transaction>>); @override - _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i26.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i26.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( + _i26.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( Invocation.getter(#currentChangeAddressP2PKH), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i24.Future<_i9.FeeObject> get fees => (super.noSuchMethod( + _i26.Future<_i9.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i24.Future<_i9.FeeObject>.value(_FakeFeeObject_6( + returnValue: _i26.Future<_i9.FeeObject>.value(_FakeFeeObject_6( this, Invocation.getter(#fees), )), - ) as _i24.Future<_i9.FeeObject>); + ) as _i26.Future<_i9.FeeObject>); @override - _i24.Future<int> get maxFee => (super.noSuchMethod( + _i26.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override - _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i26.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i26.Future<List<String>>.value(<String>[]), + ) as _i26.Future<List<String>>); @override - _i24.Future<String?> get mnemonicString => (super.noSuchMethod( + _i26.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i26.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<int> get chainHeight => (super.noSuchMethod( + _i26.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -1133,10 +1158,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { ), ) as _i12.Balance); @override - _i24.Future<String> get xpub => (super.noSuchMethod( + _i26.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1163,26 +1188,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { ), ) as _i14.NetworkType); @override - _i24.Future<void> exit() => (super.noSuchMethod( + _i26.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i29.DerivePathType addressType({required String? address}) => + _i31.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i29.DerivePathType.bip44, - ) as _i29.DerivePathType); + returnValue: _i31.DerivePathType.bip44, + ) as _i31.DerivePathType); @override - _i24.Future<void> recoverFromMnemonic({ + _i26.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -1201,47 +1226,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { #height: height, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i26.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i26.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i26.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> refresh() => (super.noSuchMethod( + _i26.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<Map<String, dynamic>> prepareSend({ + _i26.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -1257,26 +1282,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i26.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i26.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -1294,35 +1319,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<void> initializeNew( + _i26.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> initializeExisting() => (super.noSuchMethod( + _i26.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i26.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1332,70 +1357,70 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { returnValue: false, ) as bool); @override - _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i26.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i10.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i26.Future<_i10.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), returnValue: - _i24.Future<_i10.ElectrumXNode>.value(_FakeElectrumXNode_12( + _i26.Future<_i10.ElectrumXNode>.value(_FakeElectrumXNode_12( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i24.Future<_i10.ElectrumXNode>); + ) as _i26.Future<_i10.ElectrumXNode>); @override - _i24.Future<List<Map<String, dynamic>>> fastFetch( + _i26.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i24.Future<List<Map<String, dynamic>>>.value( + returnValue: _i26.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i24.Future<List<Map<String, dynamic>>>); + ) as _i26.Future<List<Map<String, dynamic>>>); @override - _i24.Future<int> getTxCount({required String? address}) => + _i26.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override - _i24.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i26.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> checkCurrentChangeAddressesForTransactions() => + _i26.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1421,7 +1446,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { required bool? isSendAll, int? satsPerVByte, int? additionalOutputs = 0, - List<_i18.UTXO>? utxos, + List<_i19.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1438,19 +1463,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { }, )); @override - _i24.Future<List<_i30.SigningData>> fetchBuildTxData( - List<_i18.UTXO>? utxosToUse) => + _i26.Future<List<_i32.SigningData>> fetchBuildTxData( + List<_i19.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i24.Future<List<_i30.SigningData>>.value(<_i30.SigningData>[]), - ) as _i24.Future<List<_i30.SigningData>>); + _i26.Future<List<_i32.SigningData>>.value(<_i32.SigningData>[]), + ) as _i26.Future<List<_i32.SigningData>>); @override - _i24.Future<Map<String, dynamic>> buildTransaction({ - required List<_i30.SigningData>? utxoSigningData, + _i26.Future<Map<String, dynamic>> buildTransaction({ + required List<_i32.SigningData>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, }) => @@ -1465,10 +1490,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<void> fullRescan( + _i26.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1480,11 +1505,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i15.Amount> estimateFeeFor( + _i26.Future<_i15.Amount> estimateFeeFor( _i15.Amount? amount, int? feeRate, ) => @@ -1496,7 +1521,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { feeRate, ], ), - returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i26.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #estimateFeeFor, @@ -1506,7 +1531,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { ], ), )), - ) as _i24.Future<_i15.Amount>); + ) as _i26.Future<_i15.Amount>); @override _i15.Amount roughFeeEstimate( int? inputCount, @@ -1535,32 +1560,32 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { ), ) as _i15.Amount); @override - _i24.Future<_i15.Amount> sweepAllEstimate(int? feeRate) => + _i26.Future<_i15.Amount> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i26.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #sweepAllEstimate, [feeRate], ), )), - ) as _i24.Future<_i15.Amount>); + ) as _i26.Future<_i15.Amount>); @override - _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i26.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override void initCache( String? walletId, - _i23.Coin? coin, + _i25.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1573,14 +1598,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i26.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1590,14 +1615,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { returnValue: 0, ) as int); @override - _i24.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i26.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1607,15 +1632,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { returnValue: false, ) as bool); @override - _i24.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i26.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override _i12.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1631,15 +1656,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { ), ) as _i12.Balance); @override - _i24.Future<void> updateCachedBalance(_i12.Balance? balance) => + _i26.Future<void> updateCachedBalance(_i12.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override _i12.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1655,15 +1680,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { ), ) as _i12.Balance); @override - _i24.Future<void> updateCachedBalanceSecondary(_i12.Balance? balance) => + _i26.Future<void> updateCachedBalanceSecondary(_i12.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override List<String> getWalletTokenContractAddresses() => (super.noSuchMethod( Invocation.method( @@ -1673,16 +1698,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { returnValue: <String>[], ) as List<String>); @override - _i24.Future<void> updateWalletTokenContractAddresses( + _i26.Future<void> updateWalletTokenContractAddresses( List<String>? contractAddresses) => (super.noSuchMethod( Invocation.method( #updateWalletTokenContractAddresses, [contractAddresses], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override void initWalletDB({_i13.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1693,11 +1718,45 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>> parseTransaction( + _i26.Future<_i16.TransactionV2> getTransaction( + String? txHash, + _i25.Coin? coin, + String? walletId, + _i11.CachedElectrumX? cachedElectrumX, [ + String? debugTitle, + ]) => + (super.noSuchMethod( + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + returnValue: + _i26.Future<_i16.TransactionV2>.value(_FakeTransactionV2_14( + this, + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + )), + ) as _i26.Future<_i16.TransactionV2>); + @override + _i26.Future<_i17.Tuple2<_i19.Transaction, _i19.Address>> parseTransaction( Map<String, dynamic>? txData, dynamic electrumxClient, - List<_i18.Address>? myAddresses, - _i23.Coin? coin, + List<_i19.Address>? myAddresses, + _i25.Coin? coin, int? minConfirms, String? walletId, ) => @@ -1714,8 +1773,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { ], ), returnValue: - _i24.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>.value( - _FakeTuple2_14<_i18.Transaction, _i18.Address>( + _i26.Future<_i17.Tuple2<_i19.Transaction, _i19.Address>>.value( + _FakeTuple2_15<_i19.Transaction, _i19.Address>( this, Invocation.method( #parseTransaction, @@ -1729,37 +1788,37 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { ], ), )), - ) as _i24.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>); + ) as _i26.Future<_i17.Tuple2<_i19.Transaction, _i19.Address>>); @override void initPaynymWalletInterface({ required String? walletId, required String? walletName, required _i14.NetworkType? network, - required _i23.Coin? coin, + required _i25.Coin? coin, required _i13.MainDB? db, required _i10.ElectrumX? electrumXClient, required _i7.SecureStorageInterface? secureStorage, required int? dustLimit, required int? dustLimitP2PKH, required int? minConfirms, - required _i24.Future<String?> Function()? getMnemonicString, - required _i24.Future<String?> Function()? getMnemonicPassphrase, - required _i24.Future<int> Function()? getChainHeight, - required _i24.Future<String> Function()? getCurrentChangeAddress, + required _i26.Future<String?> Function()? getMnemonicString, + required _i26.Future<String?> Function()? getMnemonicPassphrase, + required _i26.Future<int> Function()? getChainHeight, + required _i26.Future<String> Function()? getCurrentChangeAddress, required int Function({ required int feeRatePerKB, required int vSize, })? estimateTxFee, - required _i24.Future<Map<String, dynamic>> Function({ + required _i26.Future<Map<String, dynamic>> Function({ required String address, required _i15.Amount amount, Map<String, dynamic>? args, })? prepareSend, - required _i24.Future<int> Function({required String address})? getTxCount, - required _i24.Future<List<_i30.SigningData>> Function(List<_i18.UTXO>)? + required _i26.Future<int> Function({required String address})? getTxCount, + required _i26.Future<List<_i32.SigningData>> Function(List<_i19.UTXO>)? fetchBuildTxData, - required _i24.Future<void> Function()? refresh, - required _i24.Future<void> Function()? checkChangeAddressForTransactions, + required _i26.Future<void> Function()? refresh, + required _i26.Future<void> Function()? checkChangeAddressForTransactions, }) => super.noSuchMethod( Invocation.method( @@ -1792,21 +1851,21 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<_i17.BIP32> getBip47BaseNode() => (super.noSuchMethod( + _i26.Future<_i18.BIP32> getBip47BaseNode() => (super.noSuchMethod( Invocation.method( #getBip47BaseNode, [], ), - returnValue: _i24.Future<_i17.BIP32>.value(_FakeBIP32_15( + returnValue: _i26.Future<_i18.BIP32>.value(_FakeBIP32_16( this, Invocation.method( #getBip47BaseNode, [], ), )), - ) as _i24.Future<_i17.BIP32>); + ) as _i26.Future<_i18.BIP32>); @override - _i24.Future<_i31.Uint8List> getPrivateKeyForPaynymReceivingAddress({ + _i26.Future<_i33.Uint8List> getPrivateKeyForPaynymReceivingAddress({ required String? paymentCodeString, required int? index, }) => @@ -1819,11 +1878,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { #index: index, }, ), - returnValue: _i24.Future<_i31.Uint8List>.value(_i31.Uint8List(0)), - ) as _i24.Future<_i31.Uint8List>); + returnValue: _i26.Future<_i33.Uint8List>.value(_i33.Uint8List(0)), + ) as _i26.Future<_i33.Uint8List>); @override - _i24.Future<_i18.Address> currentReceivingPaynymAddress({ - required _i19.PaymentCode? sender, + _i26.Future<_i19.Address> currentReceivingPaynymAddress({ + required _i20.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1835,7 +1894,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i24.Future<_i18.Address>.value(_FakeAddress_16( + returnValue: _i26.Future<_i19.Address>.value(_FakeAddress_17( this, Invocation.method( #currentReceivingPaynymAddress, @@ -1846,10 +1905,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { }, ), )), - ) as _i24.Future<_i18.Address>); + ) as _i26.Future<_i19.Address>); @override - _i24.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ - required _i19.PaymentCode? sender, + _i26.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ + required _i20.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1861,42 +1920,42 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => + _i26.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkAllCurrentReceivingPaynymAddressesForTransactions, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i17.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( + _i26.Future<_i18.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( Invocation.method( #deriveNotificationBip32Node, [], ), - returnValue: _i24.Future<_i17.BIP32>.value(_FakeBIP32_15( + returnValue: _i26.Future<_i18.BIP32>.value(_FakeBIP32_16( this, Invocation.method( #deriveNotificationBip32Node, [], ), )), - ) as _i24.Future<_i17.BIP32>); + ) as _i26.Future<_i18.BIP32>); @override - _i24.Future<_i19.PaymentCode> getPaymentCode({required bool? isSegwit}) => + _i26.Future<_i20.PaymentCode> getPaymentCode({required bool? isSegwit}) => (super.noSuchMethod( Invocation.method( #getPaymentCode, [], {#isSegwit: isSegwit}, ), - returnValue: _i24.Future<_i19.PaymentCode>.value(_FakePaymentCode_17( + returnValue: _i26.Future<_i20.PaymentCode>.value(_FakePaymentCode_18( this, Invocation.method( #getPaymentCode, @@ -1904,28 +1963,28 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { {#isSegwit: isSegwit}, ), )), - ) as _i24.Future<_i19.PaymentCode>); + ) as _i26.Future<_i20.PaymentCode>); @override - _i24.Future<_i31.Uint8List> signWithNotificationKey(_i31.Uint8List? data) => + _i26.Future<_i33.Uint8List> signWithNotificationKey(_i33.Uint8List? data) => (super.noSuchMethod( Invocation.method( #signWithNotificationKey, [data], ), - returnValue: _i24.Future<_i31.Uint8List>.value(_i31.Uint8List(0)), - ) as _i24.Future<_i31.Uint8List>); + returnValue: _i26.Future<_i33.Uint8List>.value(_i33.Uint8List(0)), + ) as _i26.Future<_i33.Uint8List>); @override - _i24.Future<String> signStringWithNotificationKey(String? data) => + _i26.Future<String> signStringWithNotificationKey(String? data) => (super.noSuchMethod( Invocation.method( #signStringWithNotificationKey, [data], ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<Map<String, dynamic>> preparePaymentCodeSend({ - required _i19.PaymentCode? paymentCode, + _i26.Future<Map<String, dynamic>> preparePaymentCodeSend({ + required _i20.PaymentCode? paymentCode, required bool? isSegwit, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -1942,13 +2001,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<_i18.Address> nextUnusedSendAddressFrom({ - required _i19.PaymentCode? pCode, + _i26.Future<_i19.Address> nextUnusedSendAddressFrom({ + required _i20.PaymentCode? pCode, required bool? isSegwit, - required _i17.BIP32? privateKeyNode, + required _i18.BIP32? privateKeyNode, int? startIndex = 0, }) => (super.noSuchMethod( @@ -1962,7 +2021,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { #startIndex: startIndex, }, ), - returnValue: _i24.Future<_i18.Address>.value(_FakeAddress_16( + returnValue: _i26.Future<_i19.Address>.value(_FakeAddress_17( this, Invocation.method( #nextUnusedSendAddressFrom, @@ -1975,13 +2034,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { }, ), )), - ) as _i24.Future<_i18.Address>); + ) as _i26.Future<_i19.Address>); @override - _i24.Future<Map<String, dynamic>> prepareNotificationTx({ + _i26.Future<Map<String, dynamic>> prepareNotificationTx({ required int? selectedTxFeeRate, required String? targetPaymentCodeString, int? additionalOutputs = 0, - List<_i18.UTXO>? utxos, + List<_i19.UTXO>? utxos, }) => (super.noSuchMethod( Invocation.method( @@ -1995,10 +2054,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<String> broadcastNotificationTx( + _i26.Future<String> broadcastNotificationTx( {required Map<String, dynamic>? preparedTx}) => (super.noSuchMethod( Invocation.method( @@ -2006,62 +2065,62 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { [], {#preparedTx: preparedTx}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<bool> hasConnected(String? paymentCodeString) => + _i26.Future<bool> hasConnected(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #hasConnected, [paymentCodeString], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransaction( - {required _i18.Transaction? transaction}) => + _i26.Future<_i20.PaymentCode?> unBlindedPaymentCodeFromTransaction( + {required _i19.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransaction, [], {#transaction: transaction}, ), - returnValue: _i24.Future<_i19.PaymentCode?>.value(), - ) as _i24.Future<_i19.PaymentCode?>); + returnValue: _i26.Future<_i20.PaymentCode?>.value(), + ) as _i26.Future<_i20.PaymentCode?>); @override - _i24.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( - {required _i18.Transaction? transaction}) => + _i26.Future<_i20.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( + {required _i19.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransactionBad, [], {#transaction: transaction}, ), - returnValue: _i24.Future<_i19.PaymentCode?>.value(), - ) as _i24.Future<_i19.PaymentCode?>); + returnValue: _i26.Future<_i20.PaymentCode?>.value(), + ) as _i26.Future<_i20.PaymentCode?>); @override - _i24.Future<List<_i19.PaymentCode>> + _i26.Future<List<_i20.PaymentCode>> getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod( Invocation.method( #getAllPaymentCodesFromNotificationTransactions, [], ), returnValue: - _i24.Future<List<_i19.PaymentCode>>.value(<_i19.PaymentCode>[]), - ) as _i24.Future<List<_i19.PaymentCode>>); + _i26.Future<List<_i20.PaymentCode>>.value(<_i20.PaymentCode>[]), + ) as _i26.Future<List<_i20.PaymentCode>>); @override - _i24.Future<void> checkForNotificationTransactionsTo( + _i26.Future<void> checkForNotificationTransactionsTo( Set<String>? otherCodeStrings) => (super.noSuchMethod( Invocation.method( #checkForNotificationTransactionsTo, [otherCodeStrings], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> restoreAllHistory({ + _i26.Future<void> restoreAllHistory({ required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, required Set<String>? paymentCodeStrings, @@ -2076,12 +2135,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { #paymentCodeStrings: paymentCodeStrings, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> restoreHistoryWith({ - required _i19.PaymentCode? other, + _i26.Future<void> restoreHistoryWith({ + required _i20.PaymentCode? other, required bool? checkSegwitAsWell, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2097,58 +2156,58 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { #maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i18.Address> getMyNotificationAddress() => (super.noSuchMethod( + _i26.Future<_i19.Address> getMyNotificationAddress() => (super.noSuchMethod( Invocation.method( #getMyNotificationAddress, [], ), - returnValue: _i24.Future<_i18.Address>.value(_FakeAddress_16( + returnValue: _i26.Future<_i19.Address>.value(_FakeAddress_17( this, Invocation.method( #getMyNotificationAddress, [], ), )), - ) as _i24.Future<_i18.Address>); + ) as _i26.Future<_i19.Address>); @override - _i24.Future<List<String>> lookupKey(String? paymentCodeString) => + _i26.Future<List<String>> lookupKey(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #lookupKey, [paymentCodeString], ), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i26.Future<List<String>>.value(<String>[]), + ) as _i26.Future<List<String>>); @override - _i24.Future<String?> paymentCodeStringByKey(String? key) => + _i26.Future<String?> paymentCodeStringByKey(String? key) => (super.noSuchMethod( Invocation.method( #paymentCodeStringByKey, [key], ), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<String> storeCode(String? paymentCodeString) => + _i26.Future<String> storeCode(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #storeCode, [paymentCodeString], ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override void initCoinControlInterface({ required String? walletId, required String? walletName, - required _i23.Coin? coin, + required _i25.Coin? coin, required _i13.MainDB? db, - required _i24.Future<int> Function()? getChainHeight, - required _i24.Future<void> Function(_i12.Balance)? refreshedBalanceCallback, + required _i26.Future<int> Function()? getChainHeight, + required _i26.Future<void> Function(_i12.Balance)? refreshedBalanceCallback, }) => super.noSuchMethod( Invocation.method( @@ -2166,22 +2225,22 @@ class MockBitcoinWallet extends _i1.Mock implements _i28.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<void> refreshBalance({bool? notify = false}) => + _i26.Future<void> refreshBalance({bool? notify = false}) => (super.noSuchMethod( Invocation.method( #refreshBalance, [], {#notify: notify}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); } /// A class which mocks [LocaleService]. /// /// See the documentation for Mockito's code generation for more information. -class MockLocaleService extends _i1.Mock implements _i32.LocaleService { +class MockLocaleService extends _i1.Mock implements _i34.LocaleService { MockLocaleService() { _i1.throwOnMissingStub(this); } @@ -2197,17 +2256,17 @@ class MockLocaleService extends _i1.Mock implements _i32.LocaleService { returnValue: false, ) as bool); @override - _i24.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( + _i26.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( #loadLocale, [], {#notify: notify}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2215,7 +2274,7 @@ class MockLocaleService extends _i1.Mock implements _i32.LocaleService { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2243,21 +2302,21 @@ class MockLocaleService extends _i1.Mock implements _i32.LocaleService { /// A class which mocks [ThemeService]. /// /// See the documentation for Mockito's code generation for more information. -class MockThemeService extends _i1.Mock implements _i33.ThemeService { +class MockThemeService extends _i1.Mock implements _i35.ThemeService { MockThemeService() { _i1.throwOnMissingStub(this); } @override - _i20.HTTP get client => (super.noSuchMethod( + _i21.HTTP get client => (super.noSuchMethod( Invocation.getter(#client), - returnValue: _FakeHTTP_18( + returnValue: _FakeHTTP_19( this, Invocation.getter(#client), ), - ) as _i20.HTTP); + ) as _i21.HTTP); @override - set client(_i20.HTTP? _client) => super.noSuchMethod( + set client(_i21.HTTP? _client) => super.noSuchMethod( Invocation.setter( #client, _client, @@ -2273,10 +2332,10 @@ class MockThemeService extends _i1.Mock implements _i33.ThemeService { ), ) as _i13.MainDB); @override - List<_i34.StackTheme> get installedThemes => (super.noSuchMethod( + List<_i36.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), - returnValue: <_i34.StackTheme>[], - ) as List<_i34.StackTheme>); + returnValue: <_i36.StackTheme>[], + ) as List<_i36.StackTheme>); @override void init(_i13.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -2286,79 +2345,79 @@ class MockThemeService extends _i1.Mock implements _i33.ThemeService { returnValueForMissingStub: null, ); @override - _i24.Future<void> install({required _i31.Uint8List? themeArchiveData}) => + _i26.Future<void> install({required _i33.Uint8List? themeArchiveData}) => (super.noSuchMethod( Invocation.method( #install, [], {#themeArchiveData: themeArchiveData}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> remove({required String? themeId}) => (super.noSuchMethod( + _i26.Future<void> remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( #remove, [], {#themeId: themeId}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( + _i26.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( #checkDefaultThemesOnStartup, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<bool> verifyInstalled({required String? themeId}) => + _i26.Future<bool> verifyInstalled({required String? themeId}) => (super.noSuchMethod( Invocation.method( #verifyInstalled, [], {#themeId: themeId}, ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<List<_i33.StackThemeMetaData>> fetchThemes() => + _i26.Future<List<_i35.StackThemeMetaData>> fetchThemes() => (super.noSuchMethod( Invocation.method( #fetchThemes, [], ), - returnValue: _i24.Future<List<_i33.StackThemeMetaData>>.value( - <_i33.StackThemeMetaData>[]), - ) as _i24.Future<List<_i33.StackThemeMetaData>>); + returnValue: _i26.Future<List<_i35.StackThemeMetaData>>.value( + <_i35.StackThemeMetaData>[]), + ) as _i26.Future<List<_i35.StackThemeMetaData>>); @override - _i24.Future<_i31.Uint8List> fetchTheme( - {required _i33.StackThemeMetaData? themeMetaData}) => + _i26.Future<_i33.Uint8List> fetchTheme( + {required _i35.StackThemeMetaData? themeMetaData}) => (super.noSuchMethod( Invocation.method( #fetchTheme, [], {#themeMetaData: themeMetaData}, ), - returnValue: _i24.Future<_i31.Uint8List>.value(_i31.Uint8List(0)), - ) as _i24.Future<_i31.Uint8List>); + returnValue: _i26.Future<_i33.Uint8List>.value(_i33.Uint8List(0)), + ) as _i26.Future<_i33.Uint8List>); @override - _i34.StackTheme? getTheme({required String? themeId}) => + _i36.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( #getTheme, [], {#themeId: themeId}, - )) as _i34.StackTheme?); + )) as _i36.StackTheme?); } /// A class which mocks [Prefs]. /// /// See the documentation for Mockito's code generation for more information. -class MockPrefs extends _i1.Mock implements _i25.Prefs { +class MockPrefs extends _i1.Mock implements _i27.Prefs { MockPrefs() { _i1.throwOnMissingStub(this); } @@ -2414,12 +2473,12 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override - _i35.SyncingType get syncType => (super.noSuchMethod( + _i37.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), - returnValue: _i35.SyncingType.currentWalletOnly, - ) as _i35.SyncingType); + returnValue: _i37.SyncingType.currentWalletOnly, + ) as _i37.SyncingType); @override - set syncType(_i35.SyncingType? syncType) => super.noSuchMethod( + set syncType(_i37.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( #syncType, syncType, @@ -2578,12 +2637,12 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override - _i36.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( + _i38.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), - returnValue: _i36.BackupFrequencyType.everyTenMinutes, - ) as _i36.BackupFrequencyType); + returnValue: _i38.BackupFrequencyType.everyTenMinutes, + ) as _i38.BackupFrequencyType); @override - set backupFrequencyType(_i36.BackupFrequencyType? backupFrequencyType) => + set backupFrequencyType(_i38.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( Invocation.setter( #backupFrequencyType, @@ -2729,66 +2788,82 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override + _i22.FusionInfo get fusionServerInfo => (super.noSuchMethod( + Invocation.getter(#fusionServerInfo), + returnValue: _FakeFusionInfo_20( + this, + Invocation.getter(#fusionServerInfo), + ), + ) as _i22.FusionInfo); + @override + set fusionServerInfo(_i22.FusionInfo? fusionServerInfo) => super.noSuchMethod( + Invocation.setter( + #fusionServerInfo, + fusionServerInfo, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i24.Future<void> init() => (super.noSuchMethod( + _i26.Future<void> init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( + _i26.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( #incrementCurrentNotificationIndex, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<bool> isExternalCallsSet() => (super.noSuchMethod( + _i26.Future<bool> isExternalCallsSet() => (super.noSuchMethod( Invocation.method( #isExternalCallsSet, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> saveUserID(String? userId) => (super.noSuchMethod( + _i26.Future<void> saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( #saveUserID, [userId], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( + _i26.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( #saveSignupEpoch, [signupEpoch], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i37.AmountUnit amountUnit(_i23.Coin? coin) => (super.noSuchMethod( + _i39.AmountUnit amountUnit(_i25.Coin? coin) => (super.noSuchMethod( Invocation.method( #amountUnit, [coin], ), - returnValue: _i37.AmountUnit.normal, - ) as _i37.AmountUnit); + returnValue: _i39.AmountUnit.normal, + ) as _i39.AmountUnit); @override void updateAmountUnit({ - required _i23.Coin? coin, - required _i37.AmountUnit? amountUnit, + required _i25.Coin? coin, + required _i39.AmountUnit? amountUnit, }) => super.noSuchMethod( Invocation.method( @@ -2802,7 +2877,7 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override - int maxDecimals(_i23.Coin? coin) => (super.noSuchMethod( + int maxDecimals(_i25.Coin? coin) => (super.noSuchMethod( Invocation.method( #maxDecimals, [coin], @@ -2811,7 +2886,7 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { ) as int); @override void updateMaxDecimals({ - required _i23.Coin? coin, + required _i25.Coin? coin, required int? maxDecimals, }) => super.noSuchMethod( @@ -2826,7 +2901,7 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2834,7 +2909,7 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2877,23 +2952,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i21.CoinServiceAPI get wallet => (super.noSuchMethod( + _i23.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_19( + returnValue: _FakeCoinServiceAPI_21( this, Invocation.getter(#wallet), ), - ) as _i21.CoinServiceAPI); + ) as _i23.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i23.Coin get coin => (super.noSuchMethod( + _i25.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i23.Coin.bitcoin, - ) as _i23.Coin); + returnValue: _i25.Coin.bitcoin, + ) as _i25.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2926,23 +3001,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i24.Future<_i9.FeeObject> get fees => (super.noSuchMethod( + _i26.Future<_i9.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i24.Future<_i9.FeeObject>.value(_FakeFeeObject_6( + returnValue: _i26.Future<_i9.FeeObject>.value(_FakeFeeObject_6( this, Invocation.getter(#fees), )), - ) as _i24.Future<_i9.FeeObject>); + ) as _i26.Future<_i9.FeeObject>); @override - _i24.Future<int> get maxFee => (super.noSuchMethod( + _i26.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override - _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i26.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override _i12.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2952,16 +3027,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i12.Balance); @override - _i24.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( + _i26.Future<List<_i19.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i24.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), - ) as _i24.Future<List<_i18.Transaction>>); + _i26.Future<List<_i19.Transaction>>.value(<_i19.Transaction>[]), + ) as _i26.Future<List<_i19.Transaction>>); @override - _i24.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( + _i26.Future<List<_i19.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i24.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), - ) as _i24.Future<List<_i18.UTXO>>); + returnValue: _i26.Future<List<_i19.UTXO>>.value(<_i19.UTXO>[]), + ) as _i26.Future<List<_i19.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2981,15 +3056,15 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i26.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i26.Future<List<String>>.value(<String>[]), + ) as _i26.Future<List<String>>); @override - _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i26.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -3026,6 +3101,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, @@ -3036,24 +3116,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i24.Future<String> get xpub => (super.noSuchMethod( + _i26.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i26.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -3063,7 +3143,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i24.Future<Map<String, dynamic>> prepareSend({ + _i26.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -3079,27 +3159,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i26.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<void> refresh() => (super.noSuchMethod( + _i26.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -3109,35 +3189,35 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i26.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> initializeNew( + _i26.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> initializeExisting() => (super.noSuchMethod( + _i26.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> recoverFromMnemonic({ + _i26.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -3156,20 +3236,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i26.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> fullRescan( + _i26.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -3181,11 +3261,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i15.Amount> estimateFeeFor( + _i26.Future<_i15.Amount> estimateFeeFor( _i15.Amount? amount, int? feeRate, ) => @@ -3197,7 +3277,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i26.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #estimateFeeFor, @@ -3207,26 +3287,26 @@ class MockManager extends _i1.Mock implements _i6.Manager { ], ), )), - ) as _i24.Future<_i15.Amount>); + ) as _i26.Future<_i15.Amount>); @override - _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i26.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> resetRescanOnOpen() => (super.noSuchMethod( + _i26.Future<void> resetRescanOnOpen() => (super.noSuchMethod( Invocation.method( #resetRescanOnOpen, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -3234,7 +3314,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -3254,7 +3334,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i23.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -3265,10 +3345,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i23.Coin get coin => (super.noSuchMethod( + _i25.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i23.Coin.bitcoin, - ) as _i23.Coin); + returnValue: _i25.Coin.bitcoin, + ) as _i25.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -3301,23 +3381,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i24.Future<_i9.FeeObject> get fees => (super.noSuchMethod( + _i26.Future<_i9.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i24.Future<_i9.FeeObject>.value(_FakeFeeObject_6( + returnValue: _i26.Future<_i9.FeeObject>.value(_FakeFeeObject_6( this, Invocation.getter(#fees), )), - ) as _i24.Future<_i9.FeeObject>); + ) as _i26.Future<_i9.FeeObject>); @override - _i24.Future<int> get maxFee => (super.noSuchMethod( + _i26.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override - _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i26.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override _i12.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -3327,16 +3407,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { ), ) as _i12.Balance); @override - _i24.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( + _i26.Future<List<_i19.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i24.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), - ) as _i24.Future<List<_i18.Transaction>>); + _i26.Future<List<_i19.Transaction>>.value(<_i19.Transaction>[]), + ) as _i26.Future<List<_i19.Transaction>>); @override - _i24.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( + _i26.Future<List<_i19.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i24.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), - ) as _i24.Future<List<_i18.UTXO>>); + returnValue: _i26.Future<List<_i19.UTXO>>.value(<_i19.UTXO>[]), + ) as _i26.Future<List<_i19.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -3356,20 +3436,20 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValue: '', ) as String); @override - _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i26.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i26.Future<List<String>>.value(<String>[]), + ) as _i26.Future<List<String>>); @override - _i24.Future<String?> get mnemonicString => (super.noSuchMethod( + _i26.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i26.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -3386,7 +3466,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValue: 0, ) as int); @override - _i24.Future<Map<String, dynamic>> prepareSend({ + _i26.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -3402,36 +3482,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i26.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<void> refresh() => (super.noSuchMethod( + _i26.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i26.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -3441,15 +3521,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValue: false, ) as bool); @override - _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i26.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> recoverFromMnemonic({ + _i26.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -3468,40 +3548,40 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { #height: height, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> initializeNew( + _i26.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> initializeExisting() => (super.noSuchMethod( + _i26.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> exit() => (super.noSuchMethod( + _i26.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> fullRescan( + _i26.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -3513,11 +3593,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i15.Amount> estimateFeeFor( + _i26.Future<_i15.Amount> estimateFeeFor( _i15.Amount? amount, int? feeRate, ) => @@ -3529,7 +3609,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { feeRate, ], ), - returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i26.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #estimateFeeFor, @@ -3539,23 +3619,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { ], ), )), - ) as _i24.Future<_i15.Amount>); + ) as _i26.Future<_i15.Amount>); @override - _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i26.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i26.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); } diff --git a/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart index 29318d2c5..12b403ecc 100644 --- a/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/add_address_book_view_screen_test.mocks.dart @@ -401,6 +401,11 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart index cd9108d2a..6139b42aa 100644 --- a/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/address_book_entry_details_view_screen_test.mocks.dart @@ -362,6 +362,11 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart b/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart index 65ab3b1f2..24bc3f793 100644 --- a/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart +++ b/test/screen_tests/address_book_view/subviews/edit_address_book_entry_view_screen_test.mocks.dart @@ -360,6 +360,11 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/exchange/exchange_view_test.mocks.dart b/test/screen_tests/exchange/exchange_view_test.mocks.dart index 5e23da459..ceec69497 100644 --- a/test/screen_tests/exchange/exchange_view_test.mocks.dart +++ b/test/screen_tests/exchange/exchange_view_test.mocks.dart @@ -3,38 +3,40 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i7; -import 'dart:ui' as _i10; +import 'dart:async' as _i8; +import 'dart:ui' as _i11; -import 'package:decimal/decimal.dart' as _i16; +import 'package:decimal/decimal.dart' as _i17; import 'package:mockito/mockito.dart' as _i1; import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart' - as _i19; -import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart' - as _i21; -import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart' - as _i22; -import 'package:stackwallet/models/exchange/response_objects/estimate.dart' - as _i18; -import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart' as _i20; +import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart' + as _i22; +import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart' + as _i23; +import 'package:stackwallet/models/exchange/response_objects/estimate.dart' + as _i19; +import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart' + as _i21; import 'package:stackwallet/models/exchange/response_objects/range.dart' - as _i17; + as _i18; import 'package:stackwallet/models/exchange/response_objects/trade.dart' - as _i12; -import 'package:stackwallet/models/isar/exchange_cache/currency.dart' as _i15; -import 'package:stackwallet/models/isar/exchange_cache/pair.dart' as _i23; -import 'package:stackwallet/networking/http.dart' as _i2; + as _i13; +import 'package:stackwallet/models/isar/exchange_cache/currency.dart' as _i16; +import 'package:stackwallet/models/isar/exchange_cache/pair.dart' as _i24; +import 'package:stackwallet/networking/http.dart' as _i3; import 'package:stackwallet/services/exchange/change_now/change_now_api.dart' - as _i14; -import 'package:stackwallet/services/exchange/exchange_response.dart' as _i3; -import 'package:stackwallet/services/trade_notes_service.dart' as _i13; -import 'package:stackwallet/services/trade_service.dart' as _i11; -import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i8; -import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i6; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i9; -import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i5; -import 'package:stackwallet/utilities/prefs.dart' as _i4; + as _i15; +import 'package:stackwallet/services/exchange/exchange_response.dart' as _i4; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart' + as _i2; +import 'package:stackwallet/services/trade_notes_service.dart' as _i14; +import 'package:stackwallet/services/trade_service.dart' as _i12; +import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i9; +import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i7; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i10; +import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i6; +import 'package:stackwallet/utilities/prefs.dart' as _i5; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -47,8 +49,8 @@ import 'package:stackwallet/utilities/prefs.dart' as _i4; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeHTTP_0 extends _i1.SmartFake implements _i2.HTTP { - _FakeHTTP_0( +class _FakeFusionInfo_0 extends _i1.SmartFake implements _i2.FusionInfo { + _FakeFusionInfo_0( Object parent, Invocation parentInvocation, ) : super( @@ -57,9 +59,19 @@ class _FakeHTTP_0 extends _i1.SmartFake implements _i2.HTTP { ); } -class _FakeExchangeResponse_1<T> extends _i1.SmartFake - implements _i3.ExchangeResponse<T> { - _FakeExchangeResponse_1( +class _FakeHTTP_1 extends _i1.SmartFake implements _i3.HTTP { + _FakeHTTP_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeExchangeResponse_2<T> extends _i1.SmartFake + implements _i4.ExchangeResponse<T> { + _FakeExchangeResponse_2( Object parent, Invocation parentInvocation, ) : super( @@ -71,7 +83,7 @@ class _FakeExchangeResponse_1<T> extends _i1.SmartFake /// A class which mocks [Prefs]. /// /// See the documentation for Mockito's code generation for more information. -class MockPrefs extends _i1.Mock implements _i4.Prefs { +class MockPrefs extends _i1.Mock implements _i5.Prefs { MockPrefs() { _i1.throwOnMissingStub(this); } @@ -127,12 +139,12 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs { returnValueForMissingStub: null, ); @override - _i5.SyncingType get syncType => (super.noSuchMethod( + _i6.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), - returnValue: _i5.SyncingType.currentWalletOnly, - ) as _i5.SyncingType); + returnValue: _i6.SyncingType.currentWalletOnly, + ) as _i6.SyncingType); @override - set syncType(_i5.SyncingType? syncType) => super.noSuchMethod( + set syncType(_i6.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( #syncType, syncType, @@ -291,12 +303,12 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs { returnValueForMissingStub: null, ); @override - _i6.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( + _i7.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), - returnValue: _i6.BackupFrequencyType.everyTenMinutes, - ) as _i6.BackupFrequencyType); + returnValue: _i7.BackupFrequencyType.everyTenMinutes, + ) as _i7.BackupFrequencyType); @override - set backupFrequencyType(_i6.BackupFrequencyType? backupFrequencyType) => + set backupFrequencyType(_i7.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( Invocation.setter( #backupFrequencyType, @@ -442,66 +454,82 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs { returnValueForMissingStub: null, ); @override + _i2.FusionInfo get fusionServerInfo => (super.noSuchMethod( + Invocation.getter(#fusionServerInfo), + returnValue: _FakeFusionInfo_0( + this, + Invocation.getter(#fusionServerInfo), + ), + ) as _i2.FusionInfo); + @override + set fusionServerInfo(_i2.FusionInfo? fusionServerInfo) => super.noSuchMethod( + Invocation.setter( + #fusionServerInfo, + fusionServerInfo, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i7.Future<void> init() => (super.noSuchMethod( + _i8.Future<void> init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i7.Future<void>.value(), - returnValueForMissingStub: _i7.Future<void>.value(), - ) as _i7.Future<void>); + returnValue: _i8.Future<void>.value(), + returnValueForMissingStub: _i8.Future<void>.value(), + ) as _i8.Future<void>); @override - _i7.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( + _i8.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( #incrementCurrentNotificationIndex, [], ), - returnValue: _i7.Future<void>.value(), - returnValueForMissingStub: _i7.Future<void>.value(), - ) as _i7.Future<void>); + returnValue: _i8.Future<void>.value(), + returnValueForMissingStub: _i8.Future<void>.value(), + ) as _i8.Future<void>); @override - _i7.Future<bool> isExternalCallsSet() => (super.noSuchMethod( + _i8.Future<bool> isExternalCallsSet() => (super.noSuchMethod( Invocation.method( #isExternalCallsSet, [], ), - returnValue: _i7.Future<bool>.value(false), - ) as _i7.Future<bool>); + returnValue: _i8.Future<bool>.value(false), + ) as _i8.Future<bool>); @override - _i7.Future<void> saveUserID(String? userId) => (super.noSuchMethod( + _i8.Future<void> saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( #saveUserID, [userId], ), - returnValue: _i7.Future<void>.value(), - returnValueForMissingStub: _i7.Future<void>.value(), - ) as _i7.Future<void>); + returnValue: _i8.Future<void>.value(), + returnValueForMissingStub: _i8.Future<void>.value(), + ) as _i8.Future<void>); @override - _i7.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( + _i8.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( #saveSignupEpoch, [signupEpoch], ), - returnValue: _i7.Future<void>.value(), - returnValueForMissingStub: _i7.Future<void>.value(), - ) as _i7.Future<void>); + returnValue: _i8.Future<void>.value(), + returnValueForMissingStub: _i8.Future<void>.value(), + ) as _i8.Future<void>); @override - _i8.AmountUnit amountUnit(_i9.Coin? coin) => (super.noSuchMethod( + _i9.AmountUnit amountUnit(_i10.Coin? coin) => (super.noSuchMethod( Invocation.method( #amountUnit, [coin], ), - returnValue: _i8.AmountUnit.normal, - ) as _i8.AmountUnit); + returnValue: _i9.AmountUnit.normal, + ) as _i9.AmountUnit); @override void updateAmountUnit({ - required _i9.Coin? coin, - required _i8.AmountUnit? amountUnit, + required _i10.Coin? coin, + required _i9.AmountUnit? amountUnit, }) => super.noSuchMethod( Invocation.method( @@ -515,7 +543,7 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs { returnValueForMissingStub: null, ); @override - int maxDecimals(_i9.Coin? coin) => (super.noSuchMethod( + int maxDecimals(_i10.Coin? coin) => (super.noSuchMethod( Invocation.method( #maxDecimals, [coin], @@ -524,7 +552,7 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs { ) as int); @override void updateMaxDecimals({ - required _i9.Coin? coin, + required _i10.Coin? coin, required int? maxDecimals, }) => super.noSuchMethod( @@ -539,7 +567,7 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs { returnValueForMissingStub: null, ); @override - void addListener(_i10.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i11.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -547,7 +575,7 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs { returnValueForMissingStub: null, ); @override - void removeListener(_i10.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i11.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -575,29 +603,29 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs { /// A class which mocks [TradesService]. /// /// See the documentation for Mockito's code generation for more information. -class MockTradesService extends _i1.Mock implements _i11.TradesService { +class MockTradesService extends _i1.Mock implements _i12.TradesService { MockTradesService() { _i1.throwOnMissingStub(this); } @override - List<_i12.Trade> get trades => (super.noSuchMethod( + List<_i13.Trade> get trades => (super.noSuchMethod( Invocation.getter(#trades), - returnValue: <_i12.Trade>[], - ) as List<_i12.Trade>); + returnValue: <_i13.Trade>[], + ) as List<_i13.Trade>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i12.Trade? get(String? tradeId) => (super.noSuchMethod(Invocation.method( + _i13.Trade? get(String? tradeId) => (super.noSuchMethod(Invocation.method( #get, [tradeId], - )) as _i12.Trade?); + )) as _i13.Trade?); @override - _i7.Future<void> add({ - required _i12.Trade? trade, + _i8.Future<void> add({ + required _i13.Trade? trade, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -609,12 +637,12 @@ class MockTradesService extends _i1.Mock implements _i11.TradesService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i7.Future<void>.value(), - returnValueForMissingStub: _i7.Future<void>.value(), - ) as _i7.Future<void>); + returnValue: _i8.Future<void>.value(), + returnValueForMissingStub: _i8.Future<void>.value(), + ) as _i8.Future<void>); @override - _i7.Future<void> edit({ - required _i12.Trade? trade, + _i8.Future<void> edit({ + required _i13.Trade? trade, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -626,12 +654,12 @@ class MockTradesService extends _i1.Mock implements _i11.TradesService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i7.Future<void>.value(), - returnValueForMissingStub: _i7.Future<void>.value(), - ) as _i7.Future<void>); + returnValue: _i8.Future<void>.value(), + returnValueForMissingStub: _i8.Future<void>.value(), + ) as _i8.Future<void>); @override - _i7.Future<void> delete({ - required _i12.Trade? trade, + _i8.Future<void> delete({ + required _i13.Trade? trade, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -643,11 +671,11 @@ class MockTradesService extends _i1.Mock implements _i11.TradesService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i7.Future<void>.value(), - returnValueForMissingStub: _i7.Future<void>.value(), - ) as _i7.Future<void>); + returnValue: _i8.Future<void>.value(), + returnValueForMissingStub: _i8.Future<void>.value(), + ) as _i8.Future<void>); @override - _i7.Future<void> deleteByUuid({ + _i8.Future<void> deleteByUuid({ required String? uuid, required bool? shouldNotifyListeners, }) => @@ -660,11 +688,11 @@ class MockTradesService extends _i1.Mock implements _i11.TradesService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i7.Future<void>.value(), - returnValueForMissingStub: _i7.Future<void>.value(), - ) as _i7.Future<void>); + returnValue: _i8.Future<void>.value(), + returnValueForMissingStub: _i8.Future<void>.value(), + ) as _i8.Future<void>); @override - void addListener(_i10.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i11.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -672,7 +700,7 @@ class MockTradesService extends _i1.Mock implements _i11.TradesService { returnValueForMissingStub: null, ); @override - void removeListener(_i10.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i11.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -700,7 +728,7 @@ class MockTradesService extends _i1.Mock implements _i11.TradesService { /// A class which mocks [TradeNotesService]. /// /// See the documentation for Mockito's code generation for more information. -class MockTradeNotesService extends _i1.Mock implements _i13.TradeNotesService { +class MockTradeNotesService extends _i1.Mock implements _i14.TradeNotesService { MockTradeNotesService() { _i1.throwOnMissingStub(this); } @@ -725,7 +753,7 @@ class MockTradeNotesService extends _i1.Mock implements _i13.TradeNotesService { returnValue: '', ) as String); @override - _i7.Future<void> set({ + _i8.Future<void> set({ required String? tradeId, required String? note, }) => @@ -738,21 +766,21 @@ class MockTradeNotesService extends _i1.Mock implements _i13.TradeNotesService { #note: note, }, ), - returnValue: _i7.Future<void>.value(), - returnValueForMissingStub: _i7.Future<void>.value(), - ) as _i7.Future<void>); + returnValue: _i8.Future<void>.value(), + returnValueForMissingStub: _i8.Future<void>.value(), + ) as _i8.Future<void>); @override - _i7.Future<void> delete({required String? tradeId}) => (super.noSuchMethod( + _i8.Future<void> delete({required String? tradeId}) => (super.noSuchMethod( Invocation.method( #delete, [], {#tradeId: tradeId}, ), - returnValue: _i7.Future<void>.value(), - returnValueForMissingStub: _i7.Future<void>.value(), - ) as _i7.Future<void>); + returnValue: _i8.Future<void>.value(), + returnValueForMissingStub: _i8.Future<void>.value(), + ) as _i8.Future<void>); @override - void addListener(_i10.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i11.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -760,7 +788,7 @@ class MockTradeNotesService extends _i1.Mock implements _i13.TradeNotesService { returnValueForMissingStub: null, ); @override - void removeListener(_i10.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i11.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -788,21 +816,21 @@ class MockTradeNotesService extends _i1.Mock implements _i13.TradeNotesService { /// A class which mocks [ChangeNowAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { +class MockChangeNowAPI extends _i1.Mock implements _i15.ChangeNowAPI { MockChangeNowAPI() { _i1.throwOnMissingStub(this); } @override - _i2.HTTP get client => (super.noSuchMethod( + _i3.HTTP get client => (super.noSuchMethod( Invocation.getter(#client), - returnValue: _FakeHTTP_0( + returnValue: _FakeHTTP_1( this, Invocation.getter(#client), ), - ) as _i2.HTTP); + ) as _i3.HTTP); @override - _i7.Future<_i3.ExchangeResponse<List<_i15.Currency>>> getAvailableCurrencies({ + _i8.Future<_i4.ExchangeResponse<List<_i16.Currency>>> getAvailableCurrencies({ bool? fixedRate, bool? active, }) => @@ -816,8 +844,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), returnValue: - _i7.Future<_i3.ExchangeResponse<List<_i15.Currency>>>.value( - _FakeExchangeResponse_1<List<_i15.Currency>>( + _i8.Future<_i4.ExchangeResponse<List<_i16.Currency>>>.value( + _FakeExchangeResponse_2<List<_i16.Currency>>( this, Invocation.method( #getAvailableCurrencies, @@ -828,26 +856,26 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), )), - ) as _i7.Future<_i3.ExchangeResponse<List<_i15.Currency>>>); + ) as _i8.Future<_i4.ExchangeResponse<List<_i16.Currency>>>); @override - _i7.Future<_i3.ExchangeResponse<List<_i15.Currency>>> getCurrenciesV2() => + _i8.Future<_i4.ExchangeResponse<List<_i16.Currency>>> getCurrenciesV2() => (super.noSuchMethod( Invocation.method( #getCurrenciesV2, [], ), returnValue: - _i7.Future<_i3.ExchangeResponse<List<_i15.Currency>>>.value( - _FakeExchangeResponse_1<List<_i15.Currency>>( + _i8.Future<_i4.ExchangeResponse<List<_i16.Currency>>>.value( + _FakeExchangeResponse_2<List<_i16.Currency>>( this, Invocation.method( #getCurrenciesV2, [], ), )), - ) as _i7.Future<_i3.ExchangeResponse<List<_i15.Currency>>>); + ) as _i8.Future<_i4.ExchangeResponse<List<_i16.Currency>>>); @override - _i7.Future<_i3.ExchangeResponse<List<_i15.Currency>>> getPairedCurrencies({ + _i8.Future<_i4.ExchangeResponse<List<_i16.Currency>>> getPairedCurrencies({ required String? ticker, bool? fixedRate, }) => @@ -861,8 +889,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), returnValue: - _i7.Future<_i3.ExchangeResponse<List<_i15.Currency>>>.value( - _FakeExchangeResponse_1<List<_i15.Currency>>( + _i8.Future<_i4.ExchangeResponse<List<_i16.Currency>>>.value( + _FakeExchangeResponse_2<List<_i16.Currency>>( this, Invocation.method( #getPairedCurrencies, @@ -873,9 +901,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), )), - ) as _i7.Future<_i3.ExchangeResponse<List<_i15.Currency>>>); + ) as _i8.Future<_i4.ExchangeResponse<List<_i16.Currency>>>); @override - _i7.Future<_i3.ExchangeResponse<_i16.Decimal>> getMinimalExchangeAmount({ + _i8.Future<_i4.ExchangeResponse<_i17.Decimal>> getMinimalExchangeAmount({ required String? fromTicker, required String? toTicker, String? apiKey, @@ -890,8 +918,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { #apiKey: apiKey, }, ), - returnValue: _i7.Future<_i3.ExchangeResponse<_i16.Decimal>>.value( - _FakeExchangeResponse_1<_i16.Decimal>( + returnValue: _i8.Future<_i4.ExchangeResponse<_i17.Decimal>>.value( + _FakeExchangeResponse_2<_i17.Decimal>( this, Invocation.method( #getMinimalExchangeAmount, @@ -903,9 +931,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), )), - ) as _i7.Future<_i3.ExchangeResponse<_i16.Decimal>>); + ) as _i8.Future<_i4.ExchangeResponse<_i17.Decimal>>); @override - _i7.Future<_i3.ExchangeResponse<_i17.Range>> getRange({ + _i8.Future<_i4.ExchangeResponse<_i18.Range>> getRange({ required String? fromTicker, required String? toTicker, required bool? isFixedRate, @@ -922,8 +950,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { #apiKey: apiKey, }, ), - returnValue: _i7.Future<_i3.ExchangeResponse<_i17.Range>>.value( - _FakeExchangeResponse_1<_i17.Range>( + returnValue: _i8.Future<_i4.ExchangeResponse<_i18.Range>>.value( + _FakeExchangeResponse_2<_i18.Range>( this, Invocation.method( #getRange, @@ -936,12 +964,12 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), )), - ) as _i7.Future<_i3.ExchangeResponse<_i17.Range>>); + ) as _i8.Future<_i4.ExchangeResponse<_i18.Range>>); @override - _i7.Future<_i3.ExchangeResponse<_i18.Estimate>> getEstimatedExchangeAmount({ + _i8.Future<_i4.ExchangeResponse<_i19.Estimate>> getEstimatedExchangeAmount({ required String? fromTicker, required String? toTicker, - required _i16.Decimal? fromAmount, + required _i17.Decimal? fromAmount, String? apiKey, }) => (super.noSuchMethod( @@ -955,8 +983,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { #apiKey: apiKey, }, ), - returnValue: _i7.Future<_i3.ExchangeResponse<_i18.Estimate>>.value( - _FakeExchangeResponse_1<_i18.Estimate>( + returnValue: _i8.Future<_i4.ExchangeResponse<_i19.Estimate>>.value( + _FakeExchangeResponse_2<_i19.Estimate>( this, Invocation.method( #getEstimatedExchangeAmount, @@ -969,13 +997,13 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), )), - ) as _i7.Future<_i3.ExchangeResponse<_i18.Estimate>>); + ) as _i8.Future<_i4.ExchangeResponse<_i19.Estimate>>); @override - _i7.Future<_i3.ExchangeResponse<_i18.Estimate>> + _i8.Future<_i4.ExchangeResponse<_i19.Estimate>> getEstimatedExchangeAmountFixedRate({ required String? fromTicker, required String? toTicker, - required _i16.Decimal? fromAmount, + required _i17.Decimal? fromAmount, required bool? reversed, bool? useRateId = true, String? apiKey, @@ -993,8 +1021,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { #apiKey: apiKey, }, ), - returnValue: _i7.Future<_i3.ExchangeResponse<_i18.Estimate>>.value( - _FakeExchangeResponse_1<_i18.Estimate>( + returnValue: _i8.Future<_i4.ExchangeResponse<_i19.Estimate>>.value( + _FakeExchangeResponse_2<_i19.Estimate>( this, Invocation.method( #getEstimatedExchangeAmountFixedRate, @@ -1009,17 +1037,17 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), )), - ) as _i7.Future<_i3.ExchangeResponse<_i18.Estimate>>); + ) as _i8.Future<_i4.ExchangeResponse<_i19.Estimate>>); @override - _i7.Future<_i3.ExchangeResponse<_i19.CNExchangeEstimate>> + _i8.Future<_i4.ExchangeResponse<_i20.CNExchangeEstimate>> getEstimatedExchangeAmountV2({ required String? fromTicker, required String? toTicker, - required _i19.CNEstimateType? fromOrTo, - required _i16.Decimal? amount, + required _i20.CNEstimateType? fromOrTo, + required _i17.Decimal? amount, String? fromNetwork, String? toNetwork, - _i19.CNFlowType? flow = _i19.CNFlowType.standard, + _i20.CNFlowType? flow = _i20.CNFlowType.standard, String? apiKey, }) => (super.noSuchMethod( @@ -1038,8 +1066,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), returnValue: - _i7.Future<_i3.ExchangeResponse<_i19.CNExchangeEstimate>>.value( - _FakeExchangeResponse_1<_i19.CNExchangeEstimate>( + _i8.Future<_i4.ExchangeResponse<_i20.CNExchangeEstimate>>.value( + _FakeExchangeResponse_2<_i20.CNExchangeEstimate>( this, Invocation.method( #getEstimatedExchangeAmountV2, @@ -1056,18 +1084,18 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), )), - ) as _i7.Future<_i3.ExchangeResponse<_i19.CNExchangeEstimate>>); + ) as _i8.Future<_i4.ExchangeResponse<_i20.CNExchangeEstimate>>); @override - _i7.Future<_i3.ExchangeResponse<List<_i20.FixedRateMarket>>> + _i8.Future<_i4.ExchangeResponse<List<_i21.FixedRateMarket>>> getAvailableFixedRateMarkets({String? apiKey}) => (super.noSuchMethod( Invocation.method( #getAvailableFixedRateMarkets, [], {#apiKey: apiKey}, ), - returnValue: _i7 - .Future<_i3.ExchangeResponse<List<_i20.FixedRateMarket>>>.value( - _FakeExchangeResponse_1<List<_i20.FixedRateMarket>>( + returnValue: _i8 + .Future<_i4.ExchangeResponse<List<_i21.FixedRateMarket>>>.value( + _FakeExchangeResponse_2<List<_i21.FixedRateMarket>>( this, Invocation.method( #getAvailableFixedRateMarkets, @@ -1075,14 +1103,14 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { {#apiKey: apiKey}, ), )), - ) as _i7.Future<_i3.ExchangeResponse<List<_i20.FixedRateMarket>>>); + ) as _i8.Future<_i4.ExchangeResponse<List<_i21.FixedRateMarket>>>); @override - _i7.Future<_i3.ExchangeResponse<_i21.ExchangeTransaction>> + _i8.Future<_i4.ExchangeResponse<_i22.ExchangeTransaction>> createStandardExchangeTransaction({ required String? fromTicker, required String? toTicker, required String? receivingAddress, - required _i16.Decimal? amount, + required _i17.Decimal? amount, String? extraId = r'', String? userId = r'', String? contactEmail = r'', @@ -1107,9 +1135,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { #apiKey: apiKey, }, ), - returnValue: _i7 - .Future<_i3.ExchangeResponse<_i21.ExchangeTransaction>>.value( - _FakeExchangeResponse_1<_i21.ExchangeTransaction>( + returnValue: _i8 + .Future<_i4.ExchangeResponse<_i22.ExchangeTransaction>>.value( + _FakeExchangeResponse_2<_i22.ExchangeTransaction>( this, Invocation.method( #createStandardExchangeTransaction, @@ -1128,14 +1156,14 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), )), - ) as _i7.Future<_i3.ExchangeResponse<_i21.ExchangeTransaction>>); + ) as _i8.Future<_i4.ExchangeResponse<_i22.ExchangeTransaction>>); @override - _i7.Future<_i3.ExchangeResponse<_i21.ExchangeTransaction>> + _i8.Future<_i4.ExchangeResponse<_i22.ExchangeTransaction>> createFixedRateExchangeTransaction({ required String? fromTicker, required String? toTicker, required String? receivingAddress, - required _i16.Decimal? amount, + required _i17.Decimal? amount, required String? rateId, required bool? reversed, String? extraId = r'', @@ -1164,9 +1192,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { #apiKey: apiKey, }, ), - returnValue: _i7 - .Future<_i3.ExchangeResponse<_i21.ExchangeTransaction>>.value( - _FakeExchangeResponse_1<_i21.ExchangeTransaction>( + returnValue: _i8 + .Future<_i4.ExchangeResponse<_i22.ExchangeTransaction>>.value( + _FakeExchangeResponse_2<_i22.ExchangeTransaction>( this, Invocation.method( #createFixedRateExchangeTransaction, @@ -1187,11 +1215,11 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), )), - ) as _i7.Future<_i3.ExchangeResponse<_i21.ExchangeTransaction>>); + ) as _i8.Future<_i4.ExchangeResponse<_i22.ExchangeTransaction>>); @override - _i7.Future< - _i3 - .ExchangeResponse<_i22.ExchangeTransactionStatus>> getTransactionStatus({ + _i8.Future< + _i4 + .ExchangeResponse<_i23.ExchangeTransactionStatus>> getTransactionStatus({ required String? id, String? apiKey, }) => @@ -1204,9 +1232,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { #apiKey: apiKey, }, ), - returnValue: _i7 - .Future<_i3.ExchangeResponse<_i22.ExchangeTransactionStatus>>.value( - _FakeExchangeResponse_1<_i22.ExchangeTransactionStatus>( + returnValue: _i8 + .Future<_i4.ExchangeResponse<_i23.ExchangeTransactionStatus>>.value( + _FakeExchangeResponse_2<_i23.ExchangeTransactionStatus>( this, Invocation.method( #getTransactionStatus, @@ -1217,9 +1245,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { }, ), )), - ) as _i7.Future<_i3.ExchangeResponse<_i22.ExchangeTransactionStatus>>); + ) as _i8.Future<_i4.ExchangeResponse<_i23.ExchangeTransactionStatus>>); @override - _i7.Future<_i3.ExchangeResponse<List<_i23.Pair>>> + _i8.Future<_i4.ExchangeResponse<List<_i24.Pair>>> getAvailableFloatingRatePairs({bool? includePartners = false}) => (super.noSuchMethod( Invocation.method( @@ -1228,8 +1256,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { {#includePartners: includePartners}, ), returnValue: - _i7.Future<_i3.ExchangeResponse<List<_i23.Pair>>>.value( - _FakeExchangeResponse_1<List<_i23.Pair>>( + _i8.Future<_i4.ExchangeResponse<List<_i24.Pair>>>.value( + _FakeExchangeResponse_2<List<_i24.Pair>>( this, Invocation.method( #getAvailableFloatingRatePairs, @@ -1237,5 +1265,5 @@ class MockChangeNowAPI extends _i1.Mock implements _i14.ChangeNowAPI { {#includePartners: includePartners}, ), )), - ) as _i7.Future<_i3.ExchangeResponse<List<_i23.Pair>>>); + ) as _i8.Future<_i4.ExchangeResponse<List<_i24.Pair>>>); } diff --git a/test/screen_tests/lockscreen_view_screen_test.mocks.dart b/test/screen_tests/lockscreen_view_screen_test.mocks.dart index dd8f32b04..2e72a280e 100644 --- a/test/screen_tests/lockscreen_view_screen_test.mocks.dart +++ b/test/screen_tests/lockscreen_view_screen_test.mocks.dart @@ -680,6 +680,11 @@ class MockManager extends _i1.Mock implements _i13.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart index 87686d271..e85c12de3 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testA_test.mocks.dart @@ -467,6 +467,11 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart index 221cbb329..577863c66 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testB_test.mocks.dart @@ -467,6 +467,11 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart b/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart index abb608127..900b926c9 100644 --- a/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart +++ b/test/screen_tests/main_view_tests/main_view_screen_testC_test.mocks.dart @@ -467,6 +467,11 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart b/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart index b60b30832..90c66fe48 100644 --- a/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/backup_key_view_screen_test.mocks.dart @@ -234,6 +234,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart b/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart index 90907cd14..78f26c643 100644 --- a/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/backup_key_warning_view_screen_test.mocks.dart @@ -465,6 +465,11 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart b/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart index 460a35f50..da0bf466e 100644 --- a/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/create_pin_view_screen_test.mocks.dart @@ -680,6 +680,11 @@ class MockManager extends _i1.Mock implements _i13.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart b/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart index b4a8329da..6da3bf138 100644 --- a/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/restore_wallet_view_screen_test.mocks.dart @@ -521,6 +521,11 @@ class MockManager extends _i1.Mock implements _i13.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart b/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart index 25241ab80..30dd39893 100644 --- a/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart +++ b/test/screen_tests/onboarding/verify_backup_key_view_screen_test.mocks.dart @@ -234,6 +234,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart index d77078d9c..34810b643 100644 --- a/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/currency_view_screen_test.mocks.dart @@ -234,6 +234,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart index 0b8976a88..5655d968d 100644 --- a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/add_custom_node_view_screen_test.mocks.dart @@ -449,6 +449,11 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart index 803ef81c6..46fec4f9d 100644 --- a/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/network_settings_subviews/node_details_view_screen_test.mocks.dart @@ -449,6 +449,11 @@ class MockManager extends _i1.Mock implements _i12.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart index 4e59b2a40..2ca2dadc6 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_backup_view_screen_test.mocks.dart @@ -234,6 +234,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart index 151ecd1ab..7a6f10121 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/rescan_warning_view_screen_test.mocks.dart @@ -234,6 +234,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart index d9e9603d3..bfbf51cce 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_subviews/wallet_delete_mnemonic_view_screen_test.mocks.dart @@ -465,6 +465,11 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart index e0fae8b21..cae55e4e5 100644 --- a/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_subviews/wallet_settings_view_screen_test.mocks.dart @@ -701,6 +701,11 @@ class MockManager extends _i1.Mock implements _i15.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart b/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart index 97837b511..fd36e25f6 100644 --- a/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart +++ b/test/screen_tests/settings_view/settings_view_screen_test.mocks.dart @@ -465,6 +465,11 @@ class MockManager extends _i1.Mock implements _i10.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart b/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart index 97563c8ad..b32d80a56 100644 --- a/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart +++ b/test/screen_tests/transaction_subviews/transaction_search_results_view_screen_test.mocks.dart @@ -236,6 +236,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart index bab69e5d2..a30ef5112 100644 --- a/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/confirm_send_view_screen_test.mocks.dart @@ -235,6 +235,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart index 75c6d795e..0bf963ecb 100644 --- a/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/receive_view_screen_test.mocks.dart @@ -234,6 +234,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart index eb261af73..80f4f26f3 100644 --- a/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/send_view_screen_test.mocks.dart @@ -276,6 +276,11 @@ class MockManager extends _i1.Mock implements _i9.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart b/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart index d43cb5430..6ea98befe 100644 --- a/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart +++ b/test/screen_tests/wallet_view/wallet_view_screen_test.mocks.dart @@ -236,6 +236,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, diff --git a/test/services/coins/firo/firo_wallet_test.mocks.dart b/test/services/coins/firo/firo_wallet_test.mocks.dart index 0f7a0b0a3..2487bf007 100644 --- a/test/services/coins/firo/firo_wallet_test.mocks.dart +++ b/test/services/coins/firo/firo_wallet_test.mocks.dart @@ -855,6 +855,33 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB { ), ) as _i4.QueryBuilder<_i12.UTXO, _i12.UTXO, _i4.QAfterWhereClause>); @override + _i4.QueryBuilder<_i12.UTXO, _i12.UTXO, _i4.QAfterFilterCondition> + getUTXOsByAddress( + String? walletId, + String? address, + ) => + (super.noSuchMethod( + Invocation.method( + #getUTXOsByAddress, + [ + walletId, + address, + ], + ), + returnValue: _FakeQueryBuilder_4<_i12.UTXO, _i12.UTXO, + _i4.QAfterFilterCondition>( + this, + Invocation.method( + #getUTXOsByAddress, + [ + walletId, + address, + ], + ), + ), + ) as _i4 + .QueryBuilder<_i12.UTXO, _i12.UTXO, _i4.QAfterFilterCondition>); + @override _i5.Future<void> putUTXO(_i12.UTXO? utxo) => (super.noSuchMethod( Invocation.method( #putUTXO, diff --git a/test/widget_tests/managed_favorite_test.mocks.dart b/test/widget_tests/managed_favorite_test.mocks.dart index e2232e066..03b0f083a 100644 --- a/test/widget_tests/managed_favorite_test.mocks.dart +++ b/test/widget_tests/managed_favorite_test.mocks.dart @@ -3,12 +3,12 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i24; -import 'dart:typed_data' as _i30; -import 'dart:ui' as _i26; +import 'dart:async' as _i26; +import 'dart:typed_data' as _i32; +import 'dart:ui' as _i28; -import 'package:bip32/bip32.dart' as _i16; -import 'package:bip47/bip47.dart' as _i18; +import 'package:bip32/bip32.dart' as _i17; +import 'package:bip47/bip47.dart' as _i19; import 'package:bitcoindart/bitcoindart.dart' as _i13; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -17,32 +17,36 @@ import 'package:stackwallet/db/isar/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i17; -import 'package:stackwallet/models/isar/stack_theme.dart' as _i32; -import 'package:stackwallet/models/node_model.dart' as _i37; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart' + as _i15; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i18; +import 'package:stackwallet/models/isar/stack_theme.dart' as _i34; +import 'package:stackwallet/models/node_model.dart' as _i39; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/models/signing_data.dart' as _i29; -import 'package:stackwallet/networking/http.dart' as _i19; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i27; -import 'package:stackwallet/services/coins/coin_service.dart' as _i21; +import 'package:stackwallet/models/signing_data.dart' as _i31; +import 'package:stackwallet/networking/http.dart' as _i20; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i29; +import 'package:stackwallet/services/coins/coin_service.dart' as _i23; import 'package:stackwallet/services/coins/manager.dart' as _i6; -import 'package:stackwallet/services/locale_service.dart' as _i36; +import 'package:stackwallet/services/locale_service.dart' as _i38; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart' + as _i21; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i22; +import 'package:stackwallet/services/wallets.dart' as _i24; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/themes/theme_service.dart' as _i31; +import 'package:stackwallet/themes/theme_service.dart' as _i33; import 'package:stackwallet/utilities/amount/amount.dart' as _i14; -import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i35; -import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i34; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i23; -import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i28; -import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i33; +import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i37; +import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i36; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i25; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i30; +import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i35; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' - as _i20; -import 'package:stackwallet/utilities/prefs.dart' as _i25; -import 'package:tuple/tuple.dart' as _i15; + as _i22; +import 'package:stackwallet/utilities/prefs.dart' as _i27; +import 'package:tuple/tuple.dart' as _i16; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -189,9 +193,9 @@ class _FakeAmount_12 extends _i1.SmartFake implements _i14.Amount { ); } -class _FakeTuple2_13<T1, T2> extends _i1.SmartFake - implements _i15.Tuple2<T1, T2> { - _FakeTuple2_13( +class _FakeTransactionV2_13 extends _i1.SmartFake + implements _i15.TransactionV2 { + _FakeTransactionV2_13( Object parent, Invocation parentInvocation, ) : super( @@ -200,8 +204,9 @@ class _FakeTuple2_13<T1, T2> extends _i1.SmartFake ); } -class _FakeBIP32_14 extends _i1.SmartFake implements _i16.BIP32 { - _FakeBIP32_14( +class _FakeTuple2_14<T1, T2> extends _i1.SmartFake + implements _i16.Tuple2<T1, T2> { + _FakeTuple2_14( Object parent, Invocation parentInvocation, ) : super( @@ -210,8 +215,8 @@ class _FakeBIP32_14 extends _i1.SmartFake implements _i16.BIP32 { ); } -class _FakeAddress_15 extends _i1.SmartFake implements _i17.Address { - _FakeAddress_15( +class _FakeBIP32_15 extends _i1.SmartFake implements _i17.BIP32 { + _FakeBIP32_15( Object parent, Invocation parentInvocation, ) : super( @@ -220,8 +225,8 @@ class _FakeAddress_15 extends _i1.SmartFake implements _i17.Address { ); } -class _FakePaymentCode_16 extends _i1.SmartFake implements _i18.PaymentCode { - _FakePaymentCode_16( +class _FakeAddress_16 extends _i1.SmartFake implements _i18.Address { + _FakeAddress_16( Object parent, Invocation parentInvocation, ) : super( @@ -230,8 +235,8 @@ class _FakePaymentCode_16 extends _i1.SmartFake implements _i18.PaymentCode { ); } -class _FakeHTTP_17 extends _i1.SmartFake implements _i19.HTTP { - _FakeHTTP_17( +class _FakePaymentCode_17 extends _i1.SmartFake implements _i19.PaymentCode { + _FakePaymentCode_17( Object parent, Invocation parentInvocation, ) : super( @@ -240,9 +245,8 @@ class _FakeHTTP_17 extends _i1.SmartFake implements _i19.HTTP { ); } -class _FakeSecureStorageInterface_18 extends _i1.SmartFake - implements _i20.SecureStorageInterface { - _FakeSecureStorageInterface_18( +class _FakeHTTP_18 extends _i1.SmartFake implements _i20.HTTP { + _FakeHTTP_18( Object parent, Invocation parentInvocation, ) : super( @@ -251,9 +255,30 @@ class _FakeSecureStorageInterface_18 extends _i1.SmartFake ); } -class _FakeCoinServiceAPI_19 extends _i1.SmartFake - implements _i21.CoinServiceAPI { - _FakeCoinServiceAPI_19( +class _FakeFusionInfo_19 extends _i1.SmartFake implements _i21.FusionInfo { + _FakeFusionInfo_19( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeSecureStorageInterface_20 extends _i1.SmartFake + implements _i22.SecureStorageInterface { + _FakeSecureStorageInterface_20( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_21 extends _i1.SmartFake + implements _i23.CoinServiceAPI { + _FakeCoinServiceAPI_21( Object parent, Invocation parentInvocation, ) : super( @@ -265,7 +290,7 @@ class _FakeCoinServiceAPI_19 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i22.Wallets { +class MockWallets extends _i1.Mock implements _i24.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -332,7 +357,7 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i23.Coin? coin}) => + List<String> getWalletIdsFor({required _i25.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -342,20 +367,20 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValue: <String>[], ) as List<String>); @override - List<_i15.Tuple2<_i23.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> + List<_i16.Tuple2<_i25.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i15.Tuple2<_i23.Coin, + returnValue: <_i16.Tuple2<_i25.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>[], ) as List< - _i15.Tuple2<_i23.Coin, + _i16.Tuple2<_i25.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i23.Coin? coin) => + _i25.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -419,17 +444,17 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValueForMissingStub: null, ); @override - _i24.Future<void> load(_i25.Prefs? prefs) => (super.noSuchMethod( + _i26.Future<void> load(_i27.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> loadAfterStackRestore( - _i25.Prefs? prefs, + _i26.Future<void> loadAfterStackRestore( + _i27.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -440,11 +465,11 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { managers, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -452,7 +477,7 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -478,19 +503,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i24.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i26.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i24.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i26.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i24.Future<Map<String, _i2.WalletInfo>>); + ) as _i26.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i24.Future<bool> renameWallet({ + _i26.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -505,8 +530,8 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override Map<String, _i2.WalletInfo> fetchWalletsData() => (super.noSuchMethod( Invocation.method( @@ -516,10 +541,10 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: <String, _i2.WalletInfo>{}, ) as Map<String, _i2.WalletInfo>); @override - _i24.Future<void> addExistingStackWallet({ + _i26.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i23.Coin? coin, + required _i25.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -533,13 +558,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<String?> addNewWallet({ + _i26.Future<String?> addNewWallet({ required String? name, - required _i23.Coin? coin, + required _i25.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -552,46 +577,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i26.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i26.Future<List<String>>.value(<String>[]), + ) as _i26.Future<List<String>>); @override - _i24.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i26.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i26.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i26.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> moveFavorite({ + _i26.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -604,48 +629,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i26.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i26.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<bool> isMnemonicVerified({required String? walletId}) => + _i26.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> setMnemonicVerified({required String? walletId}) => + _i26.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<int> deleteWallet( + _i26.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -657,20 +682,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override - _i24.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i26.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -678,7 +703,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -706,13 +731,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i24.Timer? _timer) => super.noSuchMethod( + set timer(_i26.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -789,74 +814,74 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { returnValue: false, ) as bool); @override - _i23.Coin get coin => (super.noSuchMethod( + _i25.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i23.Coin.bitcoin, - ) as _i23.Coin); + returnValue: _i25.Coin.bitcoin, + ) as _i25.Coin); @override - _i24.Future<List<_i17.UTXO>> get utxos => (super.noSuchMethod( + _i26.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i24.Future<List<_i17.UTXO>>.value(<_i17.UTXO>[]), - ) as _i24.Future<List<_i17.UTXO>>); + returnValue: _i26.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), + ) as _i26.Future<List<_i18.UTXO>>); @override - _i24.Future<List<_i17.Transaction>> get transactions => (super.noSuchMethod( + _i26.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i24.Future<List<_i17.Transaction>>.value(<_i17.Transaction>[]), - ) as _i24.Future<List<_i17.Transaction>>); + _i26.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), + ) as _i26.Future<List<_i18.Transaction>>); @override - _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i26.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i26.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( + _i26.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( Invocation.getter(#currentChangeAddressP2PKH), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i24.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i26.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i24.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i26.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i24.Future<_i8.FeeObject>); + ) as _i26.Future<_i8.FeeObject>); @override - _i24.Future<int> get maxFee => (super.noSuchMethod( + _i26.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override - _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i26.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i26.Future<List<String>>.value(<String>[]), + ) as _i26.Future<List<String>>); @override - _i24.Future<String?> get mnemonicString => (super.noSuchMethod( + _i26.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i26.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<int> get chainHeight => (super.noSuchMethod( + _i26.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -928,10 +953,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { ), ) as _i11.Balance); @override - _i24.Future<String> get xpub => (super.noSuchMethod( + _i26.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -958,26 +983,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { ), ) as _i13.NetworkType); @override - _i24.Future<void> exit() => (super.noSuchMethod( + _i26.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i28.DerivePathType addressType({required String? address}) => + _i30.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i28.DerivePathType.bip44, - ) as _i28.DerivePathType); + returnValue: _i30.DerivePathType.bip44, + ) as _i30.DerivePathType); @override - _i24.Future<void> recoverFromMnemonic({ + _i26.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -996,47 +1021,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { #height: height, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i26.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i26.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i26.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> refresh() => (super.noSuchMethod( + _i26.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<Map<String, dynamic>> prepareSend({ + _i26.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i14.Amount? amount, Map<String, dynamic>? args, @@ -1052,26 +1077,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i26.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i26.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -1089,35 +1114,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<void> initializeNew( + _i26.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> initializeExisting() => (super.noSuchMethod( + _i26.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i26.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1127,69 +1152,69 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { returnValue: false, ) as bool); @override - _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i26.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i26.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i24.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_11( + returnValue: _i26.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_11( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i24.Future<_i9.ElectrumXNode>); + ) as _i26.Future<_i9.ElectrumXNode>); @override - _i24.Future<List<Map<String, dynamic>>> fastFetch( + _i26.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i24.Future<List<Map<String, dynamic>>>.value( + returnValue: _i26.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i24.Future<List<Map<String, dynamic>>>); + ) as _i26.Future<List<Map<String, dynamic>>>); @override - _i24.Future<int> getTxCount({required String? address}) => + _i26.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override - _i24.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i26.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> checkCurrentChangeAddressesForTransactions() => + _i26.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1215,7 +1240,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { required bool? isSendAll, int? satsPerVByte, int? additionalOutputs = 0, - List<_i17.UTXO>? utxos, + List<_i18.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1232,19 +1257,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { }, )); @override - _i24.Future<List<_i29.SigningData>> fetchBuildTxData( - List<_i17.UTXO>? utxosToUse) => + _i26.Future<List<_i31.SigningData>> fetchBuildTxData( + List<_i18.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i24.Future<List<_i29.SigningData>>.value(<_i29.SigningData>[]), - ) as _i24.Future<List<_i29.SigningData>>); + _i26.Future<List<_i31.SigningData>>.value(<_i31.SigningData>[]), + ) as _i26.Future<List<_i31.SigningData>>); @override - _i24.Future<Map<String, dynamic>> buildTransaction({ - required List<_i29.SigningData>? utxoSigningData, + _i26.Future<Map<String, dynamic>> buildTransaction({ + required List<_i31.SigningData>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, }) => @@ -1259,10 +1284,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<void> fullRescan( + _i26.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1274,11 +1299,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i14.Amount> estimateFeeFor( + _i26.Future<_i14.Amount> estimateFeeFor( _i14.Amount? amount, int? feeRate, ) => @@ -1290,7 +1315,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { feeRate, ], ), - returnValue: _i24.Future<_i14.Amount>.value(_FakeAmount_12( + returnValue: _i26.Future<_i14.Amount>.value(_FakeAmount_12( this, Invocation.method( #estimateFeeFor, @@ -1300,7 +1325,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { ], ), )), - ) as _i24.Future<_i14.Amount>); + ) as _i26.Future<_i14.Amount>); @override _i14.Amount roughFeeEstimate( int? inputCount, @@ -1329,32 +1354,32 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { ), ) as _i14.Amount); @override - _i24.Future<_i14.Amount> sweepAllEstimate(int? feeRate) => + _i26.Future<_i14.Amount> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i24.Future<_i14.Amount>.value(_FakeAmount_12( + returnValue: _i26.Future<_i14.Amount>.value(_FakeAmount_12( this, Invocation.method( #sweepAllEstimate, [feeRate], ), )), - ) as _i24.Future<_i14.Amount>); + ) as _i26.Future<_i14.Amount>); @override - _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i26.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override void initCache( String? walletId, - _i23.Coin? coin, + _i25.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1367,14 +1392,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i26.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1384,14 +1409,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { returnValue: 0, ) as int); @override - _i24.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i26.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1401,15 +1426,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { returnValue: false, ) as bool); @override - _i24.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i26.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1425,15 +1450,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { ), ) as _i11.Balance); @override - _i24.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i26.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1449,15 +1474,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { ), ) as _i11.Balance); @override - _i24.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i26.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override List<String> getWalletTokenContractAddresses() => (super.noSuchMethod( Invocation.method( @@ -1467,16 +1492,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { returnValue: <String>[], ) as List<String>); @override - _i24.Future<void> updateWalletTokenContractAddresses( + _i26.Future<void> updateWalletTokenContractAddresses( List<String>? contractAddresses) => (super.noSuchMethod( Invocation.method( #updateWalletTokenContractAddresses, [contractAddresses], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1487,11 +1512,45 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<_i15.Tuple2<_i17.Transaction, _i17.Address>> parseTransaction( + _i26.Future<_i15.TransactionV2> getTransaction( + String? txHash, + _i25.Coin? coin, + String? walletId, + _i10.CachedElectrumX? cachedElectrumX, [ + String? debugTitle, + ]) => + (super.noSuchMethod( + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + returnValue: + _i26.Future<_i15.TransactionV2>.value(_FakeTransactionV2_13( + this, + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + )), + ) as _i26.Future<_i15.TransactionV2>); + @override + _i26.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>> parseTransaction( Map<String, dynamic>? txData, dynamic electrumxClient, - List<_i17.Address>? myAddresses, - _i23.Coin? coin, + List<_i18.Address>? myAddresses, + _i25.Coin? coin, int? minConfirms, String? walletId, ) => @@ -1508,8 +1567,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { ], ), returnValue: - _i24.Future<_i15.Tuple2<_i17.Transaction, _i17.Address>>.value( - _FakeTuple2_13<_i17.Transaction, _i17.Address>( + _i26.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>.value( + _FakeTuple2_14<_i18.Transaction, _i18.Address>( this, Invocation.method( #parseTransaction, @@ -1523,37 +1582,37 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { ], ), )), - ) as _i24.Future<_i15.Tuple2<_i17.Transaction, _i17.Address>>); + ) as _i26.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>); @override void initPaynymWalletInterface({ required String? walletId, required String? walletName, required _i13.NetworkType? network, - required _i23.Coin? coin, + required _i25.Coin? coin, required _i12.MainDB? db, required _i9.ElectrumX? electrumXClient, - required _i20.SecureStorageInterface? secureStorage, + required _i22.SecureStorageInterface? secureStorage, required int? dustLimit, required int? dustLimitP2PKH, required int? minConfirms, - required _i24.Future<String?> Function()? getMnemonicString, - required _i24.Future<String?> Function()? getMnemonicPassphrase, - required _i24.Future<int> Function()? getChainHeight, - required _i24.Future<String> Function()? getCurrentChangeAddress, + required _i26.Future<String?> Function()? getMnemonicString, + required _i26.Future<String?> Function()? getMnemonicPassphrase, + required _i26.Future<int> Function()? getChainHeight, + required _i26.Future<String> Function()? getCurrentChangeAddress, required int Function({ required int feeRatePerKB, required int vSize, })? estimateTxFee, - required _i24.Future<Map<String, dynamic>> Function({ + required _i26.Future<Map<String, dynamic>> Function({ required String address, required _i14.Amount amount, Map<String, dynamic>? args, })? prepareSend, - required _i24.Future<int> Function({required String address})? getTxCount, - required _i24.Future<List<_i29.SigningData>> Function(List<_i17.UTXO>)? + required _i26.Future<int> Function({required String address})? getTxCount, + required _i26.Future<List<_i31.SigningData>> Function(List<_i18.UTXO>)? fetchBuildTxData, - required _i24.Future<void> Function()? refresh, - required _i24.Future<void> Function()? checkChangeAddressForTransactions, + required _i26.Future<void> Function()? refresh, + required _i26.Future<void> Function()? checkChangeAddressForTransactions, }) => super.noSuchMethod( Invocation.method( @@ -1586,21 +1645,21 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<_i16.BIP32> getBip47BaseNode() => (super.noSuchMethod( + _i26.Future<_i17.BIP32> getBip47BaseNode() => (super.noSuchMethod( Invocation.method( #getBip47BaseNode, [], ), - returnValue: _i24.Future<_i16.BIP32>.value(_FakeBIP32_14( + returnValue: _i26.Future<_i17.BIP32>.value(_FakeBIP32_15( this, Invocation.method( #getBip47BaseNode, [], ), )), - ) as _i24.Future<_i16.BIP32>); + ) as _i26.Future<_i17.BIP32>); @override - _i24.Future<_i30.Uint8List> getPrivateKeyForPaynymReceivingAddress({ + _i26.Future<_i32.Uint8List> getPrivateKeyForPaynymReceivingAddress({ required String? paymentCodeString, required int? index, }) => @@ -1613,11 +1672,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { #index: index, }, ), - returnValue: _i24.Future<_i30.Uint8List>.value(_i30.Uint8List(0)), - ) as _i24.Future<_i30.Uint8List>); + returnValue: _i26.Future<_i32.Uint8List>.value(_i32.Uint8List(0)), + ) as _i26.Future<_i32.Uint8List>); @override - _i24.Future<_i17.Address> currentReceivingPaynymAddress({ - required _i18.PaymentCode? sender, + _i26.Future<_i18.Address> currentReceivingPaynymAddress({ + required _i19.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1629,7 +1688,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i24.Future<_i17.Address>.value(_FakeAddress_15( + returnValue: _i26.Future<_i18.Address>.value(_FakeAddress_16( this, Invocation.method( #currentReceivingPaynymAddress, @@ -1640,10 +1699,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { }, ), )), - ) as _i24.Future<_i17.Address>); + ) as _i26.Future<_i18.Address>); @override - _i24.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ - required _i18.PaymentCode? sender, + _i26.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ + required _i19.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1655,42 +1714,42 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => + _i26.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkAllCurrentReceivingPaynymAddressesForTransactions, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i16.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( + _i26.Future<_i17.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( Invocation.method( #deriveNotificationBip32Node, [], ), - returnValue: _i24.Future<_i16.BIP32>.value(_FakeBIP32_14( + returnValue: _i26.Future<_i17.BIP32>.value(_FakeBIP32_15( this, Invocation.method( #deriveNotificationBip32Node, [], ), )), - ) as _i24.Future<_i16.BIP32>); + ) as _i26.Future<_i17.BIP32>); @override - _i24.Future<_i18.PaymentCode> getPaymentCode({required bool? isSegwit}) => + _i26.Future<_i19.PaymentCode> getPaymentCode({required bool? isSegwit}) => (super.noSuchMethod( Invocation.method( #getPaymentCode, [], {#isSegwit: isSegwit}, ), - returnValue: _i24.Future<_i18.PaymentCode>.value(_FakePaymentCode_16( + returnValue: _i26.Future<_i19.PaymentCode>.value(_FakePaymentCode_17( this, Invocation.method( #getPaymentCode, @@ -1698,28 +1757,28 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { {#isSegwit: isSegwit}, ), )), - ) as _i24.Future<_i18.PaymentCode>); + ) as _i26.Future<_i19.PaymentCode>); @override - _i24.Future<_i30.Uint8List> signWithNotificationKey(_i30.Uint8List? data) => + _i26.Future<_i32.Uint8List> signWithNotificationKey(_i32.Uint8List? data) => (super.noSuchMethod( Invocation.method( #signWithNotificationKey, [data], ), - returnValue: _i24.Future<_i30.Uint8List>.value(_i30.Uint8List(0)), - ) as _i24.Future<_i30.Uint8List>); + returnValue: _i26.Future<_i32.Uint8List>.value(_i32.Uint8List(0)), + ) as _i26.Future<_i32.Uint8List>); @override - _i24.Future<String> signStringWithNotificationKey(String? data) => + _i26.Future<String> signStringWithNotificationKey(String? data) => (super.noSuchMethod( Invocation.method( #signStringWithNotificationKey, [data], ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<Map<String, dynamic>> preparePaymentCodeSend({ - required _i18.PaymentCode? paymentCode, + _i26.Future<Map<String, dynamic>> preparePaymentCodeSend({ + required _i19.PaymentCode? paymentCode, required bool? isSegwit, required _i14.Amount? amount, Map<String, dynamic>? args, @@ -1736,13 +1795,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<_i17.Address> nextUnusedSendAddressFrom({ - required _i18.PaymentCode? pCode, + _i26.Future<_i18.Address> nextUnusedSendAddressFrom({ + required _i19.PaymentCode? pCode, required bool? isSegwit, - required _i16.BIP32? privateKeyNode, + required _i17.BIP32? privateKeyNode, int? startIndex = 0, }) => (super.noSuchMethod( @@ -1756,7 +1815,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { #startIndex: startIndex, }, ), - returnValue: _i24.Future<_i17.Address>.value(_FakeAddress_15( + returnValue: _i26.Future<_i18.Address>.value(_FakeAddress_16( this, Invocation.method( #nextUnusedSendAddressFrom, @@ -1769,13 +1828,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { }, ), )), - ) as _i24.Future<_i17.Address>); + ) as _i26.Future<_i18.Address>); @override - _i24.Future<Map<String, dynamic>> prepareNotificationTx({ + _i26.Future<Map<String, dynamic>> prepareNotificationTx({ required int? selectedTxFeeRate, required String? targetPaymentCodeString, int? additionalOutputs = 0, - List<_i17.UTXO>? utxos, + List<_i18.UTXO>? utxos, }) => (super.noSuchMethod( Invocation.method( @@ -1789,10 +1848,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<String> broadcastNotificationTx( + _i26.Future<String> broadcastNotificationTx( {required Map<String, dynamic>? preparedTx}) => (super.noSuchMethod( Invocation.method( @@ -1800,62 +1859,62 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { [], {#preparedTx: preparedTx}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<bool> hasConnected(String? paymentCodeString) => + _i26.Future<bool> hasConnected(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #hasConnected, [paymentCodeString], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<_i18.PaymentCode?> unBlindedPaymentCodeFromTransaction( - {required _i17.Transaction? transaction}) => + _i26.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransaction( + {required _i18.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransaction, [], {#transaction: transaction}, ), - returnValue: _i24.Future<_i18.PaymentCode?>.value(), - ) as _i24.Future<_i18.PaymentCode?>); + returnValue: _i26.Future<_i19.PaymentCode?>.value(), + ) as _i26.Future<_i19.PaymentCode?>); @override - _i24.Future<_i18.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( - {required _i17.Transaction? transaction}) => + _i26.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( + {required _i18.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransactionBad, [], {#transaction: transaction}, ), - returnValue: _i24.Future<_i18.PaymentCode?>.value(), - ) as _i24.Future<_i18.PaymentCode?>); + returnValue: _i26.Future<_i19.PaymentCode?>.value(), + ) as _i26.Future<_i19.PaymentCode?>); @override - _i24.Future<List<_i18.PaymentCode>> + _i26.Future<List<_i19.PaymentCode>> getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod( Invocation.method( #getAllPaymentCodesFromNotificationTransactions, [], ), returnValue: - _i24.Future<List<_i18.PaymentCode>>.value(<_i18.PaymentCode>[]), - ) as _i24.Future<List<_i18.PaymentCode>>); + _i26.Future<List<_i19.PaymentCode>>.value(<_i19.PaymentCode>[]), + ) as _i26.Future<List<_i19.PaymentCode>>); @override - _i24.Future<void> checkForNotificationTransactionsTo( + _i26.Future<void> checkForNotificationTransactionsTo( Set<String>? otherCodeStrings) => (super.noSuchMethod( Invocation.method( #checkForNotificationTransactionsTo, [otherCodeStrings], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> restoreAllHistory({ + _i26.Future<void> restoreAllHistory({ required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, required Set<String>? paymentCodeStrings, @@ -1870,12 +1929,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { #paymentCodeStrings: paymentCodeStrings, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> restoreHistoryWith({ - required _i18.PaymentCode? other, + _i26.Future<void> restoreHistoryWith({ + required _i19.PaymentCode? other, required bool? checkSegwitAsWell, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1891,58 +1950,58 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { #maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i17.Address> getMyNotificationAddress() => (super.noSuchMethod( + _i26.Future<_i18.Address> getMyNotificationAddress() => (super.noSuchMethod( Invocation.method( #getMyNotificationAddress, [], ), - returnValue: _i24.Future<_i17.Address>.value(_FakeAddress_15( + returnValue: _i26.Future<_i18.Address>.value(_FakeAddress_16( this, Invocation.method( #getMyNotificationAddress, [], ), )), - ) as _i24.Future<_i17.Address>); + ) as _i26.Future<_i18.Address>); @override - _i24.Future<List<String>> lookupKey(String? paymentCodeString) => + _i26.Future<List<String>> lookupKey(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #lookupKey, [paymentCodeString], ), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i26.Future<List<String>>.value(<String>[]), + ) as _i26.Future<List<String>>); @override - _i24.Future<String?> paymentCodeStringByKey(String? key) => + _i26.Future<String?> paymentCodeStringByKey(String? key) => (super.noSuchMethod( Invocation.method( #paymentCodeStringByKey, [key], ), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<String> storeCode(String? paymentCodeString) => + _i26.Future<String> storeCode(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #storeCode, [paymentCodeString], ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override void initCoinControlInterface({ required String? walletId, required String? walletName, - required _i23.Coin? coin, + required _i25.Coin? coin, required _i12.MainDB? db, - required _i24.Future<int> Function()? getChainHeight, - required _i24.Future<void> Function(_i11.Balance)? refreshedBalanceCallback, + required _i26.Future<int> Function()? getChainHeight, + required _i26.Future<void> Function(_i11.Balance)? refreshedBalanceCallback, }) => super.noSuchMethod( Invocation.method( @@ -1960,36 +2019,36 @@ class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<void> refreshBalance({bool? notify = false}) => + _i26.Future<void> refreshBalance({bool? notify = false}) => (super.noSuchMethod( Invocation.method( #refreshBalance, [], {#notify: notify}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); } /// A class which mocks [ThemeService]. /// /// See the documentation for Mockito's code generation for more information. -class MockThemeService extends _i1.Mock implements _i31.ThemeService { +class MockThemeService extends _i1.Mock implements _i33.ThemeService { MockThemeService() { _i1.throwOnMissingStub(this); } @override - _i19.HTTP get client => (super.noSuchMethod( + _i20.HTTP get client => (super.noSuchMethod( Invocation.getter(#client), - returnValue: _FakeHTTP_17( + returnValue: _FakeHTTP_18( this, Invocation.getter(#client), ), - ) as _i19.HTTP); + ) as _i20.HTTP); @override - set client(_i19.HTTP? _client) => super.noSuchMethod( + set client(_i20.HTTP? _client) => super.noSuchMethod( Invocation.setter( #client, _client, @@ -2005,10 +2064,10 @@ class MockThemeService extends _i1.Mock implements _i31.ThemeService { ), ) as _i12.MainDB); @override - List<_i32.StackTheme> get installedThemes => (super.noSuchMethod( + List<_i34.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), - returnValue: <_i32.StackTheme>[], - ) as List<_i32.StackTheme>); + returnValue: <_i34.StackTheme>[], + ) as List<_i34.StackTheme>); @override void init(_i12.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -2018,79 +2077,79 @@ class MockThemeService extends _i1.Mock implements _i31.ThemeService { returnValueForMissingStub: null, ); @override - _i24.Future<void> install({required _i30.Uint8List? themeArchiveData}) => + _i26.Future<void> install({required _i32.Uint8List? themeArchiveData}) => (super.noSuchMethod( Invocation.method( #install, [], {#themeArchiveData: themeArchiveData}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> remove({required String? themeId}) => (super.noSuchMethod( + _i26.Future<void> remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( #remove, [], {#themeId: themeId}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( + _i26.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( #checkDefaultThemesOnStartup, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<bool> verifyInstalled({required String? themeId}) => + _i26.Future<bool> verifyInstalled({required String? themeId}) => (super.noSuchMethod( Invocation.method( #verifyInstalled, [], {#themeId: themeId}, ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<List<_i31.StackThemeMetaData>> fetchThemes() => + _i26.Future<List<_i33.StackThemeMetaData>> fetchThemes() => (super.noSuchMethod( Invocation.method( #fetchThemes, [], ), - returnValue: _i24.Future<List<_i31.StackThemeMetaData>>.value( - <_i31.StackThemeMetaData>[]), - ) as _i24.Future<List<_i31.StackThemeMetaData>>); + returnValue: _i26.Future<List<_i33.StackThemeMetaData>>.value( + <_i33.StackThemeMetaData>[]), + ) as _i26.Future<List<_i33.StackThemeMetaData>>); @override - _i24.Future<_i30.Uint8List> fetchTheme( - {required _i31.StackThemeMetaData? themeMetaData}) => + _i26.Future<_i32.Uint8List> fetchTheme( + {required _i33.StackThemeMetaData? themeMetaData}) => (super.noSuchMethod( Invocation.method( #fetchTheme, [], {#themeMetaData: themeMetaData}, ), - returnValue: _i24.Future<_i30.Uint8List>.value(_i30.Uint8List(0)), - ) as _i24.Future<_i30.Uint8List>); + returnValue: _i26.Future<_i32.Uint8List>.value(_i32.Uint8List(0)), + ) as _i26.Future<_i32.Uint8List>); @override - _i32.StackTheme? getTheme({required String? themeId}) => + _i34.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( #getTheme, [], {#themeId: themeId}, - )) as _i32.StackTheme?); + )) as _i34.StackTheme?); } /// A class which mocks [Prefs]. /// /// See the documentation for Mockito's code generation for more information. -class MockPrefs extends _i1.Mock implements _i25.Prefs { +class MockPrefs extends _i1.Mock implements _i27.Prefs { MockPrefs() { _i1.throwOnMissingStub(this); } @@ -2146,12 +2205,12 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override - _i33.SyncingType get syncType => (super.noSuchMethod( + _i35.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), - returnValue: _i33.SyncingType.currentWalletOnly, - ) as _i33.SyncingType); + returnValue: _i35.SyncingType.currentWalletOnly, + ) as _i35.SyncingType); @override - set syncType(_i33.SyncingType? syncType) => super.noSuchMethod( + set syncType(_i35.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( #syncType, syncType, @@ -2310,12 +2369,12 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override - _i34.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( + _i36.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), - returnValue: _i34.BackupFrequencyType.everyTenMinutes, - ) as _i34.BackupFrequencyType); + returnValue: _i36.BackupFrequencyType.everyTenMinutes, + ) as _i36.BackupFrequencyType); @override - set backupFrequencyType(_i34.BackupFrequencyType? backupFrequencyType) => + set backupFrequencyType(_i36.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( Invocation.setter( #backupFrequencyType, @@ -2461,66 +2520,82 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override + _i21.FusionInfo get fusionServerInfo => (super.noSuchMethod( + Invocation.getter(#fusionServerInfo), + returnValue: _FakeFusionInfo_19( + this, + Invocation.getter(#fusionServerInfo), + ), + ) as _i21.FusionInfo); + @override + set fusionServerInfo(_i21.FusionInfo? fusionServerInfo) => super.noSuchMethod( + Invocation.setter( + #fusionServerInfo, + fusionServerInfo, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i24.Future<void> init() => (super.noSuchMethod( + _i26.Future<void> init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( + _i26.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( #incrementCurrentNotificationIndex, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<bool> isExternalCallsSet() => (super.noSuchMethod( + _i26.Future<bool> isExternalCallsSet() => (super.noSuchMethod( Invocation.method( #isExternalCallsSet, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> saveUserID(String? userId) => (super.noSuchMethod( + _i26.Future<void> saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( #saveUserID, [userId], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( + _i26.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( #saveSignupEpoch, [signupEpoch], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i35.AmountUnit amountUnit(_i23.Coin? coin) => (super.noSuchMethod( + _i37.AmountUnit amountUnit(_i25.Coin? coin) => (super.noSuchMethod( Invocation.method( #amountUnit, [coin], ), - returnValue: _i35.AmountUnit.normal, - ) as _i35.AmountUnit); + returnValue: _i37.AmountUnit.normal, + ) as _i37.AmountUnit); @override void updateAmountUnit({ - required _i23.Coin? coin, - required _i35.AmountUnit? amountUnit, + required _i25.Coin? coin, + required _i37.AmountUnit? amountUnit, }) => super.noSuchMethod( Invocation.method( @@ -2534,7 +2609,7 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override - int maxDecimals(_i23.Coin? coin) => (super.noSuchMethod( + int maxDecimals(_i25.Coin? coin) => (super.noSuchMethod( Invocation.method( #maxDecimals, [coin], @@ -2543,7 +2618,7 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { ) as int); @override void updateMaxDecimals({ - required _i23.Coin? coin, + required _i25.Coin? coin, required int? maxDecimals, }) => super.noSuchMethod( @@ -2558,7 +2633,7 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2566,7 +2641,7 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2594,7 +2669,7 @@ class MockPrefs extends _i1.Mock implements _i25.Prefs { /// A class which mocks [LocaleService]. /// /// See the documentation for Mockito's code generation for more information. -class MockLocaleService extends _i1.Mock implements _i36.LocaleService { +class MockLocaleService extends _i1.Mock implements _i38.LocaleService { MockLocaleService() { _i1.throwOnMissingStub(this); } @@ -2610,17 +2685,17 @@ class MockLocaleService extends _i1.Mock implements _i36.LocaleService { returnValue: false, ) as bool); @override - _i24.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( + _i26.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( #loadLocale, [], {#notify: notify}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2628,7 +2703,7 @@ class MockLocaleService extends _i1.Mock implements _i36.LocaleService { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2658,41 +2733,41 @@ class MockLocaleService extends _i1.Mock implements _i36.LocaleService { /// See the documentation for Mockito's code generation for more information. class MockNodeService extends _i1.Mock implements _i3.NodeService { @override - _i20.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( + _i22.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( Invocation.getter(#secureStorageInterface), - returnValue: _FakeSecureStorageInterface_18( + returnValue: _FakeSecureStorageInterface_20( this, Invocation.getter(#secureStorageInterface), ), - ) as _i20.SecureStorageInterface); + ) as _i22.SecureStorageInterface); @override - List<_i37.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i39.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i37.NodeModel>[], - ) as List<_i37.NodeModel>); + returnValue: <_i39.NodeModel>[], + ) as List<_i39.NodeModel>); @override - List<_i37.NodeModel> get nodes => (super.noSuchMethod( + List<_i39.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i37.NodeModel>[], - ) as List<_i37.NodeModel>); + returnValue: <_i39.NodeModel>[], + ) as List<_i39.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i24.Future<void> updateDefaults() => (super.noSuchMethod( + _i26.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> setPrimaryNodeFor({ - required _i23.Coin? coin, - required _i37.NodeModel? node, + _i26.Future<void> setPrimaryNodeFor({ + required _i25.Coin? coin, + required _i39.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -2705,44 +2780,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i37.NodeModel? getPrimaryNodeFor({required _i23.Coin? coin}) => + _i39.NodeModel? getPrimaryNodeFor({required _i25.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i37.NodeModel?); + )) as _i39.NodeModel?); @override - List<_i37.NodeModel> getNodesFor(_i23.Coin? coin) => (super.noSuchMethod( + List<_i39.NodeModel> getNodesFor(_i25.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i37.NodeModel>[], - ) as List<_i37.NodeModel>); + returnValue: <_i39.NodeModel>[], + ) as List<_i39.NodeModel>); @override - _i37.NodeModel? getNodeById({required String? id}) => + _i39.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i37.NodeModel?); + )) as _i39.NodeModel?); @override - List<_i37.NodeModel> failoverNodesFor({required _i23.Coin? coin}) => + List<_i39.NodeModel> failoverNodesFor({required _i25.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i37.NodeModel>[], - ) as List<_i37.NodeModel>); + returnValue: <_i39.NodeModel>[], + ) as List<_i39.NodeModel>); @override - _i24.Future<void> add( - _i37.NodeModel? node, + _i26.Future<void> add( + _i39.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -2755,11 +2830,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> delete( + _i26.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -2771,11 +2846,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> setEnabledState( + _i26.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -2789,12 +2864,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> edit( - _i37.NodeModel? editedNode, + _i26.Future<void> edit( + _i39.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -2807,20 +2882,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i26.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2828,7 +2903,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2871,23 +2946,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i21.CoinServiceAPI get wallet => (super.noSuchMethod( + _i23.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_19( + returnValue: _FakeCoinServiceAPI_21( this, Invocation.getter(#wallet), ), - ) as _i21.CoinServiceAPI); + ) as _i23.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i23.Coin get coin => (super.noSuchMethod( + _i25.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i23.Coin.bitcoin, - ) as _i23.Coin); + returnValue: _i25.Coin.bitcoin, + ) as _i25.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2920,23 +2995,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i24.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i26.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i24.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i26.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i24.Future<_i8.FeeObject>); + ) as _i26.Future<_i8.FeeObject>); @override - _i24.Future<int> get maxFee => (super.noSuchMethod( + _i26.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override - _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i26.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2946,16 +3021,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i11.Balance); @override - _i24.Future<List<_i17.Transaction>> get transactions => (super.noSuchMethod( + _i26.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i24.Future<List<_i17.Transaction>>.value(<_i17.Transaction>[]), - ) as _i24.Future<List<_i17.Transaction>>); + _i26.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), + ) as _i26.Future<List<_i18.Transaction>>); @override - _i24.Future<List<_i17.UTXO>> get utxos => (super.noSuchMethod( + _i26.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i24.Future<List<_i17.UTXO>>.value(<_i17.UTXO>[]), - ) as _i24.Future<List<_i17.UTXO>>); + returnValue: _i26.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), + ) as _i26.Future<List<_i18.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2975,15 +3050,15 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i26.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i26.Future<List<String>>.value(<String>[]), + ) as _i26.Future<List<String>>); @override - _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i26.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -3020,6 +3095,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, @@ -3030,24 +3110,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i24.Future<String> get xpub => (super.noSuchMethod( + _i26.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i26.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -3057,7 +3137,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i24.Future<Map<String, dynamic>> prepareSend({ + _i26.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i14.Amount? amount, Map<String, dynamic>? args, @@ -3073,27 +3153,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i26.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<void> refresh() => (super.noSuchMethod( + _i26.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -3103,35 +3183,35 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i26.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> initializeNew( + _i26.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> initializeExisting() => (super.noSuchMethod( + _i26.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> recoverFromMnemonic({ + _i26.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -3150,20 +3230,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i26.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> fullRescan( + _i26.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -3175,11 +3255,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i14.Amount> estimateFeeFor( + _i26.Future<_i14.Amount> estimateFeeFor( _i14.Amount? amount, int? feeRate, ) => @@ -3191,7 +3271,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i24.Future<_i14.Amount>.value(_FakeAmount_12( + returnValue: _i26.Future<_i14.Amount>.value(_FakeAmount_12( this, Invocation.method( #estimateFeeFor, @@ -3201,26 +3281,26 @@ class MockManager extends _i1.Mock implements _i6.Manager { ], ), )), - ) as _i24.Future<_i14.Amount>); + ) as _i26.Future<_i14.Amount>); @override - _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i26.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> resetRescanOnOpen() => (super.noSuchMethod( + _i26.Future<void> resetRescanOnOpen() => (super.noSuchMethod( Invocation.method( #resetRescanOnOpen, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -3228,7 +3308,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i28.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -3248,7 +3328,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i23.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -3259,10 +3339,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i23.Coin get coin => (super.noSuchMethod( + _i25.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i23.Coin.bitcoin, - ) as _i23.Coin); + returnValue: _i25.Coin.bitcoin, + ) as _i25.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -3295,23 +3375,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i24.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i26.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i24.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i26.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i24.Future<_i8.FeeObject>); + ) as _i26.Future<_i8.FeeObject>); @override - _i24.Future<int> get maxFee => (super.noSuchMethod( + _i26.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i26.Future<int>.value(0), + ) as _i26.Future<int>); @override - _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i26.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -3321,16 +3401,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { ), ) as _i11.Balance); @override - _i24.Future<List<_i17.Transaction>> get transactions => (super.noSuchMethod( + _i26.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i24.Future<List<_i17.Transaction>>.value(<_i17.Transaction>[]), - ) as _i24.Future<List<_i17.Transaction>>); + _i26.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), + ) as _i26.Future<List<_i18.Transaction>>); @override - _i24.Future<List<_i17.UTXO>> get utxos => (super.noSuchMethod( + _i26.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i24.Future<List<_i17.UTXO>>.value(<_i17.UTXO>[]), - ) as _i24.Future<List<_i17.UTXO>>); + returnValue: _i26.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), + ) as _i26.Future<List<_i18.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -3350,20 +3430,20 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValue: '', ) as String); @override - _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i26.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i26.Future<List<String>>.value(<String>[]), + ) as _i26.Future<List<String>>); @override - _i24.Future<String?> get mnemonicString => (super.noSuchMethod( + _i26.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override - _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i26.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i26.Future<String?>.value(), + ) as _i26.Future<String?>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -3380,7 +3460,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValue: 0, ) as int); @override - _i24.Future<Map<String, dynamic>> prepareSend({ + _i26.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i14.Amount? amount, Map<String, dynamic>? args, @@ -3396,36 +3476,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i26.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i26.Future<Map<String, dynamic>>); @override - _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i26.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i26.Future<String>.value(''), + ) as _i26.Future<String>); @override - _i24.Future<void> refresh() => (super.noSuchMethod( + _i26.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i26.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -3435,15 +3515,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValue: false, ) as bool); @override - _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i26.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> recoverFromMnemonic({ + _i26.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -3462,40 +3542,40 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { #height: height, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> initializeNew( + _i26.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> initializeExisting() => (super.noSuchMethod( + _i26.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> exit() => (super.noSuchMethod( + _i26.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<void> fullRescan( + _i26.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -3507,11 +3587,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); @override - _i24.Future<_i14.Amount> estimateFeeFor( + _i26.Future<_i14.Amount> estimateFeeFor( _i14.Amount? amount, int? feeRate, ) => @@ -3523,7 +3603,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { feeRate, ], ), - returnValue: _i24.Future<_i14.Amount>.value(_FakeAmount_12( + returnValue: _i26.Future<_i14.Amount>.value(_FakeAmount_12( this, Invocation.method( #estimateFeeFor, @@ -3533,23 +3613,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { ], ), )), - ) as _i24.Future<_i14.Amount>); + ) as _i26.Future<_i14.Amount>); @override - _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i26.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i26.Future<bool>.value(false), + ) as _i26.Future<bool>); @override - _i24.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i26.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i26.Future<void>.value(), + returnValueForMissingStub: _i26.Future<void>.value(), + ) as _i26.Future<void>); } diff --git a/test/widget_tests/node_options_sheet_test.mocks.dart b/test/widget_tests/node_options_sheet_test.mocks.dart index 42528b822..4b245f310 100644 --- a/test/widget_tests/node_options_sheet_test.mocks.dart +++ b/test/widget_tests/node_options_sheet_test.mocks.dart @@ -3,30 +3,32 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i12; -import 'dart:io' as _i8; -import 'dart:ui' as _i14; +import 'dart:async' as _i13; +import 'dart:io' as _i9; +import 'dart:ui' as _i15; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; import 'package:mockito/mockito.dart' as _i1; -import 'package:stackwallet/models/node_model.dart' as _i18; +import 'package:stackwallet/models/node_model.dart' as _i19; import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/event_bus/events/global/tor_connection_status_changed_event.dart' - as _i20; -import 'package:stackwallet/services/node_service.dart' as _i3; -import 'package:stackwallet/services/tor_service.dart' as _i19; -import 'package:stackwallet/services/wallets.dart' as _i9; -import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i17; -import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i16; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i10; -import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i15; -import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' + as _i21; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart' as _i7; -import 'package:stackwallet/utilities/prefs.dart' as _i13; -import 'package:tor_ffi_plugin/tor_ffi_plugin.dart' as _i21; -import 'package:tuple/tuple.dart' as _i11; +import 'package:stackwallet/services/node_service.dart' as _i3; +import 'package:stackwallet/services/tor_service.dart' as _i20; +import 'package:stackwallet/services/wallets.dart' as _i10; +import 'package:stackwallet/services/wallets_service.dart' as _i2; +import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i18; +import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i17; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i11; +import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i16; +import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' + as _i8; +import 'package:stackwallet/utilities/prefs.dart' as _i14; +import 'package:tor_ffi_plugin/tor_ffi_plugin.dart' as _i22; +import 'package:tuple/tuple.dart' as _i12; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -81,9 +83,8 @@ class _FakeManager_3 extends _i1.SmartFake implements _i6.Manager { ); } -class _FakeSecureStorageInterface_4 extends _i1.SmartFake - implements _i7.SecureStorageInterface { - _FakeSecureStorageInterface_4( +class _FakeFusionInfo_4 extends _i1.SmartFake implements _i7.FusionInfo { + _FakeFusionInfo_4( Object parent, Invocation parentInvocation, ) : super( @@ -92,9 +93,20 @@ class _FakeSecureStorageInterface_4 extends _i1.SmartFake ); } -class _FakeInternetAddress_5 extends _i1.SmartFake - implements _i8.InternetAddress { - _FakeInternetAddress_5( +class _FakeSecureStorageInterface_5 extends _i1.SmartFake + implements _i8.SecureStorageInterface { + _FakeSecureStorageInterface_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeInternetAddress_6 extends _i1.SmartFake + implements _i9.InternetAddress { + _FakeInternetAddress_6( Object parent, Invocation parentInvocation, ) : super( @@ -106,7 +118,7 @@ class _FakeInternetAddress_5 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i9.Wallets { +class MockWallets extends _i1.Mock implements _i10.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -173,7 +185,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i10.Coin? coin}) => + List<String> getWalletIdsFor({required _i11.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -183,20 +195,20 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { returnValue: <String>[], ) as List<String>); @override - List<_i11.Tuple2<_i10.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> + List<_i12.Tuple2<_i11.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i11.Tuple2<_i10.Coin, + returnValue: <_i12.Tuple2<_i11.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>[], ) as List< - _i11.Tuple2<_i10.Coin, + _i12.Tuple2<_i11.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i10.Coin? coin) => + _i11.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -260,17 +272,17 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { returnValueForMissingStub: null, ); @override - _i12.Future<void> load(_i13.Prefs? prefs) => (super.noSuchMethod( + _i13.Future<void> load(_i14.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i12.Future<void> loadAfterStackRestore( - _i13.Prefs? prefs, + _i13.Future<void> loadAfterStackRestore( + _i14.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -281,11 +293,11 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { managers, ], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - void addListener(_i14.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i15.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -293,7 +305,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i14.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i15.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -313,7 +325,7 @@ class MockWallets extends _i1.Mock implements _i9.Wallets { /// A class which mocks [Prefs]. /// /// See the documentation for Mockito's code generation for more information. -class MockPrefs extends _i1.Mock implements _i13.Prefs { +class MockPrefs extends _i1.Mock implements _i14.Prefs { MockPrefs() { _i1.throwOnMissingStub(this); } @@ -369,12 +381,12 @@ class MockPrefs extends _i1.Mock implements _i13.Prefs { returnValueForMissingStub: null, ); @override - _i15.SyncingType get syncType => (super.noSuchMethod( + _i16.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), - returnValue: _i15.SyncingType.currentWalletOnly, - ) as _i15.SyncingType); + returnValue: _i16.SyncingType.currentWalletOnly, + ) as _i16.SyncingType); @override - set syncType(_i15.SyncingType? syncType) => super.noSuchMethod( + set syncType(_i16.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( #syncType, syncType, @@ -533,12 +545,12 @@ class MockPrefs extends _i1.Mock implements _i13.Prefs { returnValueForMissingStub: null, ); @override - _i16.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( + _i17.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), - returnValue: _i16.BackupFrequencyType.everyTenMinutes, - ) as _i16.BackupFrequencyType); + returnValue: _i17.BackupFrequencyType.everyTenMinutes, + ) as _i17.BackupFrequencyType); @override - set backupFrequencyType(_i16.BackupFrequencyType? backupFrequencyType) => + set backupFrequencyType(_i17.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( Invocation.setter( #backupFrequencyType, @@ -684,66 +696,82 @@ class MockPrefs extends _i1.Mock implements _i13.Prefs { returnValueForMissingStub: null, ); @override + _i7.FusionInfo get fusionServerInfo => (super.noSuchMethod( + Invocation.getter(#fusionServerInfo), + returnValue: _FakeFusionInfo_4( + this, + Invocation.getter(#fusionServerInfo), + ), + ) as _i7.FusionInfo); + @override + set fusionServerInfo(_i7.FusionInfo? fusionServerInfo) => super.noSuchMethod( + Invocation.setter( + #fusionServerInfo, + fusionServerInfo, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i12.Future<void> init() => (super.noSuchMethod( + _i13.Future<void> init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i12.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( + _i13.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( #incrementCurrentNotificationIndex, [], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i12.Future<bool> isExternalCallsSet() => (super.noSuchMethod( + _i13.Future<bool> isExternalCallsSet() => (super.noSuchMethod( Invocation.method( #isExternalCallsSet, [], ), - returnValue: _i12.Future<bool>.value(false), - ) as _i12.Future<bool>); + returnValue: _i13.Future<bool>.value(false), + ) as _i13.Future<bool>); @override - _i12.Future<void> saveUserID(String? userId) => (super.noSuchMethod( + _i13.Future<void> saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( #saveUserID, [userId], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i12.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( + _i13.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( #saveSignupEpoch, [signupEpoch], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i17.AmountUnit amountUnit(_i10.Coin? coin) => (super.noSuchMethod( + _i18.AmountUnit amountUnit(_i11.Coin? coin) => (super.noSuchMethod( Invocation.method( #amountUnit, [coin], ), - returnValue: _i17.AmountUnit.normal, - ) as _i17.AmountUnit); + returnValue: _i18.AmountUnit.normal, + ) as _i18.AmountUnit); @override void updateAmountUnit({ - required _i10.Coin? coin, - required _i17.AmountUnit? amountUnit, + required _i11.Coin? coin, + required _i18.AmountUnit? amountUnit, }) => super.noSuchMethod( Invocation.method( @@ -757,7 +785,7 @@ class MockPrefs extends _i1.Mock implements _i13.Prefs { returnValueForMissingStub: null, ); @override - int maxDecimals(_i10.Coin? coin) => (super.noSuchMethod( + int maxDecimals(_i11.Coin? coin) => (super.noSuchMethod( Invocation.method( #maxDecimals, [coin], @@ -766,7 +794,7 @@ class MockPrefs extends _i1.Mock implements _i13.Prefs { ) as int); @override void updateMaxDecimals({ - required _i10.Coin? coin, + required _i11.Coin? coin, required int? maxDecimals, }) => super.noSuchMethod( @@ -781,7 +809,7 @@ class MockPrefs extends _i1.Mock implements _i13.Prefs { returnValueForMissingStub: null, ); @override - void addListener(_i14.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i15.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -789,7 +817,7 @@ class MockPrefs extends _i1.Mock implements _i13.Prefs { returnValueForMissingStub: null, ); @override - void removeListener(_i14.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i15.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -823,41 +851,41 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { } @override - _i7.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( + _i8.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( Invocation.getter(#secureStorageInterface), - returnValue: _FakeSecureStorageInterface_4( + returnValue: _FakeSecureStorageInterface_5( this, Invocation.getter(#secureStorageInterface), ), - ) as _i7.SecureStorageInterface); + ) as _i8.SecureStorageInterface); @override - List<_i18.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i19.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i18.NodeModel>[], - ) as List<_i18.NodeModel>); + returnValue: <_i19.NodeModel>[], + ) as List<_i19.NodeModel>); @override - List<_i18.NodeModel> get nodes => (super.noSuchMethod( + List<_i19.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i18.NodeModel>[], - ) as List<_i18.NodeModel>); + returnValue: <_i19.NodeModel>[], + ) as List<_i19.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i12.Future<void> updateDefaults() => (super.noSuchMethod( + _i13.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i12.Future<void> setPrimaryNodeFor({ - required _i10.Coin? coin, - required _i18.NodeModel? node, + _i13.Future<void> setPrimaryNodeFor({ + required _i11.Coin? coin, + required _i19.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -870,44 +898,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i18.NodeModel? getPrimaryNodeFor({required _i10.Coin? coin}) => + _i19.NodeModel? getPrimaryNodeFor({required _i11.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i18.NodeModel?); + )) as _i19.NodeModel?); @override - List<_i18.NodeModel> getNodesFor(_i10.Coin? coin) => (super.noSuchMethod( + List<_i19.NodeModel> getNodesFor(_i11.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i18.NodeModel>[], - ) as List<_i18.NodeModel>); + returnValue: <_i19.NodeModel>[], + ) as List<_i19.NodeModel>); @override - _i18.NodeModel? getNodeById({required String? id}) => + _i19.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i18.NodeModel?); + )) as _i19.NodeModel?); @override - List<_i18.NodeModel> failoverNodesFor({required _i10.Coin? coin}) => + List<_i19.NodeModel> failoverNodesFor({required _i11.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i18.NodeModel>[], - ) as List<_i18.NodeModel>); + returnValue: <_i19.NodeModel>[], + ) as List<_i19.NodeModel>); @override - _i12.Future<void> add( - _i18.NodeModel? node, + _i13.Future<void> add( + _i19.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -920,11 +948,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i12.Future<void> delete( + _i13.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -936,11 +964,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i12.Future<void> setEnabledState( + _i13.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -954,12 +982,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i12.Future<void> edit( - _i18.NodeModel? editedNode, + _i13.Future<void> edit( + _i19.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -972,20 +1000,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i12.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i13.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - void addListener(_i14.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i15.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -993,7 +1021,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i14.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i15.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1021,24 +1049,24 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { /// A class which mocks [TorService]. /// /// See the documentation for Mockito's code generation for more information. -class MockTorService extends _i1.Mock implements _i19.TorService { +class MockTorService extends _i1.Mock implements _i20.TorService { MockTorService() { _i1.throwOnMissingStub(this); } @override - _i20.TorConnectionStatus get status => (super.noSuchMethod( + _i21.TorConnectionStatus get status => (super.noSuchMethod( Invocation.getter(#status), - returnValue: _i20.TorConnectionStatus.disconnected, - ) as _i20.TorConnectionStatus); + returnValue: _i21.TorConnectionStatus.disconnected, + ) as _i21.TorConnectionStatus); @override - ({_i8.InternetAddress host, int port}) getProxyInfo() => (super.noSuchMethod( + ({_i9.InternetAddress host, int port}) getProxyInfo() => (super.noSuchMethod( Invocation.method( #getProxyInfo, [], ), returnValue: ( - host: _FakeInternetAddress_5( + host: _FakeInternetAddress_6( this, Invocation.method( #getProxyInfo, @@ -1047,11 +1075,11 @@ class MockTorService extends _i1.Mock implements _i19.TorService { ), port: 0 ), - ) as ({_i8.InternetAddress host, int port})); + ) as ({_i9.InternetAddress host, int port})); @override void init({ required String? torDataDirPath, - _i21.Tor? mockableOverride, + _i22.Tor? mockableOverride, }) => super.noSuchMethod( Invocation.method( @@ -1065,21 +1093,21 @@ class MockTorService extends _i1.Mock implements _i19.TorService { returnValueForMissingStub: null, ); @override - _i12.Future<void> start() => (super.noSuchMethod( + _i13.Future<void> start() => (super.noSuchMethod( Invocation.method( #start, [], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); @override - _i12.Future<void> disable() => (super.noSuchMethod( + _i13.Future<void> disable() => (super.noSuchMethod( Invocation.method( #disable, [], ), - returnValue: _i12.Future<void>.value(), - returnValueForMissingStub: _i12.Future<void>.value(), - ) as _i12.Future<void>); + returnValue: _i13.Future<void>.value(), + returnValueForMissingStub: _i13.Future<void>.value(), + ) as _i13.Future<void>); } diff --git a/test/widget_tests/table_view/table_view_row_test.mocks.dart b/test/widget_tests/table_view/table_view_row_test.mocks.dart index afb3f48c9..6ca13d318 100644 --- a/test/widget_tests/table_view/table_view_row_test.mocks.dart +++ b/test/widget_tests/table_view/table_view_row_test.mocks.dart @@ -3,12 +3,12 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i23; -import 'dart:typed_data' as _i28; -import 'dart:ui' as _i25; +import 'dart:async' as _i24; +import 'dart:typed_data' as _i29; +import 'dart:ui' as _i26; -import 'package:bip32/bip32.dart' as _i17; -import 'package:bip47/bip47.dart' as _i19; +import 'package:bip32/bip32.dart' as _i18; +import 'package:bip47/bip47.dart' as _i20; import 'package:bitcoindart/bitcoindart.dart' as _i14; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -17,27 +17,29 @@ import 'package:stackwallet/db/isar/main_db.dart' as _i8; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i12; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i11; import 'package:stackwallet/models/balance.dart' as _i13; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i18; -import 'package:stackwallet/models/isar/stack_theme.dart' as _i27; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart' + as _i16; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i19; +import 'package:stackwallet/models/isar/stack_theme.dart' as _i28; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i10; -import 'package:stackwallet/models/signing_data.dart' as _i31; +import 'package:stackwallet/models/signing_data.dart' as _i32; import 'package:stackwallet/networking/http.dart' as _i7; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i29; -import 'package:stackwallet/services/coins/coin_service.dart' as _i20; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i30; +import 'package:stackwallet/services/coins/coin_service.dart' as _i21; import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i9; -import 'package:stackwallet/services/wallets.dart' as _i21; +import 'package:stackwallet/services/wallets.dart' as _i22; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/themes/theme_service.dart' as _i26; +import 'package:stackwallet/themes/theme_service.dart' as _i27; import 'package:stackwallet/utilities/amount/amount.dart' as _i15; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i22; -import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i30; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i23; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i31; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' - as _i32; -import 'package:stackwallet/utilities/prefs.dart' as _i24; -import 'package:tuple/tuple.dart' as _i16; + as _i33; +import 'package:stackwallet/utilities/prefs.dart' as _i25; +import 'package:tuple/tuple.dart' as _i17; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -195,9 +197,9 @@ class _FakeAmount_13 extends _i1.SmartFake implements _i15.Amount { ); } -class _FakeTuple2_14<T1, T2> extends _i1.SmartFake - implements _i16.Tuple2<T1, T2> { - _FakeTuple2_14( +class _FakeTransactionV2_14 extends _i1.SmartFake + implements _i16.TransactionV2 { + _FakeTransactionV2_14( Object parent, Invocation parentInvocation, ) : super( @@ -206,8 +208,9 @@ class _FakeTuple2_14<T1, T2> extends _i1.SmartFake ); } -class _FakeBIP32_15 extends _i1.SmartFake implements _i17.BIP32 { - _FakeBIP32_15( +class _FakeTuple2_15<T1, T2> extends _i1.SmartFake + implements _i17.Tuple2<T1, T2> { + _FakeTuple2_15( Object parent, Invocation parentInvocation, ) : super( @@ -216,8 +219,8 @@ class _FakeBIP32_15 extends _i1.SmartFake implements _i17.BIP32 { ); } -class _FakeAddress_16 extends _i1.SmartFake implements _i18.Address { - _FakeAddress_16( +class _FakeBIP32_16 extends _i1.SmartFake implements _i18.BIP32 { + _FakeBIP32_16( Object parent, Invocation parentInvocation, ) : super( @@ -226,8 +229,8 @@ class _FakeAddress_16 extends _i1.SmartFake implements _i18.Address { ); } -class _FakePaymentCode_17 extends _i1.SmartFake implements _i19.PaymentCode { - _FakePaymentCode_17( +class _FakeAddress_17 extends _i1.SmartFake implements _i19.Address { + _FakeAddress_17( Object parent, Invocation parentInvocation, ) : super( @@ -236,9 +239,19 @@ class _FakePaymentCode_17 extends _i1.SmartFake implements _i19.PaymentCode { ); } -class _FakeCoinServiceAPI_18 extends _i1.SmartFake - implements _i20.CoinServiceAPI { - _FakeCoinServiceAPI_18( +class _FakePaymentCode_18 extends _i1.SmartFake implements _i20.PaymentCode { + _FakePaymentCode_18( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_19 extends _i1.SmartFake + implements _i21.CoinServiceAPI { + _FakeCoinServiceAPI_19( Object parent, Invocation parentInvocation, ) : super( @@ -250,7 +263,7 @@ class _FakeCoinServiceAPI_18 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i21.Wallets { +class MockWallets extends _i1.Mock implements _i22.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -317,7 +330,7 @@ class MockWallets extends _i1.Mock implements _i21.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i22.Coin? coin}) => + List<String> getWalletIdsFor({required _i23.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -327,20 +340,20 @@ class MockWallets extends _i1.Mock implements _i21.Wallets { returnValue: <String>[], ) as List<String>); @override - List<_i16.Tuple2<_i22.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> + List<_i17.Tuple2<_i23.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i16.Tuple2<_i22.Coin, + returnValue: <_i17.Tuple2<_i23.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>[], ) as List< - _i16.Tuple2<_i22.Coin, + _i17.Tuple2<_i23.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i22.Coin? coin) => + _i23.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -404,17 +417,17 @@ class MockWallets extends _i1.Mock implements _i21.Wallets { returnValueForMissingStub: null, ); @override - _i23.Future<void> load(_i24.Prefs? prefs) => (super.noSuchMethod( + _i24.Future<void> load(_i25.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> loadAfterStackRestore( - _i24.Prefs? prefs, + _i24.Future<void> loadAfterStackRestore( + _i25.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -425,11 +438,11 @@ class MockWallets extends _i1.Mock implements _i21.Wallets { managers, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - void addListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -437,7 +450,7 @@ class MockWallets extends _i1.Mock implements _i21.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -463,19 +476,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i23.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i24.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i23.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i24.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i23.Future<Map<String, _i2.WalletInfo>>); + ) as _i24.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i23.Future<bool> renameWallet({ + _i24.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -490,8 +503,8 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override Map<String, _i2.WalletInfo> fetchWalletsData() => (super.noSuchMethod( Invocation.method( @@ -501,10 +514,10 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: <String, _i2.WalletInfo>{}, ) as Map<String, _i2.WalletInfo>); @override - _i23.Future<void> addExistingStackWallet({ + _i24.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i22.Coin? coin, + required _i23.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -518,13 +531,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<String?> addNewWallet({ + _i24.Future<String?> addNewWallet({ required String? name, - required _i22.Coin? coin, + required _i23.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -537,46 +550,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i24.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i23.Future<List<String>>.value(<String>[]), - ) as _i23.Future<List<String>>); + returnValue: _i24.Future<List<String>>.value(<String>[]), + ) as _i24.Future<List<String>>); @override - _i23.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i24.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i24.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i24.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> moveFavorite({ + _i24.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -589,48 +602,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i24.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i24.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<bool> isMnemonicVerified({required String? walletId}) => + _i24.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> setMnemonicVerified({required String? walletId}) => + _i24.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<int> deleteWallet( + _i24.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -642,20 +655,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override - _i23.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i24.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - void addListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -663,7 +676,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -691,7 +704,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [ThemeService]. /// /// See the documentation for Mockito's code generation for more information. -class MockThemeService extends _i1.Mock implements _i26.ThemeService { +class MockThemeService extends _i1.Mock implements _i27.ThemeService { MockThemeService() { _i1.throwOnMissingStub(this); } @@ -721,10 +734,10 @@ class MockThemeService extends _i1.Mock implements _i26.ThemeService { ), ) as _i8.MainDB); @override - List<_i27.StackTheme> get installedThemes => (super.noSuchMethod( + List<_i28.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), - returnValue: <_i27.StackTheme>[], - ) as List<_i27.StackTheme>); + returnValue: <_i28.StackTheme>[], + ) as List<_i28.StackTheme>); @override void init(_i8.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -734,85 +747,85 @@ class MockThemeService extends _i1.Mock implements _i26.ThemeService { returnValueForMissingStub: null, ); @override - _i23.Future<void> install({required _i28.Uint8List? themeArchiveData}) => + _i24.Future<void> install({required _i29.Uint8List? themeArchiveData}) => (super.noSuchMethod( Invocation.method( #install, [], {#themeArchiveData: themeArchiveData}, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> remove({required String? themeId}) => (super.noSuchMethod( + _i24.Future<void> remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( #remove, [], {#themeId: themeId}, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( + _i24.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( #checkDefaultThemesOnStartup, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<bool> verifyInstalled({required String? themeId}) => + _i24.Future<bool> verifyInstalled({required String? themeId}) => (super.noSuchMethod( Invocation.method( #verifyInstalled, [], {#themeId: themeId}, ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<List<_i26.StackThemeMetaData>> fetchThemes() => + _i24.Future<List<_i27.StackThemeMetaData>> fetchThemes() => (super.noSuchMethod( Invocation.method( #fetchThemes, [], ), - returnValue: _i23.Future<List<_i26.StackThemeMetaData>>.value( - <_i26.StackThemeMetaData>[]), - ) as _i23.Future<List<_i26.StackThemeMetaData>>); + returnValue: _i24.Future<List<_i27.StackThemeMetaData>>.value( + <_i27.StackThemeMetaData>[]), + ) as _i24.Future<List<_i27.StackThemeMetaData>>); @override - _i23.Future<_i28.Uint8List> fetchTheme( - {required _i26.StackThemeMetaData? themeMetaData}) => + _i24.Future<_i29.Uint8List> fetchTheme( + {required _i27.StackThemeMetaData? themeMetaData}) => (super.noSuchMethod( Invocation.method( #fetchTheme, [], {#themeMetaData: themeMetaData}, ), - returnValue: _i23.Future<_i28.Uint8List>.value(_i28.Uint8List(0)), - ) as _i23.Future<_i28.Uint8List>); + returnValue: _i24.Future<_i29.Uint8List>.value(_i29.Uint8List(0)), + ) as _i24.Future<_i29.Uint8List>); @override - _i27.StackTheme? getTheme({required String? themeId}) => + _i28.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( #getTheme, [], {#themeId: themeId}, - )) as _i27.StackTheme?); + )) as _i28.StackTheme?); } /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i23.Timer? _timer) => super.noSuchMethod( + set timer(_i24.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -889,74 +902,74 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { returnValue: false, ) as bool); @override - _i22.Coin get coin => (super.noSuchMethod( + _i23.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i22.Coin.bitcoin, - ) as _i22.Coin); + returnValue: _i23.Coin.bitcoin, + ) as _i23.Coin); @override - _i23.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( + _i24.Future<List<_i19.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i23.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), - ) as _i23.Future<List<_i18.UTXO>>); + returnValue: _i24.Future<List<_i19.UTXO>>.value(<_i19.UTXO>[]), + ) as _i24.Future<List<_i19.UTXO>>); @override - _i23.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( + _i24.Future<List<_i19.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i23.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), - ) as _i23.Future<List<_i18.Transaction>>); + _i24.Future<List<_i19.Transaction>>.value(<_i19.Transaction>[]), + ) as _i24.Future<List<_i19.Transaction>>); @override - _i23.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i24.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( + _i24.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( Invocation.getter(#currentChangeAddressP2PKH), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i23.Future<_i10.FeeObject> get fees => (super.noSuchMethod( + _i24.Future<_i10.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i23.Future<_i10.FeeObject>.value(_FakeFeeObject_7( + returnValue: _i24.Future<_i10.FeeObject>.value(_FakeFeeObject_7( this, Invocation.getter(#fees), )), - ) as _i23.Future<_i10.FeeObject>); + ) as _i24.Future<_i10.FeeObject>); @override - _i23.Future<int> get maxFee => (super.noSuchMethod( + _i24.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override - _i23.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i23.Future<List<String>>.value(<String>[]), - ) as _i23.Future<List<String>>); + returnValue: _i24.Future<List<String>>.value(<String>[]), + ) as _i24.Future<List<String>>); @override - _i23.Future<String?> get mnemonicString => (super.noSuchMethod( + _i24.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<int> get chainHeight => (super.noSuchMethod( + _i24.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -1028,10 +1041,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { ), ) as _i13.Balance); @override - _i23.Future<String> get xpub => (super.noSuchMethod( + _i24.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1058,26 +1071,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { ), ) as _i14.NetworkType); @override - _i23.Future<void> exit() => (super.noSuchMethod( + _i24.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i30.DerivePathType addressType({required String? address}) => + _i31.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i30.DerivePathType.bip44, - ) as _i30.DerivePathType); + returnValue: _i31.DerivePathType.bip44, + ) as _i31.DerivePathType); @override - _i23.Future<void> recoverFromMnemonic({ + _i24.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -1096,47 +1109,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { #height: height, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i24.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i24.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i24.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> refresh() => (super.noSuchMethod( + _i24.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<Map<String, dynamic>> prepareSend({ + _i24.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -1152,26 +1165,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -1189,35 +1202,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future<void> initializeNew( + _i24.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> initializeExisting() => (super.noSuchMethod( + _i24.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i24.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1227,70 +1240,70 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { returnValue: false, ) as bool); @override - _i23.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i11.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i24.Future<_i11.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), returnValue: - _i23.Future<_i11.ElectrumXNode>.value(_FakeElectrumXNode_12( + _i24.Future<_i11.ElectrumXNode>.value(_FakeElectrumXNode_12( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i23.Future<_i11.ElectrumXNode>); + ) as _i24.Future<_i11.ElectrumXNode>); @override - _i23.Future<List<Map<String, dynamic>>> fastFetch( + _i24.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i23.Future<List<Map<String, dynamic>>>.value( + returnValue: _i24.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i23.Future<List<Map<String, dynamic>>>); + ) as _i24.Future<List<Map<String, dynamic>>>); @override - _i23.Future<int> getTxCount({required String? address}) => + _i24.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override - _i23.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i24.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> checkCurrentChangeAddressesForTransactions() => + _i24.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1316,7 +1329,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { required bool? isSendAll, int? satsPerVByte, int? additionalOutputs = 0, - List<_i18.UTXO>? utxos, + List<_i19.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1333,19 +1346,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { }, )); @override - _i23.Future<List<_i31.SigningData>> fetchBuildTxData( - List<_i18.UTXO>? utxosToUse) => + _i24.Future<List<_i32.SigningData>> fetchBuildTxData( + List<_i19.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i23.Future<List<_i31.SigningData>>.value(<_i31.SigningData>[]), - ) as _i23.Future<List<_i31.SigningData>>); + _i24.Future<List<_i32.SigningData>>.value(<_i32.SigningData>[]), + ) as _i24.Future<List<_i32.SigningData>>); @override - _i23.Future<Map<String, dynamic>> buildTransaction({ - required List<_i31.SigningData>? utxoSigningData, + _i24.Future<Map<String, dynamic>> buildTransaction({ + required List<_i32.SigningData>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, }) => @@ -1360,10 +1373,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<void> fullRescan( + _i24.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1375,11 +1388,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i15.Amount> estimateFeeFor( + _i24.Future<_i15.Amount> estimateFeeFor( _i15.Amount? amount, int? feeRate, ) => @@ -1391,7 +1404,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { feeRate, ], ), - returnValue: _i23.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #estimateFeeFor, @@ -1401,7 +1414,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { ], ), )), - ) as _i23.Future<_i15.Amount>); + ) as _i24.Future<_i15.Amount>); @override _i15.Amount roughFeeEstimate( int? inputCount, @@ -1430,32 +1443,32 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { ), ) as _i15.Amount); @override - _i23.Future<_i15.Amount> sweepAllEstimate(int? feeRate) => + _i24.Future<_i15.Amount> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i23.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #sweepAllEstimate, [feeRate], ), )), - ) as _i23.Future<_i15.Amount>); + ) as _i24.Future<_i15.Amount>); @override - _i23.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override void initCache( String? walletId, - _i22.Coin? coin, + _i23.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1468,14 +1481,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i24.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1485,14 +1498,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { returnValue: 0, ) as int); @override - _i23.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i24.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1502,15 +1515,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { returnValue: false, ) as bool); @override - _i23.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i24.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override _i13.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1526,15 +1539,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { ), ) as _i13.Balance); @override - _i23.Future<void> updateCachedBalance(_i13.Balance? balance) => + _i24.Future<void> updateCachedBalance(_i13.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override _i13.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1550,15 +1563,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { ), ) as _i13.Balance); @override - _i23.Future<void> updateCachedBalanceSecondary(_i13.Balance? balance) => + _i24.Future<void> updateCachedBalanceSecondary(_i13.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override List<String> getWalletTokenContractAddresses() => (super.noSuchMethod( Invocation.method( @@ -1568,16 +1581,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { returnValue: <String>[], ) as List<String>); @override - _i23.Future<void> updateWalletTokenContractAddresses( + _i24.Future<void> updateWalletTokenContractAddresses( List<String>? contractAddresses) => (super.noSuchMethod( Invocation.method( #updateWalletTokenContractAddresses, [contractAddresses], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override void initWalletDB({_i8.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1588,11 +1601,45 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>> parseTransaction( + _i24.Future<_i16.TransactionV2> getTransaction( + String? txHash, + _i23.Coin? coin, + String? walletId, + _i12.CachedElectrumX? cachedElectrumX, [ + String? debugTitle, + ]) => + (super.noSuchMethod( + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + returnValue: + _i24.Future<_i16.TransactionV2>.value(_FakeTransactionV2_14( + this, + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + )), + ) as _i24.Future<_i16.TransactionV2>); + @override + _i24.Future<_i17.Tuple2<_i19.Transaction, _i19.Address>> parseTransaction( Map<String, dynamic>? txData, dynamic electrumxClient, - List<_i18.Address>? myAddresses, - _i22.Coin? coin, + List<_i19.Address>? myAddresses, + _i23.Coin? coin, int? minConfirms, String? walletId, ) => @@ -1609,8 +1656,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { ], ), returnValue: - _i23.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>.value( - _FakeTuple2_14<_i18.Transaction, _i18.Address>( + _i24.Future<_i17.Tuple2<_i19.Transaction, _i19.Address>>.value( + _FakeTuple2_15<_i19.Transaction, _i19.Address>( this, Invocation.method( #parseTransaction, @@ -1624,37 +1671,37 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { ], ), )), - ) as _i23.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>); + ) as _i24.Future<_i17.Tuple2<_i19.Transaction, _i19.Address>>); @override void initPaynymWalletInterface({ required String? walletId, required String? walletName, required _i14.NetworkType? network, - required _i22.Coin? coin, + required _i23.Coin? coin, required _i8.MainDB? db, required _i11.ElectrumX? electrumXClient, - required _i32.SecureStorageInterface? secureStorage, + required _i33.SecureStorageInterface? secureStorage, required int? dustLimit, required int? dustLimitP2PKH, required int? minConfirms, - required _i23.Future<String?> Function()? getMnemonicString, - required _i23.Future<String?> Function()? getMnemonicPassphrase, - required _i23.Future<int> Function()? getChainHeight, - required _i23.Future<String> Function()? getCurrentChangeAddress, + required _i24.Future<String?> Function()? getMnemonicString, + required _i24.Future<String?> Function()? getMnemonicPassphrase, + required _i24.Future<int> Function()? getChainHeight, + required _i24.Future<String> Function()? getCurrentChangeAddress, required int Function({ required int feeRatePerKB, required int vSize, })? estimateTxFee, - required _i23.Future<Map<String, dynamic>> Function({ + required _i24.Future<Map<String, dynamic>> Function({ required String address, required _i15.Amount amount, Map<String, dynamic>? args, })? prepareSend, - required _i23.Future<int> Function({required String address})? getTxCount, - required _i23.Future<List<_i31.SigningData>> Function(List<_i18.UTXO>)? + required _i24.Future<int> Function({required String address})? getTxCount, + required _i24.Future<List<_i32.SigningData>> Function(List<_i19.UTXO>)? fetchBuildTxData, - required _i23.Future<void> Function()? refresh, - required _i23.Future<void> Function()? checkChangeAddressForTransactions, + required _i24.Future<void> Function()? refresh, + required _i24.Future<void> Function()? checkChangeAddressForTransactions, }) => super.noSuchMethod( Invocation.method( @@ -1687,21 +1734,21 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future<_i17.BIP32> getBip47BaseNode() => (super.noSuchMethod( + _i24.Future<_i18.BIP32> getBip47BaseNode() => (super.noSuchMethod( Invocation.method( #getBip47BaseNode, [], ), - returnValue: _i23.Future<_i17.BIP32>.value(_FakeBIP32_15( + returnValue: _i24.Future<_i18.BIP32>.value(_FakeBIP32_16( this, Invocation.method( #getBip47BaseNode, [], ), )), - ) as _i23.Future<_i17.BIP32>); + ) as _i24.Future<_i18.BIP32>); @override - _i23.Future<_i28.Uint8List> getPrivateKeyForPaynymReceivingAddress({ + _i24.Future<_i29.Uint8List> getPrivateKeyForPaynymReceivingAddress({ required String? paymentCodeString, required int? index, }) => @@ -1714,11 +1761,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { #index: index, }, ), - returnValue: _i23.Future<_i28.Uint8List>.value(_i28.Uint8List(0)), - ) as _i23.Future<_i28.Uint8List>); + returnValue: _i24.Future<_i29.Uint8List>.value(_i29.Uint8List(0)), + ) as _i24.Future<_i29.Uint8List>); @override - _i23.Future<_i18.Address> currentReceivingPaynymAddress({ - required _i19.PaymentCode? sender, + _i24.Future<_i19.Address> currentReceivingPaynymAddress({ + required _i20.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1730,7 +1777,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i23.Future<_i18.Address>.value(_FakeAddress_16( + returnValue: _i24.Future<_i19.Address>.value(_FakeAddress_17( this, Invocation.method( #currentReceivingPaynymAddress, @@ -1741,10 +1788,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { }, ), )), - ) as _i23.Future<_i18.Address>); + ) as _i24.Future<_i19.Address>); @override - _i23.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ - required _i19.PaymentCode? sender, + _i24.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ + required _i20.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1756,42 +1803,42 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => + _i24.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkAllCurrentReceivingPaynymAddressesForTransactions, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i17.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( + _i24.Future<_i18.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( Invocation.method( #deriveNotificationBip32Node, [], ), - returnValue: _i23.Future<_i17.BIP32>.value(_FakeBIP32_15( + returnValue: _i24.Future<_i18.BIP32>.value(_FakeBIP32_16( this, Invocation.method( #deriveNotificationBip32Node, [], ), )), - ) as _i23.Future<_i17.BIP32>); + ) as _i24.Future<_i18.BIP32>); @override - _i23.Future<_i19.PaymentCode> getPaymentCode({required bool? isSegwit}) => + _i24.Future<_i20.PaymentCode> getPaymentCode({required bool? isSegwit}) => (super.noSuchMethod( Invocation.method( #getPaymentCode, [], {#isSegwit: isSegwit}, ), - returnValue: _i23.Future<_i19.PaymentCode>.value(_FakePaymentCode_17( + returnValue: _i24.Future<_i20.PaymentCode>.value(_FakePaymentCode_18( this, Invocation.method( #getPaymentCode, @@ -1799,28 +1846,28 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { {#isSegwit: isSegwit}, ), )), - ) as _i23.Future<_i19.PaymentCode>); + ) as _i24.Future<_i20.PaymentCode>); @override - _i23.Future<_i28.Uint8List> signWithNotificationKey(_i28.Uint8List? data) => + _i24.Future<_i29.Uint8List> signWithNotificationKey(_i29.Uint8List? data) => (super.noSuchMethod( Invocation.method( #signWithNotificationKey, [data], ), - returnValue: _i23.Future<_i28.Uint8List>.value(_i28.Uint8List(0)), - ) as _i23.Future<_i28.Uint8List>); + returnValue: _i24.Future<_i29.Uint8List>.value(_i29.Uint8List(0)), + ) as _i24.Future<_i29.Uint8List>); @override - _i23.Future<String> signStringWithNotificationKey(String? data) => + _i24.Future<String> signStringWithNotificationKey(String? data) => (super.noSuchMethod( Invocation.method( #signStringWithNotificationKey, [data], ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<Map<String, dynamic>> preparePaymentCodeSend({ - required _i19.PaymentCode? paymentCode, + _i24.Future<Map<String, dynamic>> preparePaymentCodeSend({ + required _i20.PaymentCode? paymentCode, required bool? isSegwit, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -1837,13 +1884,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<_i18.Address> nextUnusedSendAddressFrom({ - required _i19.PaymentCode? pCode, + _i24.Future<_i19.Address> nextUnusedSendAddressFrom({ + required _i20.PaymentCode? pCode, required bool? isSegwit, - required _i17.BIP32? privateKeyNode, + required _i18.BIP32? privateKeyNode, int? startIndex = 0, }) => (super.noSuchMethod( @@ -1857,7 +1904,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { #startIndex: startIndex, }, ), - returnValue: _i23.Future<_i18.Address>.value(_FakeAddress_16( + returnValue: _i24.Future<_i19.Address>.value(_FakeAddress_17( this, Invocation.method( #nextUnusedSendAddressFrom, @@ -1870,13 +1917,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { }, ), )), - ) as _i23.Future<_i18.Address>); + ) as _i24.Future<_i19.Address>); @override - _i23.Future<Map<String, dynamic>> prepareNotificationTx({ + _i24.Future<Map<String, dynamic>> prepareNotificationTx({ required int? selectedTxFeeRate, required String? targetPaymentCodeString, int? additionalOutputs = 0, - List<_i18.UTXO>? utxos, + List<_i19.UTXO>? utxos, }) => (super.noSuchMethod( Invocation.method( @@ -1890,10 +1937,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<String> broadcastNotificationTx( + _i24.Future<String> broadcastNotificationTx( {required Map<String, dynamic>? preparedTx}) => (super.noSuchMethod( Invocation.method( @@ -1901,62 +1948,62 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { [], {#preparedTx: preparedTx}, ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<bool> hasConnected(String? paymentCodeString) => + _i24.Future<bool> hasConnected(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #hasConnected, [paymentCodeString], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransaction( - {required _i18.Transaction? transaction}) => + _i24.Future<_i20.PaymentCode?> unBlindedPaymentCodeFromTransaction( + {required _i19.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransaction, [], {#transaction: transaction}, ), - returnValue: _i23.Future<_i19.PaymentCode?>.value(), - ) as _i23.Future<_i19.PaymentCode?>); + returnValue: _i24.Future<_i20.PaymentCode?>.value(), + ) as _i24.Future<_i20.PaymentCode?>); @override - _i23.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( - {required _i18.Transaction? transaction}) => + _i24.Future<_i20.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( + {required _i19.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransactionBad, [], {#transaction: transaction}, ), - returnValue: _i23.Future<_i19.PaymentCode?>.value(), - ) as _i23.Future<_i19.PaymentCode?>); + returnValue: _i24.Future<_i20.PaymentCode?>.value(), + ) as _i24.Future<_i20.PaymentCode?>); @override - _i23.Future<List<_i19.PaymentCode>> + _i24.Future<List<_i20.PaymentCode>> getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod( Invocation.method( #getAllPaymentCodesFromNotificationTransactions, [], ), returnValue: - _i23.Future<List<_i19.PaymentCode>>.value(<_i19.PaymentCode>[]), - ) as _i23.Future<List<_i19.PaymentCode>>); + _i24.Future<List<_i20.PaymentCode>>.value(<_i20.PaymentCode>[]), + ) as _i24.Future<List<_i20.PaymentCode>>); @override - _i23.Future<void> checkForNotificationTransactionsTo( + _i24.Future<void> checkForNotificationTransactionsTo( Set<String>? otherCodeStrings) => (super.noSuchMethod( Invocation.method( #checkForNotificationTransactionsTo, [otherCodeStrings], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> restoreAllHistory({ + _i24.Future<void> restoreAllHistory({ required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, required Set<String>? paymentCodeStrings, @@ -1971,12 +2018,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { #paymentCodeStrings: paymentCodeStrings, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> restoreHistoryWith({ - required _i19.PaymentCode? other, + _i24.Future<void> restoreHistoryWith({ + required _i20.PaymentCode? other, required bool? checkSegwitAsWell, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1992,58 +2039,58 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { #maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i18.Address> getMyNotificationAddress() => (super.noSuchMethod( + _i24.Future<_i19.Address> getMyNotificationAddress() => (super.noSuchMethod( Invocation.method( #getMyNotificationAddress, [], ), - returnValue: _i23.Future<_i18.Address>.value(_FakeAddress_16( + returnValue: _i24.Future<_i19.Address>.value(_FakeAddress_17( this, Invocation.method( #getMyNotificationAddress, [], ), )), - ) as _i23.Future<_i18.Address>); + ) as _i24.Future<_i19.Address>); @override - _i23.Future<List<String>> lookupKey(String? paymentCodeString) => + _i24.Future<List<String>> lookupKey(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #lookupKey, [paymentCodeString], ), - returnValue: _i23.Future<List<String>>.value(<String>[]), - ) as _i23.Future<List<String>>); + returnValue: _i24.Future<List<String>>.value(<String>[]), + ) as _i24.Future<List<String>>); @override - _i23.Future<String?> paymentCodeStringByKey(String? key) => + _i24.Future<String?> paymentCodeStringByKey(String? key) => (super.noSuchMethod( Invocation.method( #paymentCodeStringByKey, [key], ), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<String> storeCode(String? paymentCodeString) => + _i24.Future<String> storeCode(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #storeCode, [paymentCodeString], ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override void initCoinControlInterface({ required String? walletId, required String? walletName, - required _i22.Coin? coin, + required _i23.Coin? coin, required _i8.MainDB? db, - required _i23.Future<int> Function()? getChainHeight, - required _i23.Future<void> Function(_i13.Balance)? refreshedBalanceCallback, + required _i24.Future<int> Function()? getChainHeight, + required _i24.Future<void> Function(_i13.Balance)? refreshedBalanceCallback, }) => super.noSuchMethod( Invocation.method( @@ -2061,16 +2108,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i29.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future<void> refreshBalance({bool? notify = false}) => + _i24.Future<void> refreshBalance({bool? notify = false}) => (super.noSuchMethod( Invocation.method( #refreshBalance, [], {#notify: notify}, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); } /// A class which mocks [Manager]. @@ -2091,23 +2138,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i20.CoinServiceAPI get wallet => (super.noSuchMethod( + _i21.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_18( + returnValue: _FakeCoinServiceAPI_19( this, Invocation.getter(#wallet), ), - ) as _i20.CoinServiceAPI); + ) as _i21.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i22.Coin get coin => (super.noSuchMethod( + _i23.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i22.Coin.bitcoin, - ) as _i22.Coin); + returnValue: _i23.Coin.bitcoin, + ) as _i23.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2140,23 +2187,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i23.Future<_i10.FeeObject> get fees => (super.noSuchMethod( + _i24.Future<_i10.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i23.Future<_i10.FeeObject>.value(_FakeFeeObject_7( + returnValue: _i24.Future<_i10.FeeObject>.value(_FakeFeeObject_7( this, Invocation.getter(#fees), )), - ) as _i23.Future<_i10.FeeObject>); + ) as _i24.Future<_i10.FeeObject>); @override - _i23.Future<int> get maxFee => (super.noSuchMethod( + _i24.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override - _i23.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override _i13.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2166,16 +2213,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i13.Balance); @override - _i23.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( + _i24.Future<List<_i19.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i23.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), - ) as _i23.Future<List<_i18.Transaction>>); + _i24.Future<List<_i19.Transaction>>.value(<_i19.Transaction>[]), + ) as _i24.Future<List<_i19.Transaction>>); @override - _i23.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( + _i24.Future<List<_i19.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i23.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), - ) as _i23.Future<List<_i18.UTXO>>); + returnValue: _i24.Future<List<_i19.UTXO>>.value(<_i19.UTXO>[]), + ) as _i24.Future<List<_i19.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2195,15 +2242,15 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i23.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i23.Future<List<String>>.value(<String>[]), - ) as _i23.Future<List<String>>); + returnValue: _i24.Future<List<String>>.value(<String>[]), + ) as _i24.Future<List<String>>); @override - _i23.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -2240,6 +2287,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, @@ -2250,24 +2302,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i23.Future<String> get xpub => (super.noSuchMethod( + _i24.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i23.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -2277,7 +2329,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i23.Future<Map<String, dynamic>> prepareSend({ + _i24.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -2293,27 +2345,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<void> refresh() => (super.noSuchMethod( + _i24.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2323,35 +2375,35 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i23.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> initializeNew( + _i24.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> initializeExisting() => (super.noSuchMethod( + _i24.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> recoverFromMnemonic({ + _i24.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -2370,20 +2422,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i24.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> fullRescan( + _i24.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2395,11 +2447,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i15.Amount> estimateFeeFor( + _i24.Future<_i15.Amount> estimateFeeFor( _i15.Amount? amount, int? feeRate, ) => @@ -2411,7 +2463,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i23.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #estimateFeeFor, @@ -2421,26 +2473,26 @@ class MockManager extends _i1.Mock implements _i6.Manager { ], ), )), - ) as _i23.Future<_i15.Amount>); + ) as _i24.Future<_i15.Amount>); @override - _i23.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> resetRescanOnOpen() => (super.noSuchMethod( + _i24.Future<void> resetRescanOnOpen() => (super.noSuchMethod( Invocation.method( #resetRescanOnOpen, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - void addListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2448,7 +2500,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2468,7 +2520,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -2479,10 +2531,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i22.Coin get coin => (super.noSuchMethod( + _i23.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i22.Coin.bitcoin, - ) as _i22.Coin); + returnValue: _i23.Coin.bitcoin, + ) as _i23.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2515,23 +2567,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i23.Future<_i10.FeeObject> get fees => (super.noSuchMethod( + _i24.Future<_i10.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i23.Future<_i10.FeeObject>.value(_FakeFeeObject_7( + returnValue: _i24.Future<_i10.FeeObject>.value(_FakeFeeObject_7( this, Invocation.getter(#fees), )), - ) as _i23.Future<_i10.FeeObject>); + ) as _i24.Future<_i10.FeeObject>); @override - _i23.Future<int> get maxFee => (super.noSuchMethod( + _i24.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override - _i23.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override _i13.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2541,16 +2593,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { ), ) as _i13.Balance); @override - _i23.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( + _i24.Future<List<_i19.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i23.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), - ) as _i23.Future<List<_i18.Transaction>>); + _i24.Future<List<_i19.Transaction>>.value(<_i19.Transaction>[]), + ) as _i24.Future<List<_i19.Transaction>>); @override - _i23.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( + _i24.Future<List<_i19.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i23.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), - ) as _i23.Future<List<_i18.UTXO>>); + returnValue: _i24.Future<List<_i19.UTXO>>.value(<_i19.UTXO>[]), + ) as _i24.Future<List<_i19.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2570,20 +2622,20 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValue: '', ) as String); @override - _i23.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i23.Future<List<String>>.value(<String>[]), - ) as _i23.Future<List<String>>); + returnValue: _i24.Future<List<String>>.value(<String>[]), + ) as _i24.Future<List<String>>); @override - _i23.Future<String?> get mnemonicString => (super.noSuchMethod( + _i24.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -2600,7 +2652,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValue: 0, ) as int); @override - _i23.Future<Map<String, dynamic>> prepareSend({ + _i24.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -2616,36 +2668,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<void> refresh() => (super.noSuchMethod( + _i24.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2655,15 +2707,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValue: false, ) as bool); @override - _i23.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> recoverFromMnemonic({ + _i24.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -2682,40 +2734,40 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { #height: height, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> initializeNew( + _i24.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> initializeExisting() => (super.noSuchMethod( + _i24.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> exit() => (super.noSuchMethod( + _i24.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> fullRescan( + _i24.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2727,11 +2779,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i15.Amount> estimateFeeFor( + _i24.Future<_i15.Amount> estimateFeeFor( _i15.Amount? amount, int? feeRate, ) => @@ -2743,7 +2795,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { feeRate, ], ), - returnValue: _i23.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #estimateFeeFor, @@ -2753,23 +2805,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { ], ), )), - ) as _i23.Future<_i15.Amount>); + ) as _i24.Future<_i15.Amount>); @override - _i23.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i24.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); } diff --git a/test/widget_tests/transaction_card_test.mocks.dart b/test/widget_tests/transaction_card_test.mocks.dart index 5ef7ef5a1..23748d274 100644 --- a/test/widget_tests/transaction_card_test.mocks.dart +++ b/test/widget_tests/transaction_card_test.mocks.dart @@ -3,45 +3,47 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i20; -import 'dart:typed_data' as _i35; -import 'dart:ui' as _i22; +import 'dart:async' as _i21; +import 'dart:typed_data' as _i36; +import 'dart:ui' as _i23; -import 'package:decimal/decimal.dart' as _i31; +import 'package:decimal/decimal.dart' as _i32; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; -import 'package:isar/isar.dart' as _i17; +import 'package:isar/isar.dart' as _i18; import 'package:mockito/mockito.dart' as _i1; import 'package:stackwallet/db/isar/main_db.dart' as _i14; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i13; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i12; import 'package:stackwallet/models/balance.dart' as _i9; -import 'package:stackwallet/models/isar/models/block_explorer.dart' as _i37; -import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i36; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i23; -import 'package:stackwallet/models/isar/stack_theme.dart' as _i34; +import 'package:stackwallet/models/isar/models/block_explorer.dart' as _i38; +import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i37; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i24; +import 'package:stackwallet/models/isar/stack_theme.dart' as _i35; import 'package:stackwallet/models/models.dart' as _i8; -import 'package:stackwallet/models/signing_data.dart' as _i25; -import 'package:stackwallet/networking/http.dart' as _i16; +import 'package:stackwallet/models/signing_data.dart' as _i26; +import 'package:stackwallet/networking/http.dart' as _i17; import 'package:stackwallet/services/coins/coin_service.dart' as _i7; -import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as _i24; +import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as _i25; import 'package:stackwallet/services/coins/manager.dart' as _i6; -import 'package:stackwallet/services/locale_service.dart' as _i26; +import 'package:stackwallet/services/locale_service.dart' as _i27; +import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart' + as _i15; import 'package:stackwallet/services/node_service.dart' as _i3; -import 'package:stackwallet/services/notes_service.dart' as _i32; -import 'package:stackwallet/services/price_service.dart' as _i30; +import 'package:stackwallet/services/notes_service.dart' as _i33; +import 'package:stackwallet/services/price_service.dart' as _i31; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i11; -import 'package:stackwallet/services/wallets.dart' as _i18; +import 'package:stackwallet/services/wallets.dart' as _i19; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/themes/theme_service.dart' as _i33; +import 'package:stackwallet/themes/theme_service.dart' as _i34; import 'package:stackwallet/utilities/amount/amount.dart' as _i10; -import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i29; -import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i28; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i19; -import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i27; -import 'package:stackwallet/utilities/prefs.dart' as _i21; -import 'package:tuple/tuple.dart' as _i15; +import 'package:stackwallet/utilities/amount/amount_unit.dart' as _i30; +import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i29; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i20; +import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i28; +import 'package:stackwallet/utilities/prefs.dart' as _i22; +import 'package:tuple/tuple.dart' as _i16; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -179,8 +181,8 @@ class _FakeMainDB_11 extends _i1.SmartFake implements _i14.MainDB { ); } -class _FakeDuration_12 extends _i1.SmartFake implements Duration { - _FakeDuration_12( +class _FakeFusionInfo_12 extends _i1.SmartFake implements _i15.FusionInfo { + _FakeFusionInfo_12( Object parent, Invocation parentInvocation, ) : super( @@ -189,9 +191,8 @@ class _FakeDuration_12 extends _i1.SmartFake implements Duration { ); } -class _FakeTuple2_13<T1, T2> extends _i1.SmartFake - implements _i15.Tuple2<T1, T2> { - _FakeTuple2_13( +class _FakeDuration_13 extends _i1.SmartFake implements Duration { + _FakeDuration_13( Object parent, Invocation parentInvocation, ) : super( @@ -200,8 +201,9 @@ class _FakeTuple2_13<T1, T2> extends _i1.SmartFake ); } -class _FakeHTTP_14 extends _i1.SmartFake implements _i16.HTTP { - _FakeHTTP_14( +class _FakeTuple2_14<T1, T2> extends _i1.SmartFake + implements _i16.Tuple2<T1, T2> { + _FakeTuple2_14( Object parent, Invocation parentInvocation, ) : super( @@ -210,8 +212,8 @@ class _FakeHTTP_14 extends _i1.SmartFake implements _i16.HTTP { ); } -class _FakeIsar_15 extends _i1.SmartFake implements _i17.Isar { - _FakeIsar_15( +class _FakeHTTP_15 extends _i1.SmartFake implements _i17.HTTP { + _FakeHTTP_15( Object parent, Invocation parentInvocation, ) : super( @@ -220,9 +222,19 @@ class _FakeIsar_15 extends _i1.SmartFake implements _i17.Isar { ); } -class _FakeQueryBuilder_16<OBJ, R, S> extends _i1.SmartFake - implements _i17.QueryBuilder<OBJ, R, S> { - _FakeQueryBuilder_16( +class _FakeIsar_16 extends _i1.SmartFake implements _i18.Isar { + _FakeIsar_16( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeQueryBuilder_17<OBJ, R, S> extends _i1.SmartFake + implements _i18.QueryBuilder<OBJ, R, S> { + _FakeQueryBuilder_17( Object parent, Invocation parentInvocation, ) : super( @@ -234,7 +246,7 @@ class _FakeQueryBuilder_16<OBJ, R, S> extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i18.Wallets { +class MockWallets extends _i1.Mock implements _i19.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -301,7 +313,7 @@ class MockWallets extends _i1.Mock implements _i18.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i19.Coin? coin}) => + List<String> getWalletIdsFor({required _i20.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -311,20 +323,20 @@ class MockWallets extends _i1.Mock implements _i18.Wallets { returnValue: <String>[], ) as List<String>); @override - List<_i15.Tuple2<_i19.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> + List<_i16.Tuple2<_i20.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i15.Tuple2<_i19.Coin, + returnValue: <_i16.Tuple2<_i20.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>[], ) as List< - _i15.Tuple2<_i19.Coin, + _i16.Tuple2<_i20.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i19.Coin? coin) => + _i20.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -388,17 +400,17 @@ class MockWallets extends _i1.Mock implements _i18.Wallets { returnValueForMissingStub: null, ); @override - _i20.Future<void> load(_i21.Prefs? prefs) => (super.noSuchMethod( + _i21.Future<void> load(_i22.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> loadAfterStackRestore( - _i21.Prefs? prefs, + _i21.Future<void> loadAfterStackRestore( + _i22.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -409,11 +421,11 @@ class MockWallets extends _i1.Mock implements _i18.Wallets { managers, ], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - void addListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -421,7 +433,7 @@ class MockWallets extends _i1.Mock implements _i18.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -473,10 +485,10 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i19.Coin get coin => (super.noSuchMethod( + _i20.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i19.Coin.bitcoin, - ) as _i19.Coin); + returnValue: _i20.Coin.bitcoin, + ) as _i20.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -509,23 +521,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i20.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i21.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i20.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i21.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i20.Future<_i8.FeeObject>); + ) as _i21.Future<_i8.FeeObject>); @override - _i20.Future<int> get maxFee => (super.noSuchMethod( + _i21.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - _i20.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i21.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override _i9.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -535,16 +547,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i9.Balance); @override - _i20.Future<List<_i23.Transaction>> get transactions => (super.noSuchMethod( + _i21.Future<List<_i24.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i20.Future<List<_i23.Transaction>>.value(<_i23.Transaction>[]), - ) as _i20.Future<List<_i23.Transaction>>); + _i21.Future<List<_i24.Transaction>>.value(<_i24.Transaction>[]), + ) as _i21.Future<List<_i24.Transaction>>); @override - _i20.Future<List<_i23.UTXO>> get utxos => (super.noSuchMethod( + _i21.Future<List<_i24.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i20.Future<List<_i23.UTXO>>.value(<_i23.UTXO>[]), - ) as _i20.Future<List<_i23.UTXO>>); + returnValue: _i21.Future<List<_i24.UTXO>>.value(<_i24.UTXO>[]), + ) as _i21.Future<List<_i24.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -564,15 +576,15 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i20.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i21.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i20.Future<List<String>>.value(<String>[]), - ) as _i20.Future<List<String>>); + returnValue: _i21.Future<List<String>>.value(<String>[]), + ) as _i21.Future<List<String>>); @override - _i20.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i21.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i20.Future<String?>.value(), - ) as _i20.Future<String?>); + returnValue: _i21.Future<String?>.value(), + ) as _i21.Future<String?>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -609,6 +621,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, @@ -619,24 +636,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i20.Future<String> get xpub => (super.noSuchMethod( + _i21.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i20.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i21.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -646,7 +663,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i20.Future<Map<String, dynamic>> prepareSend({ + _i21.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i10.Amount? amount, Map<String, dynamic>? args, @@ -662,27 +679,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i20.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i20.Future<Map<String, dynamic>>); + _i21.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i21.Future<Map<String, dynamic>>); @override - _i20.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i21.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override - _i20.Future<void> refresh() => (super.noSuchMethod( + _i21.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -692,35 +709,35 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i20.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i21.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i20.Future<void> initializeNew( + _i21.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> initializeExisting() => (super.noSuchMethod( + _i21.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> recoverFromMnemonic({ + _i21.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -739,20 +756,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i21.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> fullRescan( + _i21.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -764,11 +781,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<_i10.Amount> estimateFeeFor( + _i21.Future<_i10.Amount> estimateFeeFor( _i10.Amount? amount, int? feeRate, ) => @@ -780,7 +797,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i20.Future<_i10.Amount>.value(_FakeAmount_7( + returnValue: _i21.Future<_i10.Amount>.value(_FakeAmount_7( this, Invocation.method( #estimateFeeFor, @@ -790,26 +807,26 @@ class MockManager extends _i1.Mock implements _i6.Manager { ], ), )), - ) as _i20.Future<_i10.Amount>); + ) as _i21.Future<_i10.Amount>); @override - _i20.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i21.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i20.Future<void> resetRescanOnOpen() => (super.noSuchMethod( + _i21.Future<void> resetRescanOnOpen() => (super.noSuchMethod( Invocation.method( #resetRescanOnOpen, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - void addListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -817,7 +834,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -852,10 +869,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i19.Coin get coin => (super.noSuchMethod( + _i20.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i19.Coin.bitcoin, - ) as _i19.Coin); + returnValue: _i20.Coin.bitcoin, + ) as _i20.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -888,23 +905,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i20.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i21.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i20.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i21.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i20.Future<_i8.FeeObject>); + ) as _i21.Future<_i8.FeeObject>); @override - _i20.Future<int> get maxFee => (super.noSuchMethod( + _i21.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - _i20.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i21.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override _i9.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -914,16 +931,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { ), ) as _i9.Balance); @override - _i20.Future<List<_i23.Transaction>> get transactions => (super.noSuchMethod( + _i21.Future<List<_i24.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i20.Future<List<_i23.Transaction>>.value(<_i23.Transaction>[]), - ) as _i20.Future<List<_i23.Transaction>>); + _i21.Future<List<_i24.Transaction>>.value(<_i24.Transaction>[]), + ) as _i21.Future<List<_i24.Transaction>>); @override - _i20.Future<List<_i23.UTXO>> get utxos => (super.noSuchMethod( + _i21.Future<List<_i24.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i20.Future<List<_i23.UTXO>>.value(<_i23.UTXO>[]), - ) as _i20.Future<List<_i23.UTXO>>); + returnValue: _i21.Future<List<_i24.UTXO>>.value(<_i24.UTXO>[]), + ) as _i21.Future<List<_i24.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -943,20 +960,20 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { returnValue: '', ) as String); @override - _i20.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i21.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i20.Future<List<String>>.value(<String>[]), - ) as _i20.Future<List<String>>); + returnValue: _i21.Future<List<String>>.value(<String>[]), + ) as _i21.Future<List<String>>); @override - _i20.Future<String?> get mnemonicString => (super.noSuchMethod( + _i21.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i20.Future<String?>.value(), - ) as _i20.Future<String?>); + returnValue: _i21.Future<String?>.value(), + ) as _i21.Future<String?>); @override - _i20.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i21.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i20.Future<String?>.value(), - ) as _i20.Future<String?>); + returnValue: _i21.Future<String?>.value(), + ) as _i21.Future<String?>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -973,7 +990,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { returnValue: 0, ) as int); @override - _i20.Future<Map<String, dynamic>> prepareSend({ + _i21.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i10.Amount? amount, Map<String, dynamic>? args, @@ -989,36 +1006,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { }, ), returnValue: - _i20.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i20.Future<Map<String, dynamic>>); + _i21.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i21.Future<Map<String, dynamic>>); @override - _i20.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i21.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override - _i20.Future<void> refresh() => (super.noSuchMethod( + _i21.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i21.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1028,15 +1045,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { returnValue: false, ) as bool); @override - _i20.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i21.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i20.Future<void> recoverFromMnemonic({ + _i21.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -1055,40 +1072,40 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { #height: height, }, ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> initializeNew( + _i21.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> initializeExisting() => (super.noSuchMethod( + _i21.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> exit() => (super.noSuchMethod( + _i21.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> fullRescan( + _i21.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1100,11 +1117,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<_i10.Amount> estimateFeeFor( + _i21.Future<_i10.Amount> estimateFeeFor( _i10.Amount? amount, int? feeRate, ) => @@ -1116,7 +1133,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { feeRate, ], ), - returnValue: _i20.Future<_i10.Amount>.value(_FakeAmount_7( + returnValue: _i21.Future<_i10.Amount>.value(_FakeAmount_7( this, Invocation.method( #estimateFeeFor, @@ -1126,37 +1143,37 @@ class MockCoinServiceAPI extends _i1.Mock implements _i7.CoinServiceAPI { ], ), )), - ) as _i20.Future<_i10.Amount>); + ) as _i21.Future<_i10.Amount>); @override - _i20.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i21.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i20.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i21.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); } /// A class which mocks [FiroWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { +class MockFiroWallet extends _i1.Mock implements _i25.FiroWallet { MockFiroWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i20.Timer? _timer) => super.noSuchMethod( + set timer(_i21.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -1246,48 +1263,48 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { returnValue: false, ) as bool); @override - _i19.Coin get coin => (super.noSuchMethod( + _i20.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i19.Coin.bitcoin, - ) as _i19.Coin); + returnValue: _i20.Coin.bitcoin, + ) as _i20.Coin); @override - _i20.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i21.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i20.Future<List<String>>.value(<String>[]), - ) as _i20.Future<List<String>>); + returnValue: _i21.Future<List<String>>.value(<String>[]), + ) as _i21.Future<List<String>>); @override - _i20.Future<String?> get mnemonicString => (super.noSuchMethod( + _i21.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i20.Future<String?>.value(), - ) as _i20.Future<String?>); + returnValue: _i21.Future<String?>.value(), + ) as _i21.Future<String?>); @override - _i20.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i21.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i20.Future<String?>.value(), - ) as _i20.Future<String?>); + returnValue: _i21.Future<String?>.value(), + ) as _i21.Future<String?>); @override - _i20.Future<int> get maxFee => (super.noSuchMethod( + _i21.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - _i20.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i21.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i20.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i21.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i20.Future<_i8.FeeObject>); + ) as _i21.Future<_i8.FeeObject>); @override - _i20.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i21.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override - _i20.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i21.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override String get walletName => (super.noSuchMethod( Invocation.getter(#walletName), @@ -1343,10 +1360,10 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { returnValue: false, ) as bool); @override - _i20.Future<int> get chainHeight => (super.noSuchMethod( + _i21.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -1369,21 +1386,21 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { ), ) as _i9.Balance); @override - _i20.Future<List<_i23.UTXO>> get utxos => (super.noSuchMethod( + _i21.Future<List<_i24.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i20.Future<List<_i23.UTXO>>.value(<_i23.UTXO>[]), - ) as _i20.Future<List<_i23.UTXO>>); + returnValue: _i21.Future<List<_i24.UTXO>>.value(<_i24.UTXO>[]), + ) as _i21.Future<List<_i24.UTXO>>); @override - _i20.Future<List<_i23.Transaction>> get transactions => (super.noSuchMethod( + _i21.Future<List<_i24.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i20.Future<List<_i23.Transaction>>.value(<_i23.Transaction>[]), - ) as _i20.Future<List<_i23.Transaction>>); + _i21.Future<List<_i24.Transaction>>.value(<_i24.Transaction>[]), + ) as _i21.Future<List<_i24.Transaction>>); @override - _i20.Future<String> get xpub => (super.noSuchMethod( + _i21.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1410,23 +1427,23 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { returnValue: false, ) as bool); @override - _i20.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i21.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i21.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -1444,7 +1461,7 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { returnValueForMissingStub: null, ); @override - _i20.Future<Map<String, dynamic>> prepareSendPublic({ + _i21.Future<Map<String, dynamic>> prepareSendPublic({ required String? address, required _i10.Amount? amount, Map<String, dynamic>? args, @@ -1460,20 +1477,20 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { }, ), returnValue: - _i20.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i20.Future<Map<String, dynamic>>); + _i21.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i21.Future<Map<String, dynamic>>); @override - _i20.Future<String> confirmSendPublic({dynamic txData}) => + _i21.Future<String> confirmSendPublic({dynamic txData}) => (super.noSuchMethod( Invocation.method( #confirmSendPublic, [], {#txData: txData}, ), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override - _i20.Future<Map<String, dynamic>> prepareSend({ + _i21.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i10.Amount? amount, Map<String, dynamic>? args, @@ -1489,18 +1506,18 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { }, ), returnValue: - _i20.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i20.Future<Map<String, dynamic>>); + _i21.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i21.Future<Map<String, dynamic>>); @override - _i20.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i21.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override int estimateTxFee({ required int? vSize, @@ -1525,7 +1542,7 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { bool? isSendAll, { int? satsPerVByte, int? additionalOutputs = 0, - List<_i23.UTXO>? utxos, + List<_i24.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1542,19 +1559,19 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { }, )); @override - _i20.Future<List<_i25.SigningData>> fetchBuildTxData( - List<_i23.UTXO>? utxosToUse) => + _i21.Future<List<_i26.SigningData>> fetchBuildTxData( + List<_i24.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i20.Future<List<_i25.SigningData>>.value(<_i25.SigningData>[]), - ) as _i20.Future<List<_i25.SigningData>>); + _i21.Future<List<_i26.SigningData>>.value(<_i26.SigningData>[]), + ) as _i21.Future<List<_i26.SigningData>>); @override - _i20.Future<Map<String, dynamic>> buildTransaction({ - required List<_i25.SigningData>? utxoSigningData, + _i21.Future<Map<String, dynamic>> buildTransaction({ + required List<_i26.SigningData>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, }) => @@ -1569,111 +1586,111 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { }, ), returnValue: - _i20.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i20.Future<Map<String, dynamic>>); + _i21.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i21.Future<Map<String, dynamic>>); @override - _i20.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i21.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> initializeNew( + _i21.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> setLelantusCoinIsarRescanRequiredDone() => + _i21.Future<void> setLelantusCoinIsarRescanRequiredDone() => (super.noSuchMethod( Invocation.method( #setLelantusCoinIsarRescanRequiredDone, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<bool> firoRescanRecovery() => (super.noSuchMethod( + _i21.Future<bool> firoRescanRecovery() => (super.noSuchMethod( Invocation.method( #firoRescanRecovery, [], ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i20.Future<void> initializeExisting() => (super.noSuchMethod( + _i21.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i21.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i20.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i21.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> refresh() => (super.noSuchMethod( + _i21.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> anonymizeAllPublicFunds() => (super.noSuchMethod( + _i21.Future<void> anonymizeAllPublicFunds() => (super.noSuchMethod( Invocation.method( #anonymizeAllPublicFunds, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<List<Map<String, dynamic>>> createMintsFromAmount(int? total) => + _i21.Future<List<Map<String, dynamic>>> createMintsFromAmount(int? total) => (super.noSuchMethod( Invocation.method( #createMintsFromAmount, [total], ), - returnValue: _i20.Future<List<Map<String, dynamic>>>.value( + returnValue: _i21.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i20.Future<List<Map<String, dynamic>>>); + ) as _i21.Future<List<Map<String, dynamic>>>); @override - _i20.Future<String> submitHexToNetwork(String? hex) => (super.noSuchMethod( + _i21.Future<String> submitHexToNetwork(String? hex) => (super.noSuchMethod( Invocation.method( #submitHexToNetwork, [hex], ), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override - _i20.Future<Map<String, dynamic>> buildMintTransaction( - List<_i23.UTXO>? utxosToUse, + _i21.Future<Map<String, dynamic>> buildMintTransaction( + List<_i24.UTXO>? utxosToUse, int? satoshisPerRecipient, List<Map<String, dynamic>>? mintsMap, ) => @@ -1687,29 +1704,29 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { ], ), returnValue: - _i20.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i20.Future<Map<String, dynamic>>); + _i21.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i21.Future<Map<String, dynamic>>); @override - _i20.Future<void> checkReceivingAddressForTransactions() => + _i21.Future<void> checkReceivingAddressForTransactions() => (super.noSuchMethod( Invocation.method( #checkReceivingAddressForTransactions, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> checkChangeAddressForTransactions() => (super.noSuchMethod( + _i21.Future<void> checkChangeAddressForTransactions() => (super.noSuchMethod( Invocation.method( #checkChangeAddressForTransactions, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> fullRescan( + _i21.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1721,11 +1738,11 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> recoverFromMnemonic({ + _i21.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -1744,74 +1761,74 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { #height: height, }, ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<Map<int, dynamic>> getSetDataMap(int? latestSetId) => + _i21.Future<Map<int, dynamic>> getSetDataMap(int? latestSetId) => (super.noSuchMethod( Invocation.method( #getSetDataMap, [latestSetId], ), - returnValue: _i20.Future<Map<int, dynamic>>.value(<int, dynamic>{}), - ) as _i20.Future<Map<int, dynamic>>); + returnValue: _i21.Future<Map<int, dynamic>>.value(<int, dynamic>{}), + ) as _i21.Future<Map<int, dynamic>>); @override - _i20.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i21.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<List<Map<String, dynamic>>> fetchAnonymitySets() => + _i21.Future<List<Map<String, dynamic>>> fetchAnonymitySets() => (super.noSuchMethod( Invocation.method( #fetchAnonymitySets, [], ), - returnValue: _i20.Future<List<Map<String, dynamic>>>.value( + returnValue: _i21.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i20.Future<List<Map<String, dynamic>>>); + ) as _i21.Future<List<Map<String, dynamic>>>); @override - _i20.Future<int> getLatestSetId() => (super.noSuchMethod( + _i21.Future<int> getLatestSetId() => (super.noSuchMethod( Invocation.method( #getLatestSetId, [], ), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - _i20.Future<List<String>> getUsedCoinSerials() => (super.noSuchMethod( + _i21.Future<List<String>> getUsedCoinSerials() => (super.noSuchMethod( Invocation.method( #getUsedCoinSerials, [], ), - returnValue: _i20.Future<List<String>>.value(<String>[]), - ) as _i20.Future<List<String>>); + returnValue: _i21.Future<List<String>>.value(<String>[]), + ) as _i21.Future<List<String>>); @override - _i20.Future<void> exit() => (super.noSuchMethod( + _i21.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<int> estimateJoinSplitFee(int? spendAmount) => + _i21.Future<int> estimateJoinSplitFee(int? spendAmount) => (super.noSuchMethod( Invocation.method( #estimateJoinSplitFee, [spendAmount], ), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - _i20.Future<_i10.Amount> estimateFeeFor( + _i21.Future<_i10.Amount> estimateFeeFor( _i10.Amount? amount, int? feeRate, ) => @@ -1823,7 +1840,7 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { feeRate, ], ), - returnValue: _i20.Future<_i10.Amount>.value(_FakeAmount_7( + returnValue: _i21.Future<_i10.Amount>.value(_FakeAmount_7( this, Invocation.method( #estimateFeeFor, @@ -1833,9 +1850,9 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { ], ), )), - ) as _i20.Future<_i10.Amount>); + ) as _i21.Future<_i10.Amount>); @override - _i20.Future<_i10.Amount> estimateFeeForPublic( + _i21.Future<_i10.Amount> estimateFeeForPublic( _i10.Amount? amount, int? feeRate, ) => @@ -1847,7 +1864,7 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { feeRate, ], ), - returnValue: _i20.Future<_i10.Amount>.value(_FakeAmount_7( + returnValue: _i21.Future<_i10.Amount>.value(_FakeAmount_7( this, Invocation.method( #estimateFeeForPublic, @@ -1857,7 +1874,7 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { ], ), )), - ) as _i20.Future<_i10.Amount>); + ) as _i21.Future<_i10.Amount>); @override _i10.Amount roughFeeEstimate( int? inputCount, @@ -1886,36 +1903,36 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { ), ) as _i10.Amount); @override - _i20.Future<_i10.Amount> sweepAllEstimate(int? feeRate) => + _i21.Future<_i10.Amount> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i20.Future<_i10.Amount>.value(_FakeAmount_7( + returnValue: _i21.Future<_i10.Amount>.value(_FakeAmount_7( this, Invocation.method( #sweepAllEstimate, [feeRate], ), )), - ) as _i20.Future<_i10.Amount>); + ) as _i21.Future<_i10.Amount>); @override - _i20.Future<List<Map<String, dynamic>>> fastFetch( + _i21.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i20.Future<List<Map<String, dynamic>>>.value( + returnValue: _i21.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i20.Future<List<Map<String, dynamic>>>); + ) as _i21.Future<List<Map<String, dynamic>>>); @override - _i20.Future<Map<_i23.Address, _i23.Transaction>> getJMintTransactions( + _i21.Future<Map<_i24.Address, _i24.Transaction>> getJMintTransactions( _i13.CachedElectrumX? cachedClient, List<String>? transactions, - _i19.Coin? coin, + _i20.Coin? coin, ) => (super.noSuchMethod( Invocation.method( @@ -1926,17 +1943,17 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { coin, ], ), - returnValue: _i20.Future<Map<_i23.Address, _i23.Transaction>>.value( - <_i23.Address, _i23.Transaction>{}), - ) as _i20.Future<Map<_i23.Address, _i23.Transaction>>); + returnValue: _i21.Future<Map<_i24.Address, _i24.Transaction>>.value( + <_i24.Address, _i24.Transaction>{}), + ) as _i21.Future<Map<_i24.Address, _i24.Transaction>>); @override - _i20.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i21.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override _i10.Amount availablePrivateBalance() => (super.noSuchMethod( Invocation.method( @@ -1968,7 +1985,7 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { @override void initCache( String? walletId, - _i19.Coin? coin, + _i20.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1981,14 +1998,14 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { returnValueForMissingStub: null, ); @override - _i20.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i21.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1998,14 +2015,14 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { returnValue: 0, ) as int); @override - _i20.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i21.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -2015,15 +2032,15 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { returnValue: false, ) as bool); @override - _i20.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i21.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override _i9.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -2039,15 +2056,15 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { ), ) as _i9.Balance); @override - _i20.Future<void> updateCachedBalance(_i9.Balance? balance) => + _i21.Future<void> updateCachedBalance(_i9.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override _i9.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -2063,15 +2080,15 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { ), ) as _i9.Balance); @override - _i20.Future<void> updateCachedBalanceSecondary(_i9.Balance? balance) => + _i21.Future<void> updateCachedBalanceSecondary(_i9.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override List<String> getWalletTokenContractAddresses() => (super.noSuchMethod( Invocation.method( @@ -2081,16 +2098,16 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { returnValue: <String>[], ) as List<String>); @override - _i20.Future<void> updateWalletTokenContractAddresses( + _i21.Future<void> updateWalletTokenContractAddresses( List<String>? contractAddresses) => (super.noSuchMethod( Invocation.method( #updateWalletTokenContractAddresses, [contractAddresses], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override void initWalletDB({_i14.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -2105,7 +2122,7 @@ class MockFiroWallet extends _i1.Mock implements _i24.FiroWallet { /// A class which mocks [LocaleService]. /// /// See the documentation for Mockito's code generation for more information. -class MockLocaleService extends _i1.Mock implements _i26.LocaleService { +class MockLocaleService extends _i1.Mock implements _i27.LocaleService { MockLocaleService() { _i1.throwOnMissingStub(this); } @@ -2121,17 +2138,17 @@ class MockLocaleService extends _i1.Mock implements _i26.LocaleService { returnValue: false, ) as bool); @override - _i20.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( + _i21.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( #loadLocale, [], {#notify: notify}, ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - void addListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2139,7 +2156,7 @@ class MockLocaleService extends _i1.Mock implements _i26.LocaleService { returnValueForMissingStub: null, ); @override - void removeListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2167,7 +2184,7 @@ class MockLocaleService extends _i1.Mock implements _i26.LocaleService { /// A class which mocks [Prefs]. /// /// See the documentation for Mockito's code generation for more information. -class MockPrefs extends _i1.Mock implements _i21.Prefs { +class MockPrefs extends _i1.Mock implements _i22.Prefs { MockPrefs() { _i1.throwOnMissingStub(this); } @@ -2223,12 +2240,12 @@ class MockPrefs extends _i1.Mock implements _i21.Prefs { returnValueForMissingStub: null, ); @override - _i27.SyncingType get syncType => (super.noSuchMethod( + _i28.SyncingType get syncType => (super.noSuchMethod( Invocation.getter(#syncType), - returnValue: _i27.SyncingType.currentWalletOnly, - ) as _i27.SyncingType); + returnValue: _i28.SyncingType.currentWalletOnly, + ) as _i28.SyncingType); @override - set syncType(_i27.SyncingType? syncType) => super.noSuchMethod( + set syncType(_i28.SyncingType? syncType) => super.noSuchMethod( Invocation.setter( #syncType, syncType, @@ -2387,12 +2404,12 @@ class MockPrefs extends _i1.Mock implements _i21.Prefs { returnValueForMissingStub: null, ); @override - _i28.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( + _i29.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( Invocation.getter(#backupFrequencyType), - returnValue: _i28.BackupFrequencyType.everyTenMinutes, - ) as _i28.BackupFrequencyType); + returnValue: _i29.BackupFrequencyType.everyTenMinutes, + ) as _i29.BackupFrequencyType); @override - set backupFrequencyType(_i28.BackupFrequencyType? backupFrequencyType) => + set backupFrequencyType(_i29.BackupFrequencyType? backupFrequencyType) => super.noSuchMethod( Invocation.setter( #backupFrequencyType, @@ -2538,66 +2555,82 @@ class MockPrefs extends _i1.Mock implements _i21.Prefs { returnValueForMissingStub: null, ); @override + _i15.FusionInfo get fusionServerInfo => (super.noSuchMethod( + Invocation.getter(#fusionServerInfo), + returnValue: _FakeFusionInfo_12( + this, + Invocation.getter(#fusionServerInfo), + ), + ) as _i15.FusionInfo); + @override + set fusionServerInfo(_i15.FusionInfo? fusionServerInfo) => super.noSuchMethod( + Invocation.setter( + #fusionServerInfo, + fusionServerInfo, + ), + returnValueForMissingStub: null, + ); + @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i20.Future<void> init() => (super.noSuchMethod( + _i21.Future<void> init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( + _i21.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( Invocation.method( #incrementCurrentNotificationIndex, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<bool> isExternalCallsSet() => (super.noSuchMethod( + _i21.Future<bool> isExternalCallsSet() => (super.noSuchMethod( Invocation.method( #isExternalCallsSet, [], ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i20.Future<void> saveUserID(String? userId) => (super.noSuchMethod( + _i21.Future<void> saveUserID(String? userId) => (super.noSuchMethod( Invocation.method( #saveUserID, [userId], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( + _i21.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( Invocation.method( #saveSignupEpoch, [signupEpoch], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i29.AmountUnit amountUnit(_i19.Coin? coin) => (super.noSuchMethod( + _i30.AmountUnit amountUnit(_i20.Coin? coin) => (super.noSuchMethod( Invocation.method( #amountUnit, [coin], ), - returnValue: _i29.AmountUnit.normal, - ) as _i29.AmountUnit); + returnValue: _i30.AmountUnit.normal, + ) as _i30.AmountUnit); @override void updateAmountUnit({ - required _i19.Coin? coin, - required _i29.AmountUnit? amountUnit, + required _i20.Coin? coin, + required _i30.AmountUnit? amountUnit, }) => super.noSuchMethod( Invocation.method( @@ -2611,7 +2644,7 @@ class MockPrefs extends _i1.Mock implements _i21.Prefs { returnValueForMissingStub: null, ); @override - int maxDecimals(_i19.Coin? coin) => (super.noSuchMethod( + int maxDecimals(_i20.Coin? coin) => (super.noSuchMethod( Invocation.method( #maxDecimals, [coin], @@ -2620,7 +2653,7 @@ class MockPrefs extends _i1.Mock implements _i21.Prefs { ) as int); @override void updateMaxDecimals({ - required _i19.Coin? coin, + required _i20.Coin? coin, required int? maxDecimals, }) => super.noSuchMethod( @@ -2635,7 +2668,7 @@ class MockPrefs extends _i1.Mock implements _i21.Prefs { returnValueForMissingStub: null, ); @override - void addListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2643,7 +2676,7 @@ class MockPrefs extends _i1.Mock implements _i21.Prefs { returnValueForMissingStub: null, ); @override - void removeListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2671,7 +2704,7 @@ class MockPrefs extends _i1.Mock implements _i21.Prefs { /// A class which mocks [PriceService]. /// /// See the documentation for Mockito's code generation for more information. -class MockPriceService extends _i1.Mock implements _i30.PriceService { +class MockPriceService extends _i1.Mock implements _i31.PriceService { MockPriceService() { _i1.throwOnMissingStub(this); } @@ -2697,7 +2730,7 @@ class MockPriceService extends _i1.Mock implements _i30.PriceService { @override Duration get updateInterval => (super.noSuchMethod( Invocation.getter(#updateInterval), - returnValue: _FakeDuration_12( + returnValue: _FakeDuration_13( this, Invocation.getter(#updateInterval), ), @@ -2708,44 +2741,44 @@ class MockPriceService extends _i1.Mock implements _i30.PriceService { returnValue: false, ) as bool); @override - _i15.Tuple2<_i31.Decimal, double> getPrice(_i19.Coin? coin) => + _i16.Tuple2<_i32.Decimal, double> getPrice(_i20.Coin? coin) => (super.noSuchMethod( Invocation.method( #getPrice, [coin], ), - returnValue: _FakeTuple2_13<_i31.Decimal, double>( + returnValue: _FakeTuple2_14<_i32.Decimal, double>( this, Invocation.method( #getPrice, [coin], ), ), - ) as _i15.Tuple2<_i31.Decimal, double>); + ) as _i16.Tuple2<_i32.Decimal, double>); @override - _i15.Tuple2<_i31.Decimal, double> getTokenPrice(String? contractAddress) => + _i16.Tuple2<_i32.Decimal, double> getTokenPrice(String? contractAddress) => (super.noSuchMethod( Invocation.method( #getTokenPrice, [contractAddress], ), - returnValue: _FakeTuple2_13<_i31.Decimal, double>( + returnValue: _FakeTuple2_14<_i32.Decimal, double>( this, Invocation.method( #getTokenPrice, [contractAddress], ), ), - ) as _i15.Tuple2<_i31.Decimal, double>); + ) as _i16.Tuple2<_i32.Decimal, double>); @override - _i20.Future<void> updatePrice() => (super.noSuchMethod( + _i21.Future<void> updatePrice() => (super.noSuchMethod( Invocation.method( #updatePrice, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override void cancel() => super.noSuchMethod( Invocation.method( @@ -2771,7 +2804,7 @@ class MockPriceService extends _i1.Mock implements _i30.PriceService { returnValueForMissingStub: null, ); @override - void addListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2779,7 +2812,7 @@ class MockPriceService extends _i1.Mock implements _i30.PriceService { returnValueForMissingStub: null, ); @override - void removeListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2799,7 +2832,7 @@ class MockPriceService extends _i1.Mock implements _i30.PriceService { /// A class which mocks [NotesService]. /// /// See the documentation for Mockito's code generation for more information. -class MockNotesService extends _i1.Mock implements _i32.NotesService { +class MockNotesService extends _i1.Mock implements _i33.NotesService { MockNotesService() { _i1.throwOnMissingStub(this); } @@ -2815,35 +2848,35 @@ class MockNotesService extends _i1.Mock implements _i32.NotesService { returnValue: <String, String>{}, ) as Map<String, String>); @override - _i20.Future<Map<String, String>> get notes => (super.noSuchMethod( + _i21.Future<Map<String, String>> get notes => (super.noSuchMethod( Invocation.getter(#notes), - returnValue: _i20.Future<Map<String, String>>.value(<String, String>{}), - ) as _i20.Future<Map<String, String>>); + returnValue: _i21.Future<Map<String, String>>.value(<String, String>{}), + ) as _i21.Future<Map<String, String>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i20.Future<Map<String, String>> search(String? text) => (super.noSuchMethod( + _i21.Future<Map<String, String>> search(String? text) => (super.noSuchMethod( Invocation.method( #search, [text], ), - returnValue: _i20.Future<Map<String, String>>.value(<String, String>{}), - ) as _i20.Future<Map<String, String>>); + returnValue: _i21.Future<Map<String, String>>.value(<String, String>{}), + ) as _i21.Future<Map<String, String>>); @override - _i20.Future<String> getNoteFor({required String? txid}) => + _i21.Future<String> getNoteFor({required String? txid}) => (super.noSuchMethod( Invocation.method( #getNoteFor, [], {#txid: txid}, ), - returnValue: _i20.Future<String>.value(''), - ) as _i20.Future<String>); + returnValue: _i21.Future<String>.value(''), + ) as _i21.Future<String>); @override - _i20.Future<void> editOrAddNote({ + _i21.Future<void> editOrAddNote({ required String? txid, required String? note, }) => @@ -2856,21 +2889,21 @@ class MockNotesService extends _i1.Mock implements _i32.NotesService { #note: note, }, ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> deleteNote({required String? txid}) => (super.noSuchMethod( + _i21.Future<void> deleteNote({required String? txid}) => (super.noSuchMethod( Invocation.method( #deleteNote, [], {#txid: txid}, ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - void addListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2878,7 +2911,7 @@ class MockNotesService extends _i1.Mock implements _i32.NotesService { returnValueForMissingStub: null, ); @override - void removeListener(_i22.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i23.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2906,21 +2939,21 @@ class MockNotesService extends _i1.Mock implements _i32.NotesService { /// A class which mocks [ThemeService]. /// /// See the documentation for Mockito's code generation for more information. -class MockThemeService extends _i1.Mock implements _i33.ThemeService { +class MockThemeService extends _i1.Mock implements _i34.ThemeService { MockThemeService() { _i1.throwOnMissingStub(this); } @override - _i16.HTTP get client => (super.noSuchMethod( + _i17.HTTP get client => (super.noSuchMethod( Invocation.getter(#client), - returnValue: _FakeHTTP_14( + returnValue: _FakeHTTP_15( this, Invocation.getter(#client), ), - ) as _i16.HTTP); + ) as _i17.HTTP); @override - set client(_i16.HTTP? _client) => super.noSuchMethod( + set client(_i17.HTTP? _client) => super.noSuchMethod( Invocation.setter( #client, _client, @@ -2936,10 +2969,10 @@ class MockThemeService extends _i1.Mock implements _i33.ThemeService { ), ) as _i14.MainDB); @override - List<_i34.StackTheme> get installedThemes => (super.noSuchMethod( + List<_i35.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), - returnValue: <_i34.StackTheme>[], - ) as List<_i34.StackTheme>); + returnValue: <_i35.StackTheme>[], + ) as List<_i35.StackTheme>); @override void init(_i14.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -2949,73 +2982,73 @@ class MockThemeService extends _i1.Mock implements _i33.ThemeService { returnValueForMissingStub: null, ); @override - _i20.Future<void> install({required _i35.Uint8List? themeArchiveData}) => + _i21.Future<void> install({required _i36.Uint8List? themeArchiveData}) => (super.noSuchMethod( Invocation.method( #install, [], {#themeArchiveData: themeArchiveData}, ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> remove({required String? themeId}) => (super.noSuchMethod( + _i21.Future<void> remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( #remove, [], {#themeId: themeId}, ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( + _i21.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( #checkDefaultThemesOnStartup, [], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<bool> verifyInstalled({required String? themeId}) => + _i21.Future<bool> verifyInstalled({required String? themeId}) => (super.noSuchMethod( Invocation.method( #verifyInstalled, [], {#themeId: themeId}, ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i20.Future<List<_i33.StackThemeMetaData>> fetchThemes() => + _i21.Future<List<_i34.StackThemeMetaData>> fetchThemes() => (super.noSuchMethod( Invocation.method( #fetchThemes, [], ), - returnValue: _i20.Future<List<_i33.StackThemeMetaData>>.value( - <_i33.StackThemeMetaData>[]), - ) as _i20.Future<List<_i33.StackThemeMetaData>>); + returnValue: _i21.Future<List<_i34.StackThemeMetaData>>.value( + <_i34.StackThemeMetaData>[]), + ) as _i21.Future<List<_i34.StackThemeMetaData>>); @override - _i20.Future<_i35.Uint8List> fetchTheme( - {required _i33.StackThemeMetaData? themeMetaData}) => + _i21.Future<_i36.Uint8List> fetchTheme( + {required _i34.StackThemeMetaData? themeMetaData}) => (super.noSuchMethod( Invocation.method( #fetchTheme, [], {#themeMetaData: themeMetaData}, ), - returnValue: _i20.Future<_i35.Uint8List>.value(_i35.Uint8List(0)), - ) as _i20.Future<_i35.Uint8List>); + returnValue: _i21.Future<_i36.Uint8List>.value(_i36.Uint8List(0)), + ) as _i21.Future<_i36.Uint8List>); @override - _i34.StackTheme? getTheme({required String? themeId}) => + _i35.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( #getTheme, [], {#themeId: themeId}, - )) as _i34.StackTheme?); + )) as _i35.StackTheme?); } /// A class which mocks [MainDB]. @@ -3027,131 +3060,131 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { } @override - _i17.Isar get isar => (super.noSuchMethod( + _i18.Isar get isar => (super.noSuchMethod( Invocation.getter(#isar), - returnValue: _FakeIsar_15( + returnValue: _FakeIsar_16( this, Invocation.getter(#isar), ), - ) as _i17.Isar); + ) as _i18.Isar); @override - _i20.Future<bool> initMainDB({_i17.Isar? mock}) => (super.noSuchMethod( + _i21.Future<bool> initMainDB({_i18.Isar? mock}) => (super.noSuchMethod( Invocation.method( #initMainDB, [], {#mock: mock}, ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - List<_i36.ContactEntry> getContactEntries() => (super.noSuchMethod( + List<_i37.ContactEntry> getContactEntries() => (super.noSuchMethod( Invocation.method( #getContactEntries, [], ), - returnValue: <_i36.ContactEntry>[], - ) as List<_i36.ContactEntry>); + returnValue: <_i37.ContactEntry>[], + ) as List<_i37.ContactEntry>); @override - _i20.Future<bool> deleteContactEntry({required String? id}) => + _i21.Future<bool> deleteContactEntry({required String? id}) => (super.noSuchMethod( Invocation.method( #deleteContactEntry, [], {#id: id}, ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i20.Future<bool> isContactEntryExists({required String? id}) => + _i21.Future<bool> isContactEntryExists({required String? id}) => (super.noSuchMethod( Invocation.method( #isContactEntryExists, [], {#id: id}, ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i36.ContactEntry? getContactEntry({required String? id}) => + _i37.ContactEntry? getContactEntry({required String? id}) => (super.noSuchMethod(Invocation.method( #getContactEntry, [], {#id: id}, - )) as _i36.ContactEntry?); + )) as _i37.ContactEntry?); @override - _i20.Future<bool> putContactEntry( - {required _i36.ContactEntry? contactEntry}) => + _i21.Future<bool> putContactEntry( + {required _i37.ContactEntry? contactEntry}) => (super.noSuchMethod( Invocation.method( #putContactEntry, [], {#contactEntry: contactEntry}, ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i37.TransactionBlockExplorer? getTransactionBlockExplorer( - {required _i19.Coin? coin}) => + _i38.TransactionBlockExplorer? getTransactionBlockExplorer( + {required _i20.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getTransactionBlockExplorer, [], {#coin: coin}, - )) as _i37.TransactionBlockExplorer?); + )) as _i38.TransactionBlockExplorer?); @override - _i20.Future<int> putTransactionBlockExplorer( - _i37.TransactionBlockExplorer? explorer) => + _i21.Future<int> putTransactionBlockExplorer( + _i38.TransactionBlockExplorer? explorer) => (super.noSuchMethod( Invocation.method( #putTransactionBlockExplorer, [explorer], ), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - _i17.QueryBuilder<_i23.Address, _i23.Address, _i17.QAfterWhereClause> + _i18.QueryBuilder<_i24.Address, _i24.Address, _i18.QAfterWhereClause> getAddresses(String? walletId) => (super.noSuchMethod( Invocation.method( #getAddresses, [walletId], ), - returnValue: _FakeQueryBuilder_16<_i23.Address, _i23.Address, - _i17.QAfterWhereClause>( + returnValue: _FakeQueryBuilder_17<_i24.Address, _i24.Address, + _i18.QAfterWhereClause>( this, Invocation.method( #getAddresses, [walletId], ), ), - ) as _i17.QueryBuilder<_i23.Address, _i23.Address, - _i17.QAfterWhereClause>); + ) as _i18.QueryBuilder<_i24.Address, _i24.Address, + _i18.QAfterWhereClause>); @override - _i20.Future<int> putAddress(_i23.Address? address) => (super.noSuchMethod( + _i21.Future<int> putAddress(_i24.Address? address) => (super.noSuchMethod( Invocation.method( #putAddress, [address], ), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - _i20.Future<List<int>> putAddresses(List<_i23.Address>? addresses) => + _i21.Future<List<int>> putAddresses(List<_i24.Address>? addresses) => (super.noSuchMethod( Invocation.method( #putAddresses, [addresses], ), - returnValue: _i20.Future<List<int>>.value(<int>[]), - ) as _i20.Future<List<int>>); + returnValue: _i21.Future<List<int>>.value(<int>[]), + ) as _i21.Future<List<int>>); @override - _i20.Future<List<int>> updateOrPutAddresses(List<_i23.Address>? addresses) => + _i21.Future<List<int>> updateOrPutAddresses(List<_i24.Address>? addresses) => (super.noSuchMethod( Invocation.method( #updateOrPutAddresses, [addresses], ), - returnValue: _i20.Future<List<int>>.value(<int>[]), - ) as _i20.Future<List<int>>); + returnValue: _i21.Future<List<int>>.value(<int>[]), + ) as _i21.Future<List<int>>); @override - _i20.Future<_i23.Address?> getAddress( + _i21.Future<_i24.Address?> getAddress( String? walletId, String? address, ) => @@ -3163,12 +3196,12 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { address, ], ), - returnValue: _i20.Future<_i23.Address?>.value(), - ) as _i20.Future<_i23.Address?>); + returnValue: _i21.Future<_i24.Address?>.value(), + ) as _i21.Future<_i24.Address?>); @override - _i20.Future<int> updateAddress( - _i23.Address? oldAddress, - _i23.Address? newAddress, + _i21.Future<int> updateAddress( + _i24.Address? oldAddress, + _i24.Address? newAddress, ) => (super.noSuchMethod( Invocation.method( @@ -3178,46 +3211,46 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { newAddress, ], ), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - _i17.QueryBuilder<_i23.Transaction, _i23.Transaction, _i17.QAfterWhereClause> + _i18.QueryBuilder<_i24.Transaction, _i24.Transaction, _i18.QAfterWhereClause> getTransactions(String? walletId) => (super.noSuchMethod( Invocation.method( #getTransactions, [walletId], ), - returnValue: _FakeQueryBuilder_16<_i23.Transaction, - _i23.Transaction, _i17.QAfterWhereClause>( + returnValue: _FakeQueryBuilder_17<_i24.Transaction, + _i24.Transaction, _i18.QAfterWhereClause>( this, Invocation.method( #getTransactions, [walletId], ), ), - ) as _i17.QueryBuilder<_i23.Transaction, _i23.Transaction, - _i17.QAfterWhereClause>); + ) as _i18.QueryBuilder<_i24.Transaction, _i24.Transaction, + _i18.QAfterWhereClause>); @override - _i20.Future<int> putTransaction(_i23.Transaction? transaction) => + _i21.Future<int> putTransaction(_i24.Transaction? transaction) => (super.noSuchMethod( Invocation.method( #putTransaction, [transaction], ), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - _i20.Future<List<int>> putTransactions( - List<_i23.Transaction>? transactions) => + _i21.Future<List<int>> putTransactions( + List<_i24.Transaction>? transactions) => (super.noSuchMethod( Invocation.method( #putTransactions, [transactions], ), - returnValue: _i20.Future<List<int>>.value(<int>[]), - ) as _i20.Future<List<int>>); + returnValue: _i21.Future<List<int>>.value(<int>[]), + ) as _i21.Future<List<int>>); @override - _i20.Future<_i23.Transaction?> getTransaction( + _i21.Future<_i24.Transaction?> getTransaction( String? walletId, String? txid, ) => @@ -3229,10 +3262,10 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { txid, ], ), - returnValue: _i20.Future<_i23.Transaction?>.value(), - ) as _i20.Future<_i23.Transaction?>); + returnValue: _i21.Future<_i24.Transaction?>.value(), + ) as _i21.Future<_i24.Transaction?>); @override - _i20.Stream<_i23.Transaction?> watchTransaction({ + _i21.Stream<_i24.Transaction?> watchTransaction({ required int? id, bool? fireImmediately = false, }) => @@ -3245,10 +3278,10 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { #fireImmediately: fireImmediately, }, ), - returnValue: _i20.Stream<_i23.Transaction?>.empty(), - ) as _i20.Stream<_i23.Transaction?>); + returnValue: _i21.Stream<_i24.Transaction?>.empty(), + ) as _i21.Stream<_i24.Transaction?>); @override - _i17.QueryBuilder<_i23.UTXO, _i23.UTXO, _i17.QAfterWhereClause> getUTXOs( + _i18.QueryBuilder<_i24.UTXO, _i24.UTXO, _i18.QAfterWhereClause> getUTXOs( String? walletId) => (super.noSuchMethod( Invocation.method( @@ -3256,36 +3289,63 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { [walletId], ), returnValue: - _FakeQueryBuilder_16<_i23.UTXO, _i23.UTXO, _i17.QAfterWhereClause>( + _FakeQueryBuilder_17<_i24.UTXO, _i24.UTXO, _i18.QAfterWhereClause>( this, Invocation.method( #getUTXOs, [walletId], ), ), - ) as _i17.QueryBuilder<_i23.UTXO, _i23.UTXO, _i17.QAfterWhereClause>); + ) as _i18.QueryBuilder<_i24.UTXO, _i24.UTXO, _i18.QAfterWhereClause>); @override - _i20.Future<void> putUTXO(_i23.UTXO? utxo) => (super.noSuchMethod( + _i18.QueryBuilder<_i24.UTXO, _i24.UTXO, _i18.QAfterFilterCondition> + getUTXOsByAddress( + String? walletId, + String? address, + ) => + (super.noSuchMethod( + Invocation.method( + #getUTXOsByAddress, + [ + walletId, + address, + ], + ), + returnValue: _FakeQueryBuilder_17<_i24.UTXO, _i24.UTXO, + _i18.QAfterFilterCondition>( + this, + Invocation.method( + #getUTXOsByAddress, + [ + walletId, + address, + ], + ), + ), + ) as _i18 + .QueryBuilder<_i24.UTXO, _i24.UTXO, _i18.QAfterFilterCondition>); + @override + _i21.Future<void> putUTXO(_i24.UTXO? utxo) => (super.noSuchMethod( Invocation.method( #putUTXO, [utxo], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> putUTXOs(List<_i23.UTXO>? utxos) => (super.noSuchMethod( + _i21.Future<void> putUTXOs(List<_i24.UTXO>? utxos) => (super.noSuchMethod( Invocation.method( #putUTXOs, [utxos], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<bool> updateUTXOs( + _i21.Future<bool> updateUTXOs( String? walletId, - List<_i23.UTXO>? utxos, + List<_i24.UTXO>? utxos, ) => (super.noSuchMethod( Invocation.method( @@ -3295,10 +3355,10 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { utxos, ], ), - returnValue: _i20.Future<bool>.value(false), - ) as _i20.Future<bool>); + returnValue: _i21.Future<bool>.value(false), + ) as _i21.Future<bool>); @override - _i20.Stream<_i23.UTXO?> watchUTXO({ + _i21.Stream<_i24.UTXO?> watchUTXO({ required int? id, bool? fireImmediately = false, }) => @@ -3311,50 +3371,50 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { #fireImmediately: fireImmediately, }, ), - returnValue: _i20.Stream<_i23.UTXO?>.empty(), - ) as _i20.Stream<_i23.UTXO?>); + returnValue: _i21.Stream<_i24.UTXO?>.empty(), + ) as _i21.Stream<_i24.UTXO?>); @override - _i17.QueryBuilder<_i23.TransactionNote, _i23.TransactionNote, - _i17.QAfterWhereClause> getTransactionNotes( + _i18.QueryBuilder<_i24.TransactionNote, _i24.TransactionNote, + _i18.QAfterWhereClause> getTransactionNotes( String? walletId) => (super.noSuchMethod( Invocation.method( #getTransactionNotes, [walletId], ), - returnValue: _FakeQueryBuilder_16<_i23.TransactionNote, - _i23.TransactionNote, _i17.QAfterWhereClause>( + returnValue: _FakeQueryBuilder_17<_i24.TransactionNote, + _i24.TransactionNote, _i18.QAfterWhereClause>( this, Invocation.method( #getTransactionNotes, [walletId], ), ), - ) as _i17.QueryBuilder<_i23.TransactionNote, _i23.TransactionNote, - _i17.QAfterWhereClause>); + ) as _i18.QueryBuilder<_i24.TransactionNote, _i24.TransactionNote, + _i18.QAfterWhereClause>); @override - _i20.Future<void> putTransactionNote(_i23.TransactionNote? transactionNote) => + _i21.Future<void> putTransactionNote(_i24.TransactionNote? transactionNote) => (super.noSuchMethod( Invocation.method( #putTransactionNote, [transactionNote], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> putTransactionNotes( - List<_i23.TransactionNote>? transactionNotes) => + _i21.Future<void> putTransactionNotes( + List<_i24.TransactionNote>? transactionNotes) => (super.noSuchMethod( Invocation.method( #putTransactionNotes, [transactionNotes], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<_i23.TransactionNote?> getTransactionNote( + _i21.Future<_i24.TransactionNote?> getTransactionNote( String? walletId, String? txid, ) => @@ -3366,10 +3426,10 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { txid, ], ), - returnValue: _i20.Future<_i23.TransactionNote?>.value(), - ) as _i20.Future<_i23.TransactionNote?>); + returnValue: _i21.Future<_i24.TransactionNote?>.value(), + ) as _i21.Future<_i24.TransactionNote?>); @override - _i20.Stream<_i23.TransactionNote?> watchTransactionNote({ + _i21.Stream<_i24.TransactionNote?> watchTransactionNote({ required int? id, bool? fireImmediately = false, }) => @@ -3382,38 +3442,38 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { #fireImmediately: fireImmediately, }, ), - returnValue: _i20.Stream<_i23.TransactionNote?>.empty(), - ) as _i20.Stream<_i23.TransactionNote?>); + returnValue: _i21.Stream<_i24.TransactionNote?>.empty(), + ) as _i21.Stream<_i24.TransactionNote?>); @override - _i17.QueryBuilder<_i23.AddressLabel, _i23.AddressLabel, - _i17.QAfterWhereClause> getAddressLabels( + _i18.QueryBuilder<_i24.AddressLabel, _i24.AddressLabel, + _i18.QAfterWhereClause> getAddressLabels( String? walletId) => (super.noSuchMethod( Invocation.method( #getAddressLabels, [walletId], ), - returnValue: _FakeQueryBuilder_16<_i23.AddressLabel, _i23.AddressLabel, - _i17.QAfterWhereClause>( + returnValue: _FakeQueryBuilder_17<_i24.AddressLabel, _i24.AddressLabel, + _i18.QAfterWhereClause>( this, Invocation.method( #getAddressLabels, [walletId], ), ), - ) as _i17.QueryBuilder<_i23.AddressLabel, _i23.AddressLabel, - _i17.QAfterWhereClause>); + ) as _i18.QueryBuilder<_i24.AddressLabel, _i24.AddressLabel, + _i18.QAfterWhereClause>); @override - _i20.Future<int> putAddressLabel(_i23.AddressLabel? addressLabel) => + _i21.Future<int> putAddressLabel(_i24.AddressLabel? addressLabel) => (super.noSuchMethod( Invocation.method( #putAddressLabel, [addressLabel], ), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - int putAddressLabelSync(_i23.AddressLabel? addressLabel) => + int putAddressLabelSync(_i24.AddressLabel? addressLabel) => (super.noSuchMethod( Invocation.method( #putAddressLabelSync, @@ -3422,17 +3482,17 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { returnValue: 0, ) as int); @override - _i20.Future<void> putAddressLabels(List<_i23.AddressLabel>? addressLabels) => + _i21.Future<void> putAddressLabels(List<_i24.AddressLabel>? addressLabels) => (super.noSuchMethod( Invocation.method( #putAddressLabels, [addressLabels], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<_i23.AddressLabel?> getAddressLabel( + _i21.Future<_i24.AddressLabel?> getAddressLabel( String? walletId, String? addressString, ) => @@ -3444,10 +3504,10 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { addressString, ], ), - returnValue: _i20.Future<_i23.AddressLabel?>.value(), - ) as _i20.Future<_i23.AddressLabel?>); + returnValue: _i21.Future<_i24.AddressLabel?>.value(), + ) as _i21.Future<_i24.AddressLabel?>); @override - _i23.AddressLabel? getAddressLabelSync( + _i24.AddressLabel? getAddressLabelSync( String? walletId, String? addressString, ) => @@ -3457,9 +3517,9 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { walletId, addressString, ], - )) as _i23.AddressLabel?); + )) as _i24.AddressLabel?); @override - _i20.Stream<_i23.AddressLabel?> watchAddressLabel({ + _i21.Stream<_i24.AddressLabel?> watchAddressLabel({ required int? id, bool? fireImmediately = false, }) => @@ -3472,50 +3532,50 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { #fireImmediately: fireImmediately, }, ), - returnValue: _i20.Stream<_i23.AddressLabel?>.empty(), - ) as _i20.Stream<_i23.AddressLabel?>); + returnValue: _i21.Stream<_i24.AddressLabel?>.empty(), + ) as _i21.Stream<_i24.AddressLabel?>); @override - _i20.Future<int> updateAddressLabel(_i23.AddressLabel? addressLabel) => + _i21.Future<int> updateAddressLabel(_i24.AddressLabel? addressLabel) => (super.noSuchMethod( Invocation.method( #updateAddressLabel, [addressLabel], ), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - _i20.Future<void> deleteWalletBlockchainData(String? walletId) => + _i21.Future<void> deleteWalletBlockchainData(String? walletId) => (super.noSuchMethod( Invocation.method( #deleteWalletBlockchainData, [walletId], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> deleteAddressLabels(String? walletId) => + _i21.Future<void> deleteAddressLabels(String? walletId) => (super.noSuchMethod( Invocation.method( #deleteAddressLabels, [walletId], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> deleteTransactionNotes(String? walletId) => + _i21.Future<void> deleteTransactionNotes(String? walletId) => (super.noSuchMethod( Invocation.method( #deleteTransactionNotes, [walletId], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<void> addNewTransactionData( - List<_i15.Tuple2<_i23.Transaction, _i23.Address?>>? transactionsData, + _i21.Future<void> addNewTransactionData( + List<_i16.Tuple2<_i24.Transaction, _i24.Address?>>? transactionsData, String? walletId, ) => (super.noSuchMethod( @@ -3526,76 +3586,76 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { walletId, ], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i17.QueryBuilder<_i23.EthContract, _i23.EthContract, _i17.QWhere> + _i18.QueryBuilder<_i24.EthContract, _i24.EthContract, _i18.QWhere> getEthContracts() => (super.noSuchMethod( Invocation.method( #getEthContracts, [], ), - returnValue: _FakeQueryBuilder_16<_i23.EthContract, - _i23.EthContract, _i17.QWhere>( + returnValue: _FakeQueryBuilder_17<_i24.EthContract, + _i24.EthContract, _i18.QWhere>( this, Invocation.method( #getEthContracts, [], ), ), - ) as _i17 - .QueryBuilder<_i23.EthContract, _i23.EthContract, _i17.QWhere>); + ) as _i18 + .QueryBuilder<_i24.EthContract, _i24.EthContract, _i18.QWhere>); @override - _i20.Future<_i23.EthContract?> getEthContract(String? contractAddress) => + _i21.Future<_i24.EthContract?> getEthContract(String? contractAddress) => (super.noSuchMethod( Invocation.method( #getEthContract, [contractAddress], ), - returnValue: _i20.Future<_i23.EthContract?>.value(), - ) as _i20.Future<_i23.EthContract?>); + returnValue: _i21.Future<_i24.EthContract?>.value(), + ) as _i21.Future<_i24.EthContract?>); @override - _i23.EthContract? getEthContractSync(String? contractAddress) => + _i24.EthContract? getEthContractSync(String? contractAddress) => (super.noSuchMethod(Invocation.method( #getEthContractSync, [contractAddress], - )) as _i23.EthContract?); + )) as _i24.EthContract?); @override - _i20.Future<int> putEthContract(_i23.EthContract? contract) => + _i21.Future<int> putEthContract(_i24.EthContract? contract) => (super.noSuchMethod( Invocation.method( #putEthContract, [contract], ), - returnValue: _i20.Future<int>.value(0), - ) as _i20.Future<int>); + returnValue: _i21.Future<int>.value(0), + ) as _i21.Future<int>); @override - _i20.Future<void> putEthContracts(List<_i23.EthContract>? contracts) => + _i21.Future<void> putEthContracts(List<_i24.EthContract>? contracts) => (super.noSuchMethod( Invocation.method( #putEthContracts, [contracts], ), - returnValue: _i20.Future<void>.value(), - returnValueForMissingStub: _i20.Future<void>.value(), - ) as _i20.Future<void>); + returnValue: _i21.Future<void>.value(), + returnValueForMissingStub: _i21.Future<void>.value(), + ) as _i21.Future<void>); @override - _i20.Future<int?> getHighestUsedMintIndex({required String? walletId}) => + _i21.Future<int?> getHighestUsedMintIndex({required String? walletId}) => (super.noSuchMethod( Invocation.method( #getHighestUsedMintIndex, [], {#walletId: walletId}, ), - returnValue: _i20.Future<int?>.value(), - ) as _i20.Future<int?>); + returnValue: _i21.Future<int?>.value(), + ) as _i21.Future<int?>); } /// A class which mocks [IThemeAssets]. /// /// See the documentation for Mockito's code generation for more information. -class MockIThemeAssets extends _i1.Mock implements _i34.IThemeAssets { +class MockIThemeAssets extends _i1.Mock implements _i35.IThemeAssets { MockIThemeAssets() { _i1.throwOnMissingStub(this); } diff --git a/test/widget_tests/wallet_card_test.mocks.dart b/test/widget_tests/wallet_card_test.mocks.dart index 5ed295d28..675c27561 100644 --- a/test/widget_tests/wallet_card_test.mocks.dart +++ b/test/widget_tests/wallet_card_test.mocks.dart @@ -3,12 +3,12 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i22; -import 'dart:typed_data' as _i29; -import 'dart:ui' as _i24; +import 'dart:async' as _i23; +import 'dart:typed_data' as _i30; +import 'dart:ui' as _i25; -import 'package:bip32/bip32.dart' as _i16; -import 'package:bip47/bip47.dart' as _i18; +import 'package:bip32/bip32.dart' as _i17; +import 'package:bip47/bip47.dart' as _i19; import 'package:bitcoindart/bitcoindart.dart' as _i13; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -17,27 +17,29 @@ import 'package:stackwallet/db/isar/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i17; -import 'package:stackwallet/models/isar/stack_theme.dart' as _i32; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart' + as _i15; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i18; +import 'package:stackwallet/models/isar/stack_theme.dart' as _i33; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/models/signing_data.dart' as _i27; -import 'package:stackwallet/networking/http.dart' as _i19; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i25; +import 'package:stackwallet/models/signing_data.dart' as _i28; +import 'package:stackwallet/networking/http.dart' as _i20; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i26; import 'package:stackwallet/services/coins/manager.dart' as _i6; -import 'package:stackwallet/services/locale_service.dart' as _i30; +import 'package:stackwallet/services/locale_service.dart' as _i31; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i20; +import 'package:stackwallet/services/wallets.dart' as _i21; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/themes/theme_service.dart' as _i31; +import 'package:stackwallet/themes/theme_service.dart' as _i32; import 'package:stackwallet/utilities/amount/amount.dart' as _i14; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i21; -import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i26; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i22; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i27; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' - as _i28; -import 'package:stackwallet/utilities/prefs.dart' as _i23; -import 'package:tuple/tuple.dart' as _i15; + as _i29; +import 'package:stackwallet/utilities/prefs.dart' as _i24; +import 'package:tuple/tuple.dart' as _i16; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -184,9 +186,9 @@ class _FakeAmount_12 extends _i1.SmartFake implements _i14.Amount { ); } -class _FakeTuple2_13<T1, T2> extends _i1.SmartFake - implements _i15.Tuple2<T1, T2> { - _FakeTuple2_13( +class _FakeTransactionV2_13 extends _i1.SmartFake + implements _i15.TransactionV2 { + _FakeTransactionV2_13( Object parent, Invocation parentInvocation, ) : super( @@ -195,8 +197,9 @@ class _FakeTuple2_13<T1, T2> extends _i1.SmartFake ); } -class _FakeBIP32_14 extends _i1.SmartFake implements _i16.BIP32 { - _FakeBIP32_14( +class _FakeTuple2_14<T1, T2> extends _i1.SmartFake + implements _i16.Tuple2<T1, T2> { + _FakeTuple2_14( Object parent, Invocation parentInvocation, ) : super( @@ -205,8 +208,8 @@ class _FakeBIP32_14 extends _i1.SmartFake implements _i16.BIP32 { ); } -class _FakeAddress_15 extends _i1.SmartFake implements _i17.Address { - _FakeAddress_15( +class _FakeBIP32_15 extends _i1.SmartFake implements _i17.BIP32 { + _FakeBIP32_15( Object parent, Invocation parentInvocation, ) : super( @@ -215,8 +218,8 @@ class _FakeAddress_15 extends _i1.SmartFake implements _i17.Address { ); } -class _FakePaymentCode_16 extends _i1.SmartFake implements _i18.PaymentCode { - _FakePaymentCode_16( +class _FakeAddress_16 extends _i1.SmartFake implements _i18.Address { + _FakeAddress_16( Object parent, Invocation parentInvocation, ) : super( @@ -225,8 +228,18 @@ class _FakePaymentCode_16 extends _i1.SmartFake implements _i18.PaymentCode { ); } -class _FakeHTTP_17 extends _i1.SmartFake implements _i19.HTTP { - _FakeHTTP_17( +class _FakePaymentCode_17 extends _i1.SmartFake implements _i19.PaymentCode { + _FakePaymentCode_17( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeHTTP_18 extends _i1.SmartFake implements _i20.HTTP { + _FakeHTTP_18( Object parent, Invocation parentInvocation, ) : super( @@ -238,7 +251,7 @@ class _FakeHTTP_17 extends _i1.SmartFake implements _i19.HTTP { /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i20.Wallets { +class MockWallets extends _i1.Mock implements _i21.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -305,7 +318,7 @@ class MockWallets extends _i1.Mock implements _i20.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i21.Coin? coin}) => + List<String> getWalletIdsFor({required _i22.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -315,20 +328,20 @@ class MockWallets extends _i1.Mock implements _i20.Wallets { returnValue: <String>[], ) as List<String>); @override - List<_i15.Tuple2<_i21.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> + List<_i16.Tuple2<_i22.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i15.Tuple2<_i21.Coin, + returnValue: <_i16.Tuple2<_i22.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>[], ) as List< - _i15.Tuple2<_i21.Coin, + _i16.Tuple2<_i22.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i21.Coin? coin) => + _i22.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -392,17 +405,17 @@ class MockWallets extends _i1.Mock implements _i20.Wallets { returnValueForMissingStub: null, ); @override - _i22.Future<void> load(_i23.Prefs? prefs) => (super.noSuchMethod( + _i23.Future<void> load(_i24.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<void> loadAfterStackRestore( - _i23.Prefs? prefs, + _i23.Future<void> loadAfterStackRestore( + _i24.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -413,11 +426,11 @@ class MockWallets extends _i1.Mock implements _i20.Wallets { managers, ], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - void addListener(_i24.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i25.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -425,7 +438,7 @@ class MockWallets extends _i1.Mock implements _i20.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i24.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i25.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -445,13 +458,13 @@ class MockWallets extends _i1.Mock implements _i20.Wallets { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i22.Timer? _timer) => super.noSuchMethod( + set timer(_i23.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -528,74 +541,74 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { returnValue: false, ) as bool); @override - _i21.Coin get coin => (super.noSuchMethod( + _i22.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i21.Coin.bitcoin, - ) as _i21.Coin); + returnValue: _i22.Coin.bitcoin, + ) as _i22.Coin); @override - _i22.Future<List<_i17.UTXO>> get utxos => (super.noSuchMethod( + _i23.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i22.Future<List<_i17.UTXO>>.value(<_i17.UTXO>[]), - ) as _i22.Future<List<_i17.UTXO>>); + returnValue: _i23.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), + ) as _i23.Future<List<_i18.UTXO>>); @override - _i22.Future<List<_i17.Transaction>> get transactions => (super.noSuchMethod( + _i23.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i22.Future<List<_i17.Transaction>>.value(<_i17.Transaction>[]), - ) as _i22.Future<List<_i17.Transaction>>); + _i23.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), + ) as _i23.Future<List<_i18.Transaction>>); @override - _i22.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i23.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i22.Future<String>.value(''), - ) as _i22.Future<String>); + returnValue: _i23.Future<String>.value(''), + ) as _i23.Future<String>); @override - _i22.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i23.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i22.Future<String>.value(''), - ) as _i22.Future<String>); + returnValue: _i23.Future<String>.value(''), + ) as _i23.Future<String>); @override - _i22.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( + _i23.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( Invocation.getter(#currentChangeAddressP2PKH), - returnValue: _i22.Future<String>.value(''), - ) as _i22.Future<String>); + returnValue: _i23.Future<String>.value(''), + ) as _i23.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i22.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i23.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i22.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i23.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i22.Future<_i8.FeeObject>); + ) as _i23.Future<_i8.FeeObject>); @override - _i22.Future<int> get maxFee => (super.noSuchMethod( + _i23.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i22.Future<int>.value(0), - ) as _i22.Future<int>); + returnValue: _i23.Future<int>.value(0), + ) as _i23.Future<int>); @override - _i22.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i23.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i22.Future<List<String>>.value(<String>[]), - ) as _i22.Future<List<String>>); + returnValue: _i23.Future<List<String>>.value(<String>[]), + ) as _i23.Future<List<String>>); @override - _i22.Future<String?> get mnemonicString => (super.noSuchMethod( + _i23.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i22.Future<String?>.value(), - ) as _i22.Future<String?>); + returnValue: _i23.Future<String?>.value(), + ) as _i23.Future<String?>); @override - _i22.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i23.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i22.Future<String?>.value(), - ) as _i22.Future<String?>); + returnValue: _i23.Future<String?>.value(), + ) as _i23.Future<String?>); @override - _i22.Future<int> get chainHeight => (super.noSuchMethod( + _i23.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i22.Future<int>.value(0), - ) as _i22.Future<int>); + returnValue: _i23.Future<int>.value(0), + ) as _i23.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -667,10 +680,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { ), ) as _i11.Balance); @override - _i22.Future<String> get xpub => (super.noSuchMethod( + _i23.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i22.Future<String>.value(''), - ) as _i22.Future<String>); + returnValue: _i23.Future<String>.value(''), + ) as _i23.Future<String>); @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -697,26 +710,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { ), ) as _i13.NetworkType); @override - _i22.Future<void> exit() => (super.noSuchMethod( + _i23.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i26.DerivePathType addressType({required String? address}) => + _i27.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i26.DerivePathType.bip44, - ) as _i26.DerivePathType); + returnValue: _i27.DerivePathType.bip44, + ) as _i27.DerivePathType); @override - _i22.Future<void> recoverFromMnemonic({ + _i23.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -735,47 +748,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { #height: height, }, ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i23.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i23.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i22.Future<bool>.value(false), - ) as _i22.Future<bool>); + returnValue: _i23.Future<bool>.value(false), + ) as _i23.Future<bool>); @override - _i22.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i23.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<void> refresh() => (super.noSuchMethod( + _i23.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<Map<String, dynamic>> prepareSend({ + _i23.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i14.Amount? amount, Map<String, dynamic>? args, @@ -791,26 +804,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { }, ), returnValue: - _i22.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i22.Future<Map<String, dynamic>>); + _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i23.Future<Map<String, dynamic>>); @override - _i22.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i23.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i22.Future<String>.value(''), - ) as _i22.Future<String>); + returnValue: _i23.Future<String>.value(''), + ) as _i23.Future<String>); @override - _i22.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i23.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i22.Future<bool>.value(false), - ) as _i22.Future<bool>); + returnValue: _i23.Future<bool>.value(false), + ) as _i23.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -828,35 +841,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i22.Future<void> initializeNew( + _i23.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<void> initializeExisting() => (super.noSuchMethod( + _i23.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i23.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -866,69 +879,69 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { returnValue: false, ) as bool); @override - _i22.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i23.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i23.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i22.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_11( + returnValue: _i23.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_11( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i22.Future<_i9.ElectrumXNode>); + ) as _i23.Future<_i9.ElectrumXNode>); @override - _i22.Future<List<Map<String, dynamic>>> fastFetch( + _i23.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i22.Future<List<Map<String, dynamic>>>.value( + returnValue: _i23.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i22.Future<List<Map<String, dynamic>>>); + ) as _i23.Future<List<Map<String, dynamic>>>); @override - _i22.Future<int> getTxCount({required String? address}) => + _i23.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i22.Future<int>.value(0), - ) as _i22.Future<int>); + returnValue: _i23.Future<int>.value(0), + ) as _i23.Future<int>); @override - _i22.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i23.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<void> checkCurrentChangeAddressesForTransactions() => + _i23.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -954,7 +967,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { required bool? isSendAll, int? satsPerVByte, int? additionalOutputs = 0, - List<_i17.UTXO>? utxos, + List<_i18.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -971,19 +984,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { }, )); @override - _i22.Future<List<_i27.SigningData>> fetchBuildTxData( - List<_i17.UTXO>? utxosToUse) => + _i23.Future<List<_i28.SigningData>> fetchBuildTxData( + List<_i18.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i22.Future<List<_i27.SigningData>>.value(<_i27.SigningData>[]), - ) as _i22.Future<List<_i27.SigningData>>); + _i23.Future<List<_i28.SigningData>>.value(<_i28.SigningData>[]), + ) as _i23.Future<List<_i28.SigningData>>); @override - _i22.Future<Map<String, dynamic>> buildTransaction({ - required List<_i27.SigningData>? utxoSigningData, + _i23.Future<Map<String, dynamic>> buildTransaction({ + required List<_i28.SigningData>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, }) => @@ -998,10 +1011,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { }, ), returnValue: - _i22.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i22.Future<Map<String, dynamic>>); + _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i23.Future<Map<String, dynamic>>); @override - _i22.Future<void> fullRescan( + _i23.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1013,11 +1026,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<_i14.Amount> estimateFeeFor( + _i23.Future<_i14.Amount> estimateFeeFor( _i14.Amount? amount, int? feeRate, ) => @@ -1029,7 +1042,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { feeRate, ], ), - returnValue: _i22.Future<_i14.Amount>.value(_FakeAmount_12( + returnValue: _i23.Future<_i14.Amount>.value(_FakeAmount_12( this, Invocation.method( #estimateFeeFor, @@ -1039,7 +1052,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { ], ), )), - ) as _i22.Future<_i14.Amount>); + ) as _i23.Future<_i14.Amount>); @override _i14.Amount roughFeeEstimate( int? inputCount, @@ -1068,32 +1081,32 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { ), ) as _i14.Amount); @override - _i22.Future<_i14.Amount> sweepAllEstimate(int? feeRate) => + _i23.Future<_i14.Amount> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i22.Future<_i14.Amount>.value(_FakeAmount_12( + returnValue: _i23.Future<_i14.Amount>.value(_FakeAmount_12( this, Invocation.method( #sweepAllEstimate, [feeRate], ), )), - ) as _i22.Future<_i14.Amount>); + ) as _i23.Future<_i14.Amount>); @override - _i22.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i23.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i22.Future<bool>.value(false), - ) as _i22.Future<bool>); + returnValue: _i23.Future<bool>.value(false), + ) as _i23.Future<bool>); @override void initCache( String? walletId, - _i21.Coin? coin, + _i22.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1106,14 +1119,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i22.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i23.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1123,14 +1136,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { returnValue: 0, ) as int); @override - _i22.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i23.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1140,15 +1153,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { returnValue: false, ) as bool); @override - _i22.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i23.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1164,15 +1177,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { ), ) as _i11.Balance); @override - _i22.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i23.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1188,15 +1201,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { ), ) as _i11.Balance); @override - _i22.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i23.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override List<String> getWalletTokenContractAddresses() => (super.noSuchMethod( Invocation.method( @@ -1206,16 +1219,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { returnValue: <String>[], ) as List<String>); @override - _i22.Future<void> updateWalletTokenContractAddresses( + _i23.Future<void> updateWalletTokenContractAddresses( List<String>? contractAddresses) => (super.noSuchMethod( Invocation.method( #updateWalletTokenContractAddresses, [contractAddresses], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1226,11 +1239,45 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i22.Future<_i15.Tuple2<_i17.Transaction, _i17.Address>> parseTransaction( + _i23.Future<_i15.TransactionV2> getTransaction( + String? txHash, + _i22.Coin? coin, + String? walletId, + _i10.CachedElectrumX? cachedElectrumX, [ + String? debugTitle, + ]) => + (super.noSuchMethod( + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + returnValue: + _i23.Future<_i15.TransactionV2>.value(_FakeTransactionV2_13( + this, + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + )), + ) as _i23.Future<_i15.TransactionV2>); + @override + _i23.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>> parseTransaction( Map<String, dynamic>? txData, dynamic electrumxClient, - List<_i17.Address>? myAddresses, - _i21.Coin? coin, + List<_i18.Address>? myAddresses, + _i22.Coin? coin, int? minConfirms, String? walletId, ) => @@ -1247,8 +1294,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { ], ), returnValue: - _i22.Future<_i15.Tuple2<_i17.Transaction, _i17.Address>>.value( - _FakeTuple2_13<_i17.Transaction, _i17.Address>( + _i23.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>.value( + _FakeTuple2_14<_i18.Transaction, _i18.Address>( this, Invocation.method( #parseTransaction, @@ -1262,37 +1309,37 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { ], ), )), - ) as _i22.Future<_i15.Tuple2<_i17.Transaction, _i17.Address>>); + ) as _i23.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>); @override void initPaynymWalletInterface({ required String? walletId, required String? walletName, required _i13.NetworkType? network, - required _i21.Coin? coin, + required _i22.Coin? coin, required _i12.MainDB? db, required _i9.ElectrumX? electrumXClient, - required _i28.SecureStorageInterface? secureStorage, + required _i29.SecureStorageInterface? secureStorage, required int? dustLimit, required int? dustLimitP2PKH, required int? minConfirms, - required _i22.Future<String?> Function()? getMnemonicString, - required _i22.Future<String?> Function()? getMnemonicPassphrase, - required _i22.Future<int> Function()? getChainHeight, - required _i22.Future<String> Function()? getCurrentChangeAddress, + required _i23.Future<String?> Function()? getMnemonicString, + required _i23.Future<String?> Function()? getMnemonicPassphrase, + required _i23.Future<int> Function()? getChainHeight, + required _i23.Future<String> Function()? getCurrentChangeAddress, required int Function({ required int feeRatePerKB, required int vSize, })? estimateTxFee, - required _i22.Future<Map<String, dynamic>> Function({ + required _i23.Future<Map<String, dynamic>> Function({ required String address, required _i14.Amount amount, Map<String, dynamic>? args, })? prepareSend, - required _i22.Future<int> Function({required String address})? getTxCount, - required _i22.Future<List<_i27.SigningData>> Function(List<_i17.UTXO>)? + required _i23.Future<int> Function({required String address})? getTxCount, + required _i23.Future<List<_i28.SigningData>> Function(List<_i18.UTXO>)? fetchBuildTxData, - required _i22.Future<void> Function()? refresh, - required _i22.Future<void> Function()? checkChangeAddressForTransactions, + required _i23.Future<void> Function()? refresh, + required _i23.Future<void> Function()? checkChangeAddressForTransactions, }) => super.noSuchMethod( Invocation.method( @@ -1325,21 +1372,21 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i22.Future<_i16.BIP32> getBip47BaseNode() => (super.noSuchMethod( + _i23.Future<_i17.BIP32> getBip47BaseNode() => (super.noSuchMethod( Invocation.method( #getBip47BaseNode, [], ), - returnValue: _i22.Future<_i16.BIP32>.value(_FakeBIP32_14( + returnValue: _i23.Future<_i17.BIP32>.value(_FakeBIP32_15( this, Invocation.method( #getBip47BaseNode, [], ), )), - ) as _i22.Future<_i16.BIP32>); + ) as _i23.Future<_i17.BIP32>); @override - _i22.Future<_i29.Uint8List> getPrivateKeyForPaynymReceivingAddress({ + _i23.Future<_i30.Uint8List> getPrivateKeyForPaynymReceivingAddress({ required String? paymentCodeString, required int? index, }) => @@ -1352,11 +1399,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { #index: index, }, ), - returnValue: _i22.Future<_i29.Uint8List>.value(_i29.Uint8List(0)), - ) as _i22.Future<_i29.Uint8List>); + returnValue: _i23.Future<_i30.Uint8List>.value(_i30.Uint8List(0)), + ) as _i23.Future<_i30.Uint8List>); @override - _i22.Future<_i17.Address> currentReceivingPaynymAddress({ - required _i18.PaymentCode? sender, + _i23.Future<_i18.Address> currentReceivingPaynymAddress({ + required _i19.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1368,7 +1415,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i22.Future<_i17.Address>.value(_FakeAddress_15( + returnValue: _i23.Future<_i18.Address>.value(_FakeAddress_16( this, Invocation.method( #currentReceivingPaynymAddress, @@ -1379,10 +1426,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { }, ), )), - ) as _i22.Future<_i17.Address>); + ) as _i23.Future<_i18.Address>); @override - _i22.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ - required _i18.PaymentCode? sender, + _i23.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ + required _i19.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1394,42 +1441,42 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => + _i23.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkAllCurrentReceivingPaynymAddressesForTransactions, [], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<_i16.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( + _i23.Future<_i17.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( Invocation.method( #deriveNotificationBip32Node, [], ), - returnValue: _i22.Future<_i16.BIP32>.value(_FakeBIP32_14( + returnValue: _i23.Future<_i17.BIP32>.value(_FakeBIP32_15( this, Invocation.method( #deriveNotificationBip32Node, [], ), )), - ) as _i22.Future<_i16.BIP32>); + ) as _i23.Future<_i17.BIP32>); @override - _i22.Future<_i18.PaymentCode> getPaymentCode({required bool? isSegwit}) => + _i23.Future<_i19.PaymentCode> getPaymentCode({required bool? isSegwit}) => (super.noSuchMethod( Invocation.method( #getPaymentCode, [], {#isSegwit: isSegwit}, ), - returnValue: _i22.Future<_i18.PaymentCode>.value(_FakePaymentCode_16( + returnValue: _i23.Future<_i19.PaymentCode>.value(_FakePaymentCode_17( this, Invocation.method( #getPaymentCode, @@ -1437,28 +1484,28 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { {#isSegwit: isSegwit}, ), )), - ) as _i22.Future<_i18.PaymentCode>); + ) as _i23.Future<_i19.PaymentCode>); @override - _i22.Future<_i29.Uint8List> signWithNotificationKey(_i29.Uint8List? data) => + _i23.Future<_i30.Uint8List> signWithNotificationKey(_i30.Uint8List? data) => (super.noSuchMethod( Invocation.method( #signWithNotificationKey, [data], ), - returnValue: _i22.Future<_i29.Uint8List>.value(_i29.Uint8List(0)), - ) as _i22.Future<_i29.Uint8List>); + returnValue: _i23.Future<_i30.Uint8List>.value(_i30.Uint8List(0)), + ) as _i23.Future<_i30.Uint8List>); @override - _i22.Future<String> signStringWithNotificationKey(String? data) => + _i23.Future<String> signStringWithNotificationKey(String? data) => (super.noSuchMethod( Invocation.method( #signStringWithNotificationKey, [data], ), - returnValue: _i22.Future<String>.value(''), - ) as _i22.Future<String>); + returnValue: _i23.Future<String>.value(''), + ) as _i23.Future<String>); @override - _i22.Future<Map<String, dynamic>> preparePaymentCodeSend({ - required _i18.PaymentCode? paymentCode, + _i23.Future<Map<String, dynamic>> preparePaymentCodeSend({ + required _i19.PaymentCode? paymentCode, required bool? isSegwit, required _i14.Amount? amount, Map<String, dynamic>? args, @@ -1475,13 +1522,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { }, ), returnValue: - _i22.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i22.Future<Map<String, dynamic>>); + _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i23.Future<Map<String, dynamic>>); @override - _i22.Future<_i17.Address> nextUnusedSendAddressFrom({ - required _i18.PaymentCode? pCode, + _i23.Future<_i18.Address> nextUnusedSendAddressFrom({ + required _i19.PaymentCode? pCode, required bool? isSegwit, - required _i16.BIP32? privateKeyNode, + required _i17.BIP32? privateKeyNode, int? startIndex = 0, }) => (super.noSuchMethod( @@ -1495,7 +1542,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { #startIndex: startIndex, }, ), - returnValue: _i22.Future<_i17.Address>.value(_FakeAddress_15( + returnValue: _i23.Future<_i18.Address>.value(_FakeAddress_16( this, Invocation.method( #nextUnusedSendAddressFrom, @@ -1508,13 +1555,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { }, ), )), - ) as _i22.Future<_i17.Address>); + ) as _i23.Future<_i18.Address>); @override - _i22.Future<Map<String, dynamic>> prepareNotificationTx({ + _i23.Future<Map<String, dynamic>> prepareNotificationTx({ required int? selectedTxFeeRate, required String? targetPaymentCodeString, int? additionalOutputs = 0, - List<_i17.UTXO>? utxos, + List<_i18.UTXO>? utxos, }) => (super.noSuchMethod( Invocation.method( @@ -1528,10 +1575,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { }, ), returnValue: - _i22.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i22.Future<Map<String, dynamic>>); + _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i23.Future<Map<String, dynamic>>); @override - _i22.Future<String> broadcastNotificationTx( + _i23.Future<String> broadcastNotificationTx( {required Map<String, dynamic>? preparedTx}) => (super.noSuchMethod( Invocation.method( @@ -1539,62 +1586,62 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { [], {#preparedTx: preparedTx}, ), - returnValue: _i22.Future<String>.value(''), - ) as _i22.Future<String>); + returnValue: _i23.Future<String>.value(''), + ) as _i23.Future<String>); @override - _i22.Future<bool> hasConnected(String? paymentCodeString) => + _i23.Future<bool> hasConnected(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #hasConnected, [paymentCodeString], ), - returnValue: _i22.Future<bool>.value(false), - ) as _i22.Future<bool>); + returnValue: _i23.Future<bool>.value(false), + ) as _i23.Future<bool>); @override - _i22.Future<_i18.PaymentCode?> unBlindedPaymentCodeFromTransaction( - {required _i17.Transaction? transaction}) => + _i23.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransaction( + {required _i18.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransaction, [], {#transaction: transaction}, ), - returnValue: _i22.Future<_i18.PaymentCode?>.value(), - ) as _i22.Future<_i18.PaymentCode?>); + returnValue: _i23.Future<_i19.PaymentCode?>.value(), + ) as _i23.Future<_i19.PaymentCode?>); @override - _i22.Future<_i18.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( - {required _i17.Transaction? transaction}) => + _i23.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( + {required _i18.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransactionBad, [], {#transaction: transaction}, ), - returnValue: _i22.Future<_i18.PaymentCode?>.value(), - ) as _i22.Future<_i18.PaymentCode?>); + returnValue: _i23.Future<_i19.PaymentCode?>.value(), + ) as _i23.Future<_i19.PaymentCode?>); @override - _i22.Future<List<_i18.PaymentCode>> + _i23.Future<List<_i19.PaymentCode>> getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod( Invocation.method( #getAllPaymentCodesFromNotificationTransactions, [], ), returnValue: - _i22.Future<List<_i18.PaymentCode>>.value(<_i18.PaymentCode>[]), - ) as _i22.Future<List<_i18.PaymentCode>>); + _i23.Future<List<_i19.PaymentCode>>.value(<_i19.PaymentCode>[]), + ) as _i23.Future<List<_i19.PaymentCode>>); @override - _i22.Future<void> checkForNotificationTransactionsTo( + _i23.Future<void> checkForNotificationTransactionsTo( Set<String>? otherCodeStrings) => (super.noSuchMethod( Invocation.method( #checkForNotificationTransactionsTo, [otherCodeStrings], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<void> restoreAllHistory({ + _i23.Future<void> restoreAllHistory({ required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, required Set<String>? paymentCodeStrings, @@ -1609,12 +1656,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { #paymentCodeStrings: paymentCodeStrings, }, ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<void> restoreHistoryWith({ - required _i18.PaymentCode? other, + _i23.Future<void> restoreHistoryWith({ + required _i19.PaymentCode? other, required bool? checkSegwitAsWell, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1630,58 +1677,58 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { #maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, }, ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<_i17.Address> getMyNotificationAddress() => (super.noSuchMethod( + _i23.Future<_i18.Address> getMyNotificationAddress() => (super.noSuchMethod( Invocation.method( #getMyNotificationAddress, [], ), - returnValue: _i22.Future<_i17.Address>.value(_FakeAddress_15( + returnValue: _i23.Future<_i18.Address>.value(_FakeAddress_16( this, Invocation.method( #getMyNotificationAddress, [], ), )), - ) as _i22.Future<_i17.Address>); + ) as _i23.Future<_i18.Address>); @override - _i22.Future<List<String>> lookupKey(String? paymentCodeString) => + _i23.Future<List<String>> lookupKey(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #lookupKey, [paymentCodeString], ), - returnValue: _i22.Future<List<String>>.value(<String>[]), - ) as _i22.Future<List<String>>); + returnValue: _i23.Future<List<String>>.value(<String>[]), + ) as _i23.Future<List<String>>); @override - _i22.Future<String?> paymentCodeStringByKey(String? key) => + _i23.Future<String?> paymentCodeStringByKey(String? key) => (super.noSuchMethod( Invocation.method( #paymentCodeStringByKey, [key], ), - returnValue: _i22.Future<String?>.value(), - ) as _i22.Future<String?>); + returnValue: _i23.Future<String?>.value(), + ) as _i23.Future<String?>); @override - _i22.Future<String> storeCode(String? paymentCodeString) => + _i23.Future<String> storeCode(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #storeCode, [paymentCodeString], ), - returnValue: _i22.Future<String>.value(''), - ) as _i22.Future<String>); + returnValue: _i23.Future<String>.value(''), + ) as _i23.Future<String>); @override void initCoinControlInterface({ required String? walletId, required String? walletName, - required _i21.Coin? coin, + required _i22.Coin? coin, required _i12.MainDB? db, - required _i22.Future<int> Function()? getChainHeight, - required _i22.Future<void> Function(_i11.Balance)? refreshedBalanceCallback, + required _i23.Future<int> Function()? getChainHeight, + required _i23.Future<void> Function(_i11.Balance)? refreshedBalanceCallback, }) => super.noSuchMethod( Invocation.method( @@ -1699,22 +1746,22 @@ class MockBitcoinWallet extends _i1.Mock implements _i25.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i22.Future<void> refreshBalance({bool? notify = false}) => + _i23.Future<void> refreshBalance({bool? notify = false}) => (super.noSuchMethod( Invocation.method( #refreshBalance, [], {#notify: notify}, ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); } /// A class which mocks [LocaleService]. /// /// See the documentation for Mockito's code generation for more information. -class MockLocaleService extends _i1.Mock implements _i30.LocaleService { +class MockLocaleService extends _i1.Mock implements _i31.LocaleService { MockLocaleService() { _i1.throwOnMissingStub(this); } @@ -1730,17 +1777,17 @@ class MockLocaleService extends _i1.Mock implements _i30.LocaleService { returnValue: false, ) as bool); @override - _i22.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( + _i23.Future<void> loadLocale({bool? notify = true}) => (super.noSuchMethod( Invocation.method( #loadLocale, [], {#notify: notify}, ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - void addListener(_i24.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i25.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -1748,7 +1795,7 @@ class MockLocaleService extends _i1.Mock implements _i30.LocaleService { returnValueForMissingStub: null, ); @override - void removeListener(_i24.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i25.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -1776,21 +1823,21 @@ class MockLocaleService extends _i1.Mock implements _i30.LocaleService { /// A class which mocks [ThemeService]. /// /// See the documentation for Mockito's code generation for more information. -class MockThemeService extends _i1.Mock implements _i31.ThemeService { +class MockThemeService extends _i1.Mock implements _i32.ThemeService { MockThemeService() { _i1.throwOnMissingStub(this); } @override - _i19.HTTP get client => (super.noSuchMethod( + _i20.HTTP get client => (super.noSuchMethod( Invocation.getter(#client), - returnValue: _FakeHTTP_17( + returnValue: _FakeHTTP_18( this, Invocation.getter(#client), ), - ) as _i19.HTTP); + ) as _i20.HTTP); @override - set client(_i19.HTTP? _client) => super.noSuchMethod( + set client(_i20.HTTP? _client) => super.noSuchMethod( Invocation.setter( #client, _client, @@ -1806,10 +1853,10 @@ class MockThemeService extends _i1.Mock implements _i31.ThemeService { ), ) as _i12.MainDB); @override - List<_i32.StackTheme> get installedThemes => (super.noSuchMethod( + List<_i33.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), - returnValue: <_i32.StackTheme>[], - ) as List<_i32.StackTheme>); + returnValue: <_i33.StackTheme>[], + ) as List<_i33.StackTheme>); @override void init(_i12.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -1819,71 +1866,71 @@ class MockThemeService extends _i1.Mock implements _i31.ThemeService { returnValueForMissingStub: null, ); @override - _i22.Future<void> install({required _i29.Uint8List? themeArchiveData}) => + _i23.Future<void> install({required _i30.Uint8List? themeArchiveData}) => (super.noSuchMethod( Invocation.method( #install, [], {#themeArchiveData: themeArchiveData}, ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<void> remove({required String? themeId}) => (super.noSuchMethod( + _i23.Future<void> remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( #remove, [], {#themeId: themeId}, ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( + _i23.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( #checkDefaultThemesOnStartup, [], ), - returnValue: _i22.Future<void>.value(), - returnValueForMissingStub: _i22.Future<void>.value(), - ) as _i22.Future<void>); + returnValue: _i23.Future<void>.value(), + returnValueForMissingStub: _i23.Future<void>.value(), + ) as _i23.Future<void>); @override - _i22.Future<bool> verifyInstalled({required String? themeId}) => + _i23.Future<bool> verifyInstalled({required String? themeId}) => (super.noSuchMethod( Invocation.method( #verifyInstalled, [], {#themeId: themeId}, ), - returnValue: _i22.Future<bool>.value(false), - ) as _i22.Future<bool>); + returnValue: _i23.Future<bool>.value(false), + ) as _i23.Future<bool>); @override - _i22.Future<List<_i31.StackThemeMetaData>> fetchThemes() => + _i23.Future<List<_i32.StackThemeMetaData>> fetchThemes() => (super.noSuchMethod( Invocation.method( #fetchThemes, [], ), - returnValue: _i22.Future<List<_i31.StackThemeMetaData>>.value( - <_i31.StackThemeMetaData>[]), - ) as _i22.Future<List<_i31.StackThemeMetaData>>); + returnValue: _i23.Future<List<_i32.StackThemeMetaData>>.value( + <_i32.StackThemeMetaData>[]), + ) as _i23.Future<List<_i32.StackThemeMetaData>>); @override - _i22.Future<_i29.Uint8List> fetchTheme( - {required _i31.StackThemeMetaData? themeMetaData}) => + _i23.Future<_i30.Uint8List> fetchTheme( + {required _i32.StackThemeMetaData? themeMetaData}) => (super.noSuchMethod( Invocation.method( #fetchTheme, [], {#themeMetaData: themeMetaData}, ), - returnValue: _i22.Future<_i29.Uint8List>.value(_i29.Uint8List(0)), - ) as _i22.Future<_i29.Uint8List>); + returnValue: _i23.Future<_i30.Uint8List>.value(_i30.Uint8List(0)), + ) as _i23.Future<_i30.Uint8List>); @override - _i32.StackTheme? getTheme({required String? themeId}) => + _i33.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( #getTheme, [], {#themeId: themeId}, - )) as _i32.StackTheme?); + )) as _i33.StackTheme?); } diff --git a/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart b/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart index ef519d4c9..392c6df41 100644 --- a/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart +++ b/test/widget_tests/wallet_info_row/sub_widgets/wallet_info_row_balance_future_test.mocks.dart @@ -3,12 +3,12 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i23; -import 'dart:typed_data' as _i29; -import 'dart:ui' as _i25; +import 'dart:async' as _i24; +import 'dart:typed_data' as _i30; +import 'dart:ui' as _i26; -import 'package:bip32/bip32.dart' as _i16; -import 'package:bip47/bip47.dart' as _i18; +import 'package:bip32/bip32.dart' as _i17; +import 'package:bip47/bip47.dart' as _i19; import 'package:bitcoindart/bitcoindart.dart' as _i13; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -17,25 +17,27 @@ import 'package:stackwallet/db/isar/main_db.dart' as _i12; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i10; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i11; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i17; -import 'package:stackwallet/models/node_model.dart' as _i30; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart' + as _i15; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i18; +import 'package:stackwallet/models/node_model.dart' as _i31; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i8; -import 'package:stackwallet/models/signing_data.dart' as _i28; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i26; -import 'package:stackwallet/services/coins/coin_service.dart' as _i20; +import 'package:stackwallet/models/signing_data.dart' as _i29; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i27; +import 'package:stackwallet/services/coins/coin_service.dart' as _i21; import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i7; -import 'package:stackwallet/services/wallets.dart' as _i21; +import 'package:stackwallet/services/wallets.dart' as _i22; import 'package:stackwallet/services/wallets_service.dart' as _i2; import 'package:stackwallet/utilities/amount/amount.dart' as _i14; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i22; -import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i27; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i23; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i28; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' - as _i19; -import 'package:stackwallet/utilities/prefs.dart' as _i24; -import 'package:tuple/tuple.dart' as _i15; + as _i20; +import 'package:stackwallet/utilities/prefs.dart' as _i25; +import 'package:tuple/tuple.dart' as _i16; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -182,9 +184,9 @@ class _FakeAmount_12 extends _i1.SmartFake implements _i14.Amount { ); } -class _FakeTuple2_13<T1, T2> extends _i1.SmartFake - implements _i15.Tuple2<T1, T2> { - _FakeTuple2_13( +class _FakeTransactionV2_13 extends _i1.SmartFake + implements _i15.TransactionV2 { + _FakeTransactionV2_13( Object parent, Invocation parentInvocation, ) : super( @@ -193,8 +195,9 @@ class _FakeTuple2_13<T1, T2> extends _i1.SmartFake ); } -class _FakeBIP32_14 extends _i1.SmartFake implements _i16.BIP32 { - _FakeBIP32_14( +class _FakeTuple2_14<T1, T2> extends _i1.SmartFake + implements _i16.Tuple2<T1, T2> { + _FakeTuple2_14( Object parent, Invocation parentInvocation, ) : super( @@ -203,8 +206,8 @@ class _FakeBIP32_14 extends _i1.SmartFake implements _i16.BIP32 { ); } -class _FakeAddress_15 extends _i1.SmartFake implements _i17.Address { - _FakeAddress_15( +class _FakeBIP32_15 extends _i1.SmartFake implements _i17.BIP32 { + _FakeBIP32_15( Object parent, Invocation parentInvocation, ) : super( @@ -213,8 +216,8 @@ class _FakeAddress_15 extends _i1.SmartFake implements _i17.Address { ); } -class _FakePaymentCode_16 extends _i1.SmartFake implements _i18.PaymentCode { - _FakePaymentCode_16( +class _FakeAddress_16 extends _i1.SmartFake implements _i18.Address { + _FakeAddress_16( Object parent, Invocation parentInvocation, ) : super( @@ -223,9 +226,8 @@ class _FakePaymentCode_16 extends _i1.SmartFake implements _i18.PaymentCode { ); } -class _FakeSecureStorageInterface_17 extends _i1.SmartFake - implements _i19.SecureStorageInterface { - _FakeSecureStorageInterface_17( +class _FakePaymentCode_17 extends _i1.SmartFake implements _i19.PaymentCode { + _FakePaymentCode_17( Object parent, Invocation parentInvocation, ) : super( @@ -234,9 +236,20 @@ class _FakeSecureStorageInterface_17 extends _i1.SmartFake ); } -class _FakeCoinServiceAPI_18 extends _i1.SmartFake - implements _i20.CoinServiceAPI { - _FakeCoinServiceAPI_18( +class _FakeSecureStorageInterface_18 extends _i1.SmartFake + implements _i20.SecureStorageInterface { + _FakeSecureStorageInterface_18( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_19 extends _i1.SmartFake + implements _i21.CoinServiceAPI { + _FakeCoinServiceAPI_19( Object parent, Invocation parentInvocation, ) : super( @@ -248,7 +261,7 @@ class _FakeCoinServiceAPI_18 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i21.Wallets { +class MockWallets extends _i1.Mock implements _i22.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -315,7 +328,7 @@ class MockWallets extends _i1.Mock implements _i21.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i22.Coin? coin}) => + List<String> getWalletIdsFor({required _i23.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -325,20 +338,20 @@ class MockWallets extends _i1.Mock implements _i21.Wallets { returnValue: <String>[], ) as List<String>); @override - List<_i15.Tuple2<_i22.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> + List<_i16.Tuple2<_i23.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i15.Tuple2<_i22.Coin, + returnValue: <_i16.Tuple2<_i23.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>[], ) as List< - _i15.Tuple2<_i22.Coin, + _i16.Tuple2<_i23.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i22.Coin? coin) => + _i23.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -402,17 +415,17 @@ class MockWallets extends _i1.Mock implements _i21.Wallets { returnValueForMissingStub: null, ); @override - _i23.Future<void> load(_i24.Prefs? prefs) => (super.noSuchMethod( + _i24.Future<void> load(_i25.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> loadAfterStackRestore( - _i24.Prefs? prefs, + _i24.Future<void> loadAfterStackRestore( + _i25.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -423,11 +436,11 @@ class MockWallets extends _i1.Mock implements _i21.Wallets { managers, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - void addListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -435,7 +448,7 @@ class MockWallets extends _i1.Mock implements _i21.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -461,19 +474,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i23.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i24.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i23.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i24.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i23.Future<Map<String, _i2.WalletInfo>>); + ) as _i24.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i23.Future<bool> renameWallet({ + _i24.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -488,8 +501,8 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override Map<String, _i2.WalletInfo> fetchWalletsData() => (super.noSuchMethod( Invocation.method( @@ -499,10 +512,10 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: <String, _i2.WalletInfo>{}, ) as Map<String, _i2.WalletInfo>); @override - _i23.Future<void> addExistingStackWallet({ + _i24.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i22.Coin? coin, + required _i23.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -516,13 +529,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<String?> addNewWallet({ + _i24.Future<String?> addNewWallet({ required String? name, - required _i22.Coin? coin, + required _i23.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -535,46 +548,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i24.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i23.Future<List<String>>.value(<String>[]), - ) as _i23.Future<List<String>>); + returnValue: _i24.Future<List<String>>.value(<String>[]), + ) as _i24.Future<List<String>>); @override - _i23.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i24.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i24.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i24.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> moveFavorite({ + _i24.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -587,48 +600,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i24.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i24.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<bool> isMnemonicVerified({required String? walletId}) => + _i24.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> setMnemonicVerified({required String? walletId}) => + _i24.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<int> deleteWallet( + _i24.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -640,20 +653,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override - _i23.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i24.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - void addListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -661,7 +674,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -689,13 +702,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i27.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i23.Timer? _timer) => super.noSuchMethod( + set timer(_i24.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -772,74 +785,74 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValue: false, ) as bool); @override - _i22.Coin get coin => (super.noSuchMethod( + _i23.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i22.Coin.bitcoin, - ) as _i22.Coin); + returnValue: _i23.Coin.bitcoin, + ) as _i23.Coin); @override - _i23.Future<List<_i17.UTXO>> get utxos => (super.noSuchMethod( + _i24.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i23.Future<List<_i17.UTXO>>.value(<_i17.UTXO>[]), - ) as _i23.Future<List<_i17.UTXO>>); + returnValue: _i24.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), + ) as _i24.Future<List<_i18.UTXO>>); @override - _i23.Future<List<_i17.Transaction>> get transactions => (super.noSuchMethod( + _i24.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i23.Future<List<_i17.Transaction>>.value(<_i17.Transaction>[]), - ) as _i23.Future<List<_i17.Transaction>>); + _i24.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), + ) as _i24.Future<List<_i18.Transaction>>); @override - _i23.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i24.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( + _i24.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( Invocation.getter(#currentChangeAddressP2PKH), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i23.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i24.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i23.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i24.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i23.Future<_i8.FeeObject>); + ) as _i24.Future<_i8.FeeObject>); @override - _i23.Future<int> get maxFee => (super.noSuchMethod( + _i24.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override - _i23.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i23.Future<List<String>>.value(<String>[]), - ) as _i23.Future<List<String>>); + returnValue: _i24.Future<List<String>>.value(<String>[]), + ) as _i24.Future<List<String>>); @override - _i23.Future<String?> get mnemonicString => (super.noSuchMethod( + _i24.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<int> get chainHeight => (super.noSuchMethod( + _i24.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -911,10 +924,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { ), ) as _i11.Balance); @override - _i23.Future<String> get xpub => (super.noSuchMethod( + _i24.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -941,26 +954,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { ), ) as _i13.NetworkType); @override - _i23.Future<void> exit() => (super.noSuchMethod( + _i24.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i27.DerivePathType addressType({required String? address}) => + _i28.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i27.DerivePathType.bip44, - ) as _i27.DerivePathType); + returnValue: _i28.DerivePathType.bip44, + ) as _i28.DerivePathType); @override - _i23.Future<void> recoverFromMnemonic({ + _i24.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -979,47 +992,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { #height: height, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i24.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i24.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i24.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> refresh() => (super.noSuchMethod( + _i24.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<Map<String, dynamic>> prepareSend({ + _i24.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i14.Amount? amount, Map<String, dynamic>? args, @@ -1035,26 +1048,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -1072,35 +1085,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future<void> initializeNew( + _i24.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> initializeExisting() => (super.noSuchMethod( + _i24.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i24.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1110,69 +1123,69 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValue: false, ) as bool); @override - _i23.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i24.Future<_i9.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), - returnValue: _i23.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_11( + returnValue: _i24.Future<_i9.ElectrumXNode>.value(_FakeElectrumXNode_11( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i23.Future<_i9.ElectrumXNode>); + ) as _i24.Future<_i9.ElectrumXNode>); @override - _i23.Future<List<Map<String, dynamic>>> fastFetch( + _i24.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i23.Future<List<Map<String, dynamic>>>.value( + returnValue: _i24.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i23.Future<List<Map<String, dynamic>>>); + ) as _i24.Future<List<Map<String, dynamic>>>); @override - _i23.Future<int> getTxCount({required String? address}) => + _i24.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override - _i23.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i24.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> checkCurrentChangeAddressesForTransactions() => + _i24.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1198,7 +1211,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { required bool? isSendAll, int? satsPerVByte, int? additionalOutputs = 0, - List<_i17.UTXO>? utxos, + List<_i18.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1215,19 +1228,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { }, )); @override - _i23.Future<List<_i28.SigningData>> fetchBuildTxData( - List<_i17.UTXO>? utxosToUse) => + _i24.Future<List<_i29.SigningData>> fetchBuildTxData( + List<_i18.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i23.Future<List<_i28.SigningData>>.value(<_i28.SigningData>[]), - ) as _i23.Future<List<_i28.SigningData>>); + _i24.Future<List<_i29.SigningData>>.value(<_i29.SigningData>[]), + ) as _i24.Future<List<_i29.SigningData>>); @override - _i23.Future<Map<String, dynamic>> buildTransaction({ - required List<_i28.SigningData>? utxoSigningData, + _i24.Future<Map<String, dynamic>> buildTransaction({ + required List<_i29.SigningData>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, }) => @@ -1242,10 +1255,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<void> fullRescan( + _i24.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1257,11 +1270,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i14.Amount> estimateFeeFor( + _i24.Future<_i14.Amount> estimateFeeFor( _i14.Amount? amount, int? feeRate, ) => @@ -1273,7 +1286,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { feeRate, ], ), - returnValue: _i23.Future<_i14.Amount>.value(_FakeAmount_12( + returnValue: _i24.Future<_i14.Amount>.value(_FakeAmount_12( this, Invocation.method( #estimateFeeFor, @@ -1283,7 +1296,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { ], ), )), - ) as _i23.Future<_i14.Amount>); + ) as _i24.Future<_i14.Amount>); @override _i14.Amount roughFeeEstimate( int? inputCount, @@ -1312,32 +1325,32 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { ), ) as _i14.Amount); @override - _i23.Future<_i14.Amount> sweepAllEstimate(int? feeRate) => + _i24.Future<_i14.Amount> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i23.Future<_i14.Amount>.value(_FakeAmount_12( + returnValue: _i24.Future<_i14.Amount>.value(_FakeAmount_12( this, Invocation.method( #sweepAllEstimate, [feeRate], ), )), - ) as _i23.Future<_i14.Amount>); + ) as _i24.Future<_i14.Amount>); @override - _i23.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override void initCache( String? walletId, - _i22.Coin? coin, + _i23.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1350,14 +1363,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i24.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1367,14 +1380,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValue: 0, ) as int); @override - _i23.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i24.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1384,15 +1397,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValue: false, ) as bool); @override - _i23.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i24.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override _i11.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1408,15 +1421,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { ), ) as _i11.Balance); @override - _i23.Future<void> updateCachedBalance(_i11.Balance? balance) => + _i24.Future<void> updateCachedBalance(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override _i11.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1432,15 +1445,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { ), ) as _i11.Balance); @override - _i23.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => + _i24.Future<void> updateCachedBalanceSecondary(_i11.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override List<String> getWalletTokenContractAddresses() => (super.noSuchMethod( Invocation.method( @@ -1450,16 +1463,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValue: <String>[], ) as List<String>); @override - _i23.Future<void> updateWalletTokenContractAddresses( + _i24.Future<void> updateWalletTokenContractAddresses( List<String>? contractAddresses) => (super.noSuchMethod( Invocation.method( #updateWalletTokenContractAddresses, [contractAddresses], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override void initWalletDB({_i12.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1470,11 +1483,45 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future<_i15.Tuple2<_i17.Transaction, _i17.Address>> parseTransaction( + _i24.Future<_i15.TransactionV2> getTransaction( + String? txHash, + _i23.Coin? coin, + String? walletId, + _i10.CachedElectrumX? cachedElectrumX, [ + String? debugTitle, + ]) => + (super.noSuchMethod( + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + returnValue: + _i24.Future<_i15.TransactionV2>.value(_FakeTransactionV2_13( + this, + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + )), + ) as _i24.Future<_i15.TransactionV2>); + @override + _i24.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>> parseTransaction( Map<String, dynamic>? txData, dynamic electrumxClient, - List<_i17.Address>? myAddresses, - _i22.Coin? coin, + List<_i18.Address>? myAddresses, + _i23.Coin? coin, int? minConfirms, String? walletId, ) => @@ -1491,8 +1538,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { ], ), returnValue: - _i23.Future<_i15.Tuple2<_i17.Transaction, _i17.Address>>.value( - _FakeTuple2_13<_i17.Transaction, _i17.Address>( + _i24.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>.value( + _FakeTuple2_14<_i18.Transaction, _i18.Address>( this, Invocation.method( #parseTransaction, @@ -1506,37 +1553,37 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { ], ), )), - ) as _i23.Future<_i15.Tuple2<_i17.Transaction, _i17.Address>>); + ) as _i24.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>); @override void initPaynymWalletInterface({ required String? walletId, required String? walletName, required _i13.NetworkType? network, - required _i22.Coin? coin, + required _i23.Coin? coin, required _i12.MainDB? db, required _i9.ElectrumX? electrumXClient, - required _i19.SecureStorageInterface? secureStorage, + required _i20.SecureStorageInterface? secureStorage, required int? dustLimit, required int? dustLimitP2PKH, required int? minConfirms, - required _i23.Future<String?> Function()? getMnemonicString, - required _i23.Future<String?> Function()? getMnemonicPassphrase, - required _i23.Future<int> Function()? getChainHeight, - required _i23.Future<String> Function()? getCurrentChangeAddress, + required _i24.Future<String?> Function()? getMnemonicString, + required _i24.Future<String?> Function()? getMnemonicPassphrase, + required _i24.Future<int> Function()? getChainHeight, + required _i24.Future<String> Function()? getCurrentChangeAddress, required int Function({ required int feeRatePerKB, required int vSize, })? estimateTxFee, - required _i23.Future<Map<String, dynamic>> Function({ + required _i24.Future<Map<String, dynamic>> Function({ required String address, required _i14.Amount amount, Map<String, dynamic>? args, })? prepareSend, - required _i23.Future<int> Function({required String address})? getTxCount, - required _i23.Future<List<_i28.SigningData>> Function(List<_i17.UTXO>)? + required _i24.Future<int> Function({required String address})? getTxCount, + required _i24.Future<List<_i29.SigningData>> Function(List<_i18.UTXO>)? fetchBuildTxData, - required _i23.Future<void> Function()? refresh, - required _i23.Future<void> Function()? checkChangeAddressForTransactions, + required _i24.Future<void> Function()? refresh, + required _i24.Future<void> Function()? checkChangeAddressForTransactions, }) => super.noSuchMethod( Invocation.method( @@ -1569,21 +1616,21 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future<_i16.BIP32> getBip47BaseNode() => (super.noSuchMethod( + _i24.Future<_i17.BIP32> getBip47BaseNode() => (super.noSuchMethod( Invocation.method( #getBip47BaseNode, [], ), - returnValue: _i23.Future<_i16.BIP32>.value(_FakeBIP32_14( + returnValue: _i24.Future<_i17.BIP32>.value(_FakeBIP32_15( this, Invocation.method( #getBip47BaseNode, [], ), )), - ) as _i23.Future<_i16.BIP32>); + ) as _i24.Future<_i17.BIP32>); @override - _i23.Future<_i29.Uint8List> getPrivateKeyForPaynymReceivingAddress({ + _i24.Future<_i30.Uint8List> getPrivateKeyForPaynymReceivingAddress({ required String? paymentCodeString, required int? index, }) => @@ -1596,11 +1643,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { #index: index, }, ), - returnValue: _i23.Future<_i29.Uint8List>.value(_i29.Uint8List(0)), - ) as _i23.Future<_i29.Uint8List>); + returnValue: _i24.Future<_i30.Uint8List>.value(_i30.Uint8List(0)), + ) as _i24.Future<_i30.Uint8List>); @override - _i23.Future<_i17.Address> currentReceivingPaynymAddress({ - required _i18.PaymentCode? sender, + _i24.Future<_i18.Address> currentReceivingPaynymAddress({ + required _i19.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1612,7 +1659,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i23.Future<_i17.Address>.value(_FakeAddress_15( + returnValue: _i24.Future<_i18.Address>.value(_FakeAddress_16( this, Invocation.method( #currentReceivingPaynymAddress, @@ -1623,10 +1670,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { }, ), )), - ) as _i23.Future<_i17.Address>); + ) as _i24.Future<_i18.Address>); @override - _i23.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ - required _i18.PaymentCode? sender, + _i24.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ + required _i19.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1638,42 +1685,42 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => + _i24.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkAllCurrentReceivingPaynymAddressesForTransactions, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i16.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( + _i24.Future<_i17.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( Invocation.method( #deriveNotificationBip32Node, [], ), - returnValue: _i23.Future<_i16.BIP32>.value(_FakeBIP32_14( + returnValue: _i24.Future<_i17.BIP32>.value(_FakeBIP32_15( this, Invocation.method( #deriveNotificationBip32Node, [], ), )), - ) as _i23.Future<_i16.BIP32>); + ) as _i24.Future<_i17.BIP32>); @override - _i23.Future<_i18.PaymentCode> getPaymentCode({required bool? isSegwit}) => + _i24.Future<_i19.PaymentCode> getPaymentCode({required bool? isSegwit}) => (super.noSuchMethod( Invocation.method( #getPaymentCode, [], {#isSegwit: isSegwit}, ), - returnValue: _i23.Future<_i18.PaymentCode>.value(_FakePaymentCode_16( + returnValue: _i24.Future<_i19.PaymentCode>.value(_FakePaymentCode_17( this, Invocation.method( #getPaymentCode, @@ -1681,28 +1728,28 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { {#isSegwit: isSegwit}, ), )), - ) as _i23.Future<_i18.PaymentCode>); + ) as _i24.Future<_i19.PaymentCode>); @override - _i23.Future<_i29.Uint8List> signWithNotificationKey(_i29.Uint8List? data) => + _i24.Future<_i30.Uint8List> signWithNotificationKey(_i30.Uint8List? data) => (super.noSuchMethod( Invocation.method( #signWithNotificationKey, [data], ), - returnValue: _i23.Future<_i29.Uint8List>.value(_i29.Uint8List(0)), - ) as _i23.Future<_i29.Uint8List>); + returnValue: _i24.Future<_i30.Uint8List>.value(_i30.Uint8List(0)), + ) as _i24.Future<_i30.Uint8List>); @override - _i23.Future<String> signStringWithNotificationKey(String? data) => + _i24.Future<String> signStringWithNotificationKey(String? data) => (super.noSuchMethod( Invocation.method( #signStringWithNotificationKey, [data], ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<Map<String, dynamic>> preparePaymentCodeSend({ - required _i18.PaymentCode? paymentCode, + _i24.Future<Map<String, dynamic>> preparePaymentCodeSend({ + required _i19.PaymentCode? paymentCode, required bool? isSegwit, required _i14.Amount? amount, Map<String, dynamic>? args, @@ -1719,13 +1766,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<_i17.Address> nextUnusedSendAddressFrom({ - required _i18.PaymentCode? pCode, + _i24.Future<_i18.Address> nextUnusedSendAddressFrom({ + required _i19.PaymentCode? pCode, required bool? isSegwit, - required _i16.BIP32? privateKeyNode, + required _i17.BIP32? privateKeyNode, int? startIndex = 0, }) => (super.noSuchMethod( @@ -1739,7 +1786,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { #startIndex: startIndex, }, ), - returnValue: _i23.Future<_i17.Address>.value(_FakeAddress_15( + returnValue: _i24.Future<_i18.Address>.value(_FakeAddress_16( this, Invocation.method( #nextUnusedSendAddressFrom, @@ -1752,13 +1799,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { }, ), )), - ) as _i23.Future<_i17.Address>); + ) as _i24.Future<_i18.Address>); @override - _i23.Future<Map<String, dynamic>> prepareNotificationTx({ + _i24.Future<Map<String, dynamic>> prepareNotificationTx({ required int? selectedTxFeeRate, required String? targetPaymentCodeString, int? additionalOutputs = 0, - List<_i17.UTXO>? utxos, + List<_i18.UTXO>? utxos, }) => (super.noSuchMethod( Invocation.method( @@ -1772,10 +1819,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<String> broadcastNotificationTx( + _i24.Future<String> broadcastNotificationTx( {required Map<String, dynamic>? preparedTx}) => (super.noSuchMethod( Invocation.method( @@ -1783,62 +1830,62 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { [], {#preparedTx: preparedTx}, ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<bool> hasConnected(String? paymentCodeString) => + _i24.Future<bool> hasConnected(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #hasConnected, [paymentCodeString], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<_i18.PaymentCode?> unBlindedPaymentCodeFromTransaction( - {required _i17.Transaction? transaction}) => + _i24.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransaction( + {required _i18.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransaction, [], {#transaction: transaction}, ), - returnValue: _i23.Future<_i18.PaymentCode?>.value(), - ) as _i23.Future<_i18.PaymentCode?>); + returnValue: _i24.Future<_i19.PaymentCode?>.value(), + ) as _i24.Future<_i19.PaymentCode?>); @override - _i23.Future<_i18.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( - {required _i17.Transaction? transaction}) => + _i24.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( + {required _i18.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransactionBad, [], {#transaction: transaction}, ), - returnValue: _i23.Future<_i18.PaymentCode?>.value(), - ) as _i23.Future<_i18.PaymentCode?>); + returnValue: _i24.Future<_i19.PaymentCode?>.value(), + ) as _i24.Future<_i19.PaymentCode?>); @override - _i23.Future<List<_i18.PaymentCode>> + _i24.Future<List<_i19.PaymentCode>> getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod( Invocation.method( #getAllPaymentCodesFromNotificationTransactions, [], ), returnValue: - _i23.Future<List<_i18.PaymentCode>>.value(<_i18.PaymentCode>[]), - ) as _i23.Future<List<_i18.PaymentCode>>); + _i24.Future<List<_i19.PaymentCode>>.value(<_i19.PaymentCode>[]), + ) as _i24.Future<List<_i19.PaymentCode>>); @override - _i23.Future<void> checkForNotificationTransactionsTo( + _i24.Future<void> checkForNotificationTransactionsTo( Set<String>? otherCodeStrings) => (super.noSuchMethod( Invocation.method( #checkForNotificationTransactionsTo, [otherCodeStrings], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> restoreAllHistory({ + _i24.Future<void> restoreAllHistory({ required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, required Set<String>? paymentCodeStrings, @@ -1853,12 +1900,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { #paymentCodeStrings: paymentCodeStrings, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> restoreHistoryWith({ - required _i18.PaymentCode? other, + _i24.Future<void> restoreHistoryWith({ + required _i19.PaymentCode? other, required bool? checkSegwitAsWell, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -1874,58 +1921,58 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { #maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i17.Address> getMyNotificationAddress() => (super.noSuchMethod( + _i24.Future<_i18.Address> getMyNotificationAddress() => (super.noSuchMethod( Invocation.method( #getMyNotificationAddress, [], ), - returnValue: _i23.Future<_i17.Address>.value(_FakeAddress_15( + returnValue: _i24.Future<_i18.Address>.value(_FakeAddress_16( this, Invocation.method( #getMyNotificationAddress, [], ), )), - ) as _i23.Future<_i17.Address>); + ) as _i24.Future<_i18.Address>); @override - _i23.Future<List<String>> lookupKey(String? paymentCodeString) => + _i24.Future<List<String>> lookupKey(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #lookupKey, [paymentCodeString], ), - returnValue: _i23.Future<List<String>>.value(<String>[]), - ) as _i23.Future<List<String>>); + returnValue: _i24.Future<List<String>>.value(<String>[]), + ) as _i24.Future<List<String>>); @override - _i23.Future<String?> paymentCodeStringByKey(String? key) => + _i24.Future<String?> paymentCodeStringByKey(String? key) => (super.noSuchMethod( Invocation.method( #paymentCodeStringByKey, [key], ), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<String> storeCode(String? paymentCodeString) => + _i24.Future<String> storeCode(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #storeCode, [paymentCodeString], ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override void initCoinControlInterface({ required String? walletId, required String? walletName, - required _i22.Coin? coin, + required _i23.Coin? coin, required _i12.MainDB? db, - required _i23.Future<int> Function()? getChainHeight, - required _i23.Future<void> Function(_i11.Balance)? refreshedBalanceCallback, + required _i24.Future<int> Function()? getChainHeight, + required _i24.Future<void> Function(_i11.Balance)? refreshedBalanceCallback, }) => super.noSuchMethod( Invocation.method( @@ -1943,16 +1990,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i23.Future<void> refreshBalance({bool? notify = false}) => + _i24.Future<void> refreshBalance({bool? notify = false}) => (super.noSuchMethod( Invocation.method( #refreshBalance, [], {#notify: notify}, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); } /// A class which mocks [NodeService]. @@ -1960,41 +2007,41 @@ class MockBitcoinWallet extends _i1.Mock implements _i26.BitcoinWallet { /// See the documentation for Mockito's code generation for more information. class MockNodeService extends _i1.Mock implements _i3.NodeService { @override - _i19.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( + _i20.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( Invocation.getter(#secureStorageInterface), - returnValue: _FakeSecureStorageInterface_17( + returnValue: _FakeSecureStorageInterface_18( this, Invocation.getter(#secureStorageInterface), ), - ) as _i19.SecureStorageInterface); + ) as _i20.SecureStorageInterface); @override - List<_i30.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i31.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i30.NodeModel>[], - ) as List<_i30.NodeModel>); + returnValue: <_i31.NodeModel>[], + ) as List<_i31.NodeModel>); @override - List<_i30.NodeModel> get nodes => (super.noSuchMethod( + List<_i31.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i30.NodeModel>[], - ) as List<_i30.NodeModel>); + returnValue: <_i31.NodeModel>[], + ) as List<_i31.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i23.Future<void> updateDefaults() => (super.noSuchMethod( + _i24.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> setPrimaryNodeFor({ - required _i22.Coin? coin, - required _i30.NodeModel? node, + _i24.Future<void> setPrimaryNodeFor({ + required _i23.Coin? coin, + required _i31.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -2007,44 +2054,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i30.NodeModel? getPrimaryNodeFor({required _i22.Coin? coin}) => + _i31.NodeModel? getPrimaryNodeFor({required _i23.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i30.NodeModel?); + )) as _i31.NodeModel?); @override - List<_i30.NodeModel> getNodesFor(_i22.Coin? coin) => (super.noSuchMethod( + List<_i31.NodeModel> getNodesFor(_i23.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i30.NodeModel>[], - ) as List<_i30.NodeModel>); + returnValue: <_i31.NodeModel>[], + ) as List<_i31.NodeModel>); @override - _i30.NodeModel? getNodeById({required String? id}) => + _i31.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i30.NodeModel?); + )) as _i31.NodeModel?); @override - List<_i30.NodeModel> failoverNodesFor({required _i22.Coin? coin}) => + List<_i31.NodeModel> failoverNodesFor({required _i23.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i30.NodeModel>[], - ) as List<_i30.NodeModel>); + returnValue: <_i31.NodeModel>[], + ) as List<_i31.NodeModel>); @override - _i23.Future<void> add( - _i30.NodeModel? node, + _i24.Future<void> add( + _i31.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -2057,11 +2104,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> delete( + _i24.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -2073,11 +2120,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> setEnabledState( + _i24.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -2091,12 +2138,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> edit( - _i30.NodeModel? editedNode, + _i24.Future<void> edit( + _i31.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -2109,20 +2156,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i24.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - void addListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2130,7 +2177,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2173,23 +2220,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i20.CoinServiceAPI get wallet => (super.noSuchMethod( + _i21.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_18( + returnValue: _FakeCoinServiceAPI_19( this, Invocation.getter(#wallet), ), - ) as _i20.CoinServiceAPI); + ) as _i21.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i22.Coin get coin => (super.noSuchMethod( + _i23.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i22.Coin.bitcoin, - ) as _i22.Coin); + returnValue: _i23.Coin.bitcoin, + ) as _i23.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2222,23 +2269,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i23.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i24.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i23.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i24.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i23.Future<_i8.FeeObject>); + ) as _i24.Future<_i8.FeeObject>); @override - _i23.Future<int> get maxFee => (super.noSuchMethod( + _i24.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override - _i23.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2248,16 +2295,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i11.Balance); @override - _i23.Future<List<_i17.Transaction>> get transactions => (super.noSuchMethod( + _i24.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i23.Future<List<_i17.Transaction>>.value(<_i17.Transaction>[]), - ) as _i23.Future<List<_i17.Transaction>>); + _i24.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), + ) as _i24.Future<List<_i18.Transaction>>); @override - _i23.Future<List<_i17.UTXO>> get utxos => (super.noSuchMethod( + _i24.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i23.Future<List<_i17.UTXO>>.value(<_i17.UTXO>[]), - ) as _i23.Future<List<_i17.UTXO>>); + returnValue: _i24.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), + ) as _i24.Future<List<_i18.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2277,15 +2324,15 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i23.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i23.Future<List<String>>.value(<String>[]), - ) as _i23.Future<List<String>>); + returnValue: _i24.Future<List<String>>.value(<String>[]), + ) as _i24.Future<List<String>>); @override - _i23.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -2322,6 +2369,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, @@ -2332,24 +2384,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i23.Future<String> get xpub => (super.noSuchMethod( + _i24.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i23.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -2359,7 +2411,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i23.Future<Map<String, dynamic>> prepareSend({ + _i24.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i14.Amount? amount, Map<String, dynamic>? args, @@ -2375,27 +2427,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<void> refresh() => (super.noSuchMethod( + _i24.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2405,35 +2457,35 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i23.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> initializeNew( + _i24.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> initializeExisting() => (super.noSuchMethod( + _i24.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> recoverFromMnemonic({ + _i24.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -2452,20 +2504,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i24.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> fullRescan( + _i24.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2477,11 +2529,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i14.Amount> estimateFeeFor( + _i24.Future<_i14.Amount> estimateFeeFor( _i14.Amount? amount, int? feeRate, ) => @@ -2493,7 +2545,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i23.Future<_i14.Amount>.value(_FakeAmount_12( + returnValue: _i24.Future<_i14.Amount>.value(_FakeAmount_12( this, Invocation.method( #estimateFeeFor, @@ -2503,26 +2555,26 @@ class MockManager extends _i1.Mock implements _i6.Manager { ], ), )), - ) as _i23.Future<_i14.Amount>); + ) as _i24.Future<_i14.Amount>); @override - _i23.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> resetRescanOnOpen() => (super.noSuchMethod( + _i24.Future<void> resetRescanOnOpen() => (super.noSuchMethod( Invocation.method( #resetRescanOnOpen, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - void addListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2530,7 +2582,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i25.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2550,7 +2602,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -2561,10 +2613,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i22.Coin get coin => (super.noSuchMethod( + _i23.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i22.Coin.bitcoin, - ) as _i22.Coin); + returnValue: _i23.Coin.bitcoin, + ) as _i23.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2597,23 +2649,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i23.Future<_i8.FeeObject> get fees => (super.noSuchMethod( + _i24.Future<_i8.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i23.Future<_i8.FeeObject>.value(_FakeFeeObject_5( + returnValue: _i24.Future<_i8.FeeObject>.value(_FakeFeeObject_5( this, Invocation.getter(#fees), )), - ) as _i23.Future<_i8.FeeObject>); + ) as _i24.Future<_i8.FeeObject>); @override - _i23.Future<int> get maxFee => (super.noSuchMethod( + _i24.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i23.Future<int>.value(0), - ) as _i23.Future<int>); + returnValue: _i24.Future<int>.value(0), + ) as _i24.Future<int>); @override - _i23.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override _i11.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2623,16 +2675,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { ), ) as _i11.Balance); @override - _i23.Future<List<_i17.Transaction>> get transactions => (super.noSuchMethod( + _i24.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i23.Future<List<_i17.Transaction>>.value(<_i17.Transaction>[]), - ) as _i23.Future<List<_i17.Transaction>>); + _i24.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), + ) as _i24.Future<List<_i18.Transaction>>); @override - _i23.Future<List<_i17.UTXO>> get utxos => (super.noSuchMethod( + _i24.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i23.Future<List<_i17.UTXO>>.value(<_i17.UTXO>[]), - ) as _i23.Future<List<_i17.UTXO>>); + returnValue: _i24.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), + ) as _i24.Future<List<_i18.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2652,20 +2704,20 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValue: '', ) as String); @override - _i23.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i23.Future<List<String>>.value(<String>[]), - ) as _i23.Future<List<String>>); + returnValue: _i24.Future<List<String>>.value(<String>[]), + ) as _i24.Future<List<String>>); @override - _i23.Future<String?> get mnemonicString => (super.noSuchMethod( + _i24.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override - _i23.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i23.Future<String?>.value(), - ) as _i23.Future<String?>); + returnValue: _i24.Future<String?>.value(), + ) as _i24.Future<String?>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -2682,7 +2734,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValue: 0, ) as int); @override - _i23.Future<Map<String, dynamic>> prepareSend({ + _i24.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i14.Amount? amount, Map<String, dynamic>? args, @@ -2698,36 +2750,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { }, ), returnValue: - _i23.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i23.Future<Map<String, dynamic>>); + _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i24.Future<Map<String, dynamic>>); @override - _i23.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i23.Future<String>.value(''), - ) as _i23.Future<String>); + returnValue: _i24.Future<String>.value(''), + ) as _i24.Future<String>); @override - _i23.Future<void> refresh() => (super.noSuchMethod( + _i24.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2737,15 +2789,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { returnValue: false, ) as bool); @override - _i23.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> recoverFromMnemonic({ + _i24.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -2764,40 +2816,40 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { #height: height, }, ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> initializeNew( + _i24.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> initializeExisting() => (super.noSuchMethod( + _i24.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> exit() => (super.noSuchMethod( + _i24.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<void> fullRescan( + _i24.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2809,11 +2861,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); @override - _i23.Future<_i14.Amount> estimateFeeFor( + _i24.Future<_i14.Amount> estimateFeeFor( _i14.Amount? amount, int? feeRate, ) => @@ -2825,7 +2877,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { feeRate, ], ), - returnValue: _i23.Future<_i14.Amount>.value(_FakeAmount_12( + returnValue: _i24.Future<_i14.Amount>.value(_FakeAmount_12( this, Invocation.method( #estimateFeeFor, @@ -2835,23 +2887,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i20.CoinServiceAPI { ], ), )), - ) as _i23.Future<_i14.Amount>); + ) as _i24.Future<_i14.Amount>); @override - _i23.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i23.Future<bool>.value(false), - ) as _i23.Future<bool>); + returnValue: _i24.Future<bool>.value(false), + ) as _i24.Future<bool>); @override - _i23.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i24.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i23.Future<void>.value(), - returnValueForMissingStub: _i23.Future<void>.value(), - ) as _i23.Future<void>); + returnValue: _i24.Future<void>.value(), + returnValueForMissingStub: _i24.Future<void>.value(), + ) as _i24.Future<void>); } diff --git a/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart b/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart index 7a14a4547..475b3a4e4 100644 --- a/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart +++ b/test/widget_tests/wallet_info_row/wallet_info_row_test.mocks.dart @@ -3,12 +3,12 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i24; -import 'dart:typed_data' as _i29; -import 'dart:ui' as _i26; +import 'dart:async' as _i25; +import 'dart:typed_data' as _i30; +import 'dart:ui' as _i27; -import 'package:bip32/bip32.dart' as _i17; -import 'package:bip47/bip47.dart' as _i19; +import 'package:bip32/bip32.dart' as _i18; +import 'package:bip47/bip47.dart' as _i20; import 'package:bitcoindart/bitcoindart.dart' as _i14; import 'package:flutter/foundation.dart' as _i4; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; @@ -17,28 +17,30 @@ import 'package:stackwallet/db/isar/main_db.dart' as _i8; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i12; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i11; import 'package:stackwallet/models/balance.dart' as _i13; -import 'package:stackwallet/models/isar/models/isar_models.dart' as _i18; -import 'package:stackwallet/models/isar/stack_theme.dart' as _i28; -import 'package:stackwallet/models/node_model.dart' as _i33; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart' + as _i16; +import 'package:stackwallet/models/isar/models/isar_models.dart' as _i19; +import 'package:stackwallet/models/isar/stack_theme.dart' as _i29; +import 'package:stackwallet/models/node_model.dart' as _i34; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i10; -import 'package:stackwallet/models/signing_data.dart' as _i32; +import 'package:stackwallet/models/signing_data.dart' as _i33; import 'package:stackwallet/networking/http.dart' as _i7; -import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i30; -import 'package:stackwallet/services/coins/coin_service.dart' as _i21; +import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i31; +import 'package:stackwallet/services/coins/coin_service.dart' as _i22; import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/transaction_notification_tracker.dart' as _i9; -import 'package:stackwallet/services/wallets.dart' as _i22; +import 'package:stackwallet/services/wallets.dart' as _i23; import 'package:stackwallet/services/wallets_service.dart' as _i2; -import 'package:stackwallet/themes/theme_service.dart' as _i27; +import 'package:stackwallet/themes/theme_service.dart' as _i28; import 'package:stackwallet/utilities/amount/amount.dart' as _i15; -import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i23; -import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i31; +import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i24; +import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i32; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' - as _i20; -import 'package:stackwallet/utilities/prefs.dart' as _i25; -import 'package:tuple/tuple.dart' as _i16; + as _i21; +import 'package:stackwallet/utilities/prefs.dart' as _i26; +import 'package:tuple/tuple.dart' as _i17; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -196,9 +198,9 @@ class _FakeAmount_13 extends _i1.SmartFake implements _i15.Amount { ); } -class _FakeTuple2_14<T1, T2> extends _i1.SmartFake - implements _i16.Tuple2<T1, T2> { - _FakeTuple2_14( +class _FakeTransactionV2_14 extends _i1.SmartFake + implements _i16.TransactionV2 { + _FakeTransactionV2_14( Object parent, Invocation parentInvocation, ) : super( @@ -207,8 +209,9 @@ class _FakeTuple2_14<T1, T2> extends _i1.SmartFake ); } -class _FakeBIP32_15 extends _i1.SmartFake implements _i17.BIP32 { - _FakeBIP32_15( +class _FakeTuple2_15<T1, T2> extends _i1.SmartFake + implements _i17.Tuple2<T1, T2> { + _FakeTuple2_15( Object parent, Invocation parentInvocation, ) : super( @@ -217,8 +220,8 @@ class _FakeBIP32_15 extends _i1.SmartFake implements _i17.BIP32 { ); } -class _FakeAddress_16 extends _i1.SmartFake implements _i18.Address { - _FakeAddress_16( +class _FakeBIP32_16 extends _i1.SmartFake implements _i18.BIP32 { + _FakeBIP32_16( Object parent, Invocation parentInvocation, ) : super( @@ -227,8 +230,8 @@ class _FakeAddress_16 extends _i1.SmartFake implements _i18.Address { ); } -class _FakePaymentCode_17 extends _i1.SmartFake implements _i19.PaymentCode { - _FakePaymentCode_17( +class _FakeAddress_17 extends _i1.SmartFake implements _i19.Address { + _FakeAddress_17( Object parent, Invocation parentInvocation, ) : super( @@ -237,9 +240,8 @@ class _FakePaymentCode_17 extends _i1.SmartFake implements _i19.PaymentCode { ); } -class _FakeSecureStorageInterface_18 extends _i1.SmartFake - implements _i20.SecureStorageInterface { - _FakeSecureStorageInterface_18( +class _FakePaymentCode_18 extends _i1.SmartFake implements _i20.PaymentCode { + _FakePaymentCode_18( Object parent, Invocation parentInvocation, ) : super( @@ -248,9 +250,20 @@ class _FakeSecureStorageInterface_18 extends _i1.SmartFake ); } -class _FakeCoinServiceAPI_19 extends _i1.SmartFake - implements _i21.CoinServiceAPI { - _FakeCoinServiceAPI_19( +class _FakeSecureStorageInterface_19 extends _i1.SmartFake + implements _i21.SecureStorageInterface { + _FakeSecureStorageInterface_19( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCoinServiceAPI_20 extends _i1.SmartFake + implements _i22.CoinServiceAPI { + _FakeCoinServiceAPI_20( Object parent, Invocation parentInvocation, ) : super( @@ -262,7 +275,7 @@ class _FakeCoinServiceAPI_19 extends _i1.SmartFake /// A class which mocks [Wallets]. /// /// See the documentation for Mockito's code generation for more information. -class MockWallets extends _i1.Mock implements _i22.Wallets { +class MockWallets extends _i1.Mock implements _i23.Wallets { MockWallets() { _i1.throwOnMissingStub(this); } @@ -329,7 +342,7 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValueForMissingStub: null, ); @override - List<String> getWalletIdsFor({required _i23.Coin? coin}) => + List<String> getWalletIdsFor({required _i24.Coin? coin}) => (super.noSuchMethod( Invocation.method( #getWalletIdsFor, @@ -339,20 +352,20 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValue: <String>[], ) as List<String>); @override - List<_i16.Tuple2<_i23.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> + List<_i17.Tuple2<_i24.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>> getManagerProvidersByCoin() => (super.noSuchMethod( Invocation.method( #getManagerProvidersByCoin, [], ), - returnValue: <_i16.Tuple2<_i23.Coin, + returnValue: <_i17.Tuple2<_i24.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>[], ) as List< - _i16.Tuple2<_i23.Coin, + _i17.Tuple2<_i24.Coin, List<_i5.ChangeNotifierProvider<_i6.Manager>>>>); @override List<_i5.ChangeNotifierProvider<_i6.Manager>> getManagerProvidersForCoin( - _i23.Coin? coin) => + _i24.Coin? coin) => (super.noSuchMethod( Invocation.method( #getManagerProvidersForCoin, @@ -416,17 +429,17 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValueForMissingStub: null, ); @override - _i24.Future<void> load(_i25.Prefs? prefs) => (super.noSuchMethod( + _i25.Future<void> load(_i26.Prefs? prefs) => (super.noSuchMethod( Invocation.method( #load, [prefs], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> loadAfterStackRestore( - _i25.Prefs? prefs, + _i25.Future<void> loadAfterStackRestore( + _i26.Prefs? prefs, List<_i6.Manager>? managers, ) => (super.noSuchMethod( @@ -437,11 +450,11 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { managers, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i27.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -449,7 +462,7 @@ class MockWallets extends _i1.Mock implements _i22.Wallets { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i27.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -475,19 +488,19 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { } @override - _i24.Future<Map<String, _i2.WalletInfo>> get walletNames => + _i25.Future<Map<String, _i2.WalletInfo>> get walletNames => (super.noSuchMethod( Invocation.getter(#walletNames), - returnValue: _i24.Future<Map<String, _i2.WalletInfo>>.value( + returnValue: _i25.Future<Map<String, _i2.WalletInfo>>.value( <String, _i2.WalletInfo>{}), - ) as _i24.Future<Map<String, _i2.WalletInfo>>); + ) as _i25.Future<Map<String, _i2.WalletInfo>>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i24.Future<bool> renameWallet({ + _i25.Future<bool> renameWallet({ required String? from, required String? to, required bool? shouldNotifyListeners, @@ -502,8 +515,8 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override Map<String, _i2.WalletInfo> fetchWalletsData() => (super.noSuchMethod( Invocation.method( @@ -513,10 +526,10 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValue: <String, _i2.WalletInfo>{}, ) as Map<String, _i2.WalletInfo>); @override - _i24.Future<void> addExistingStackWallet({ + _i25.Future<void> addExistingStackWallet({ required String? name, required String? walletId, - required _i23.Coin? coin, + required _i24.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -530,13 +543,13 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<String?> addNewWallet({ + _i25.Future<String?> addNewWallet({ required String? name, - required _i23.Coin? coin, + required _i24.Coin? coin, required bool? shouldNotifyListeners, }) => (super.noSuchMethod( @@ -549,46 +562,46 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i25.Future<String?>.value(), + ) as _i25.Future<String?>); @override - _i24.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( + _i25.Future<List<String>> getFavoriteWalletIds() => (super.noSuchMethod( Invocation.method( #getFavoriteWalletIds, [], ), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i25.Future<List<String>>.value(<String>[]), + ) as _i25.Future<List<String>>); @override - _i24.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => + _i25.Future<void> saveFavoriteWalletIds(List<String>? walletIds) => (super.noSuchMethod( Invocation.method( #saveFavoriteWalletIds, [walletIds], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( + _i25.Future<void> addFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #addFavorite, [walletId], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( + _i25.Future<void> removeFavorite(String? walletId) => (super.noSuchMethod( Invocation.method( #removeFavorite, [walletId], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> moveFavorite({ + _i25.Future<void> moveFavorite({ required int? fromIndex, required int? toIndex, }) => @@ -601,48 +614,48 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { #toIndex: toIndex, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( + _i25.Future<bool> checkForDuplicate(String? name) => (super.noSuchMethod( Invocation.method( #checkForDuplicate, [name], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override - _i24.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( + _i25.Future<String?> getWalletId(String? walletName) => (super.noSuchMethod( Invocation.method( #getWalletId, [walletName], ), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i25.Future<String?>.value(), + ) as _i25.Future<String?>); @override - _i24.Future<bool> isMnemonicVerified({required String? walletId}) => + _i25.Future<bool> isMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #isMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override - _i24.Future<void> setMnemonicVerified({required String? walletId}) => + _i25.Future<void> setMnemonicVerified({required String? walletId}) => (super.noSuchMethod( Invocation.method( #setMnemonicVerified, [], {#walletId: walletId}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<int> deleteWallet( + _i25.Future<int> deleteWallet( String? name, bool? shouldNotifyListeners, ) => @@ -654,20 +667,20 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i25.Future<int>.value(0), + ) as _i25.Future<int>); @override - _i24.Future<void> refreshWallets(bool? shouldNotifyListeners) => + _i25.Future<void> refreshWallets(bool? shouldNotifyListeners) => (super.noSuchMethod( Invocation.method( #refreshWallets, [shouldNotifyListeners], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i27.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -675,7 +688,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i27.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -703,7 +716,7 @@ class MockWalletsService extends _i1.Mock implements _i2.WalletsService { /// A class which mocks [ThemeService]. /// /// See the documentation for Mockito's code generation for more information. -class MockThemeService extends _i1.Mock implements _i27.ThemeService { +class MockThemeService extends _i1.Mock implements _i28.ThemeService { MockThemeService() { _i1.throwOnMissingStub(this); } @@ -733,10 +746,10 @@ class MockThemeService extends _i1.Mock implements _i27.ThemeService { ), ) as _i8.MainDB); @override - List<_i28.StackTheme> get installedThemes => (super.noSuchMethod( + List<_i29.StackTheme> get installedThemes => (super.noSuchMethod( Invocation.getter(#installedThemes), - returnValue: <_i28.StackTheme>[], - ) as List<_i28.StackTheme>); + returnValue: <_i29.StackTheme>[], + ) as List<_i29.StackTheme>); @override void init(_i8.MainDB? db) => super.noSuchMethod( Invocation.method( @@ -746,85 +759,85 @@ class MockThemeService extends _i1.Mock implements _i27.ThemeService { returnValueForMissingStub: null, ); @override - _i24.Future<void> install({required _i29.Uint8List? themeArchiveData}) => + _i25.Future<void> install({required _i30.Uint8List? themeArchiveData}) => (super.noSuchMethod( Invocation.method( #install, [], {#themeArchiveData: themeArchiveData}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> remove({required String? themeId}) => (super.noSuchMethod( + _i25.Future<void> remove({required String? themeId}) => (super.noSuchMethod( Invocation.method( #remove, [], {#themeId: themeId}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( + _i25.Future<void> checkDefaultThemesOnStartup() => (super.noSuchMethod( Invocation.method( #checkDefaultThemesOnStartup, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<bool> verifyInstalled({required String? themeId}) => + _i25.Future<bool> verifyInstalled({required String? themeId}) => (super.noSuchMethod( Invocation.method( #verifyInstalled, [], {#themeId: themeId}, ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override - _i24.Future<List<_i27.StackThemeMetaData>> fetchThemes() => + _i25.Future<List<_i28.StackThemeMetaData>> fetchThemes() => (super.noSuchMethod( Invocation.method( #fetchThemes, [], ), - returnValue: _i24.Future<List<_i27.StackThemeMetaData>>.value( - <_i27.StackThemeMetaData>[]), - ) as _i24.Future<List<_i27.StackThemeMetaData>>); + returnValue: _i25.Future<List<_i28.StackThemeMetaData>>.value( + <_i28.StackThemeMetaData>[]), + ) as _i25.Future<List<_i28.StackThemeMetaData>>); @override - _i24.Future<_i29.Uint8List> fetchTheme( - {required _i27.StackThemeMetaData? themeMetaData}) => + _i25.Future<_i30.Uint8List> fetchTheme( + {required _i28.StackThemeMetaData? themeMetaData}) => (super.noSuchMethod( Invocation.method( #fetchTheme, [], {#themeMetaData: themeMetaData}, ), - returnValue: _i24.Future<_i29.Uint8List>.value(_i29.Uint8List(0)), - ) as _i24.Future<_i29.Uint8List>); + returnValue: _i25.Future<_i30.Uint8List>.value(_i30.Uint8List(0)), + ) as _i25.Future<_i30.Uint8List>); @override - _i28.StackTheme? getTheme({required String? themeId}) => + _i29.StackTheme? getTheme({required String? themeId}) => (super.noSuchMethod(Invocation.method( #getTheme, [], {#themeId: themeId}, - )) as _i28.StackTheme?); + )) as _i29.StackTheme?); } /// A class which mocks [BitcoinWallet]. /// /// See the documentation for Mockito's code generation for more information. -class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { +class MockBitcoinWallet extends _i1.Mock implements _i31.BitcoinWallet { MockBitcoinWallet() { _i1.throwOnMissingStub(this); } @override - set timer(_i24.Timer? _timer) => super.noSuchMethod( + set timer(_i25.Timer? _timer) => super.noSuchMethod( Invocation.setter( #timer, _timer, @@ -901,74 +914,74 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { returnValue: false, ) as bool); @override - _i23.Coin get coin => (super.noSuchMethod( + _i24.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i23.Coin.bitcoin, - ) as _i23.Coin); + returnValue: _i24.Coin.bitcoin, + ) as _i24.Coin); @override - _i24.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( + _i25.Future<List<_i19.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i24.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), - ) as _i24.Future<List<_i18.UTXO>>); + returnValue: _i25.Future<List<_i19.UTXO>>.value(<_i19.UTXO>[]), + ) as _i25.Future<List<_i19.UTXO>>); @override - _i24.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( + _i25.Future<List<_i19.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i24.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), - ) as _i24.Future<List<_i18.Transaction>>); + _i25.Future<List<_i19.Transaction>>.value(<_i19.Transaction>[]), + ) as _i25.Future<List<_i19.Transaction>>); @override - _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i25.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override - _i24.Future<String> get currentChangeAddress => (super.noSuchMethod( + _i25.Future<String> get currentChangeAddress => (super.noSuchMethod( Invocation.getter(#currentChangeAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override - _i24.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( + _i25.Future<String> get currentChangeAddressP2PKH => (super.noSuchMethod( Invocation.getter(#currentChangeAddressP2PKH), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), returnValue: false, ) as bool); @override - _i24.Future<_i10.FeeObject> get fees => (super.noSuchMethod( + _i25.Future<_i10.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i24.Future<_i10.FeeObject>.value(_FakeFeeObject_7( + returnValue: _i25.Future<_i10.FeeObject>.value(_FakeFeeObject_7( this, Invocation.getter(#fees), )), - ) as _i24.Future<_i10.FeeObject>); + ) as _i25.Future<_i10.FeeObject>); @override - _i24.Future<int> get maxFee => (super.noSuchMethod( + _i25.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i25.Future<int>.value(0), + ) as _i25.Future<int>); @override - _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i25.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i25.Future<List<String>>.value(<String>[]), + ) as _i25.Future<List<String>>); @override - _i24.Future<String?> get mnemonicString => (super.noSuchMethod( + _i25.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i25.Future<String?>.value(), + ) as _i25.Future<String?>); @override - _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i25.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i25.Future<String?>.value(), + ) as _i25.Future<String?>); @override - _i24.Future<int> get chainHeight => (super.noSuchMethod( + _i25.Future<int> get chainHeight => (super.noSuchMethod( Invocation.getter(#chainHeight), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i25.Future<int>.value(0), + ) as _i25.Future<int>); @override int get storedChainHeight => (super.noSuchMethod( Invocation.getter(#storedChainHeight), @@ -1040,10 +1053,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { ), ) as _i13.Balance); @override - _i24.Future<String> get xpub => (super.noSuchMethod( + _i25.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -1070,26 +1083,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { ), ) as _i14.NetworkType); @override - _i24.Future<void> exit() => (super.noSuchMethod( + _i25.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i31.DerivePathType addressType({required String? address}) => + _i32.DerivePathType addressType({required String? address}) => (super.noSuchMethod( Invocation.method( #addressType, [], {#address: address}, ), - returnValue: _i31.DerivePathType.bip44, - ) as _i31.DerivePathType); + returnValue: _i32.DerivePathType.bip44, + ) as _i32.DerivePathType); @override - _i24.Future<void> recoverFromMnemonic({ + _i25.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -1108,47 +1121,47 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { #height: height, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => + _i25.Future<void> getTransactionCacheEarly(List<String>? allAddresses) => (super.noSuchMethod( Invocation.method( #getTransactionCacheEarly, [allAddresses], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( + _i25.Future<bool> refreshIfThereIsNewData() => (super.noSuchMethod( Invocation.method( #refreshIfThereIsNewData, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override - _i24.Future<void> getAllTxsToWatch() => (super.noSuchMethod( + _i25.Future<void> getAllTxsToWatch() => (super.noSuchMethod( Invocation.method( #getAllTxsToWatch, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> refresh() => (super.noSuchMethod( + _i25.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<Map<String, dynamic>> prepareSend({ + _i25.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -1164,26 +1177,26 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i25.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i25.Future<Map<String, dynamic>>); @override - _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i25.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override - _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i25.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override void startNetworkAlivePinging() => super.noSuchMethod( Invocation.method( @@ -1201,35 +1214,35 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<void> initializeNew( + _i25.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> initializeExisting() => (super.noSuchMethod( + _i25.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i25.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -1239,70 +1252,70 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { returnValue: false, ) as bool); @override - _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i25.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<_i11.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( + _i25.Future<_i11.ElectrumXNode> getCurrentNode() => (super.noSuchMethod( Invocation.method( #getCurrentNode, [], ), returnValue: - _i24.Future<_i11.ElectrumXNode>.value(_FakeElectrumXNode_12( + _i25.Future<_i11.ElectrumXNode>.value(_FakeElectrumXNode_12( this, Invocation.method( #getCurrentNode, [], ), )), - ) as _i24.Future<_i11.ElectrumXNode>); + ) as _i25.Future<_i11.ElectrumXNode>); @override - _i24.Future<List<Map<String, dynamic>>> fastFetch( + _i25.Future<List<Map<String, dynamic>>> fastFetch( List<String>? allTxHashes) => (super.noSuchMethod( Invocation.method( #fastFetch, [allTxHashes], ), - returnValue: _i24.Future<List<Map<String, dynamic>>>.value( + returnValue: _i25.Future<List<Map<String, dynamic>>>.value( <Map<String, dynamic>>[]), - ) as _i24.Future<List<Map<String, dynamic>>>); + ) as _i25.Future<List<Map<String, dynamic>>>); @override - _i24.Future<int> getTxCount({required String? address}) => + _i25.Future<int> getTxCount({required String? address}) => (super.noSuchMethod( Invocation.method( #getTxCount, [], {#address: address}, ), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i25.Future<int>.value(0), + ) as _i25.Future<int>); @override - _i24.Future<void> checkCurrentReceivingAddressesForTransactions() => + _i25.Future<void> checkCurrentReceivingAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentReceivingAddressesForTransactions, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> checkCurrentChangeAddressesForTransactions() => + _i25.Future<void> checkCurrentChangeAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkCurrentChangeAddressesForTransactions, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override int estimateTxFee({ required int? vSize, @@ -1328,7 +1341,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { required bool? isSendAll, int? satsPerVByte, int? additionalOutputs = 0, - List<_i18.UTXO>? utxos, + List<_i19.UTXO>? utxos, }) => super.noSuchMethod(Invocation.method( #coinSelection, @@ -1345,19 +1358,19 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { }, )); @override - _i24.Future<List<_i32.SigningData>> fetchBuildTxData( - List<_i18.UTXO>? utxosToUse) => + _i25.Future<List<_i33.SigningData>> fetchBuildTxData( + List<_i19.UTXO>? utxosToUse) => (super.noSuchMethod( Invocation.method( #fetchBuildTxData, [utxosToUse], ), returnValue: - _i24.Future<List<_i32.SigningData>>.value(<_i32.SigningData>[]), - ) as _i24.Future<List<_i32.SigningData>>); + _i25.Future<List<_i33.SigningData>>.value(<_i33.SigningData>[]), + ) as _i25.Future<List<_i33.SigningData>>); @override - _i24.Future<Map<String, dynamic>> buildTransaction({ - required List<_i32.SigningData>? utxoSigningData, + _i25.Future<Map<String, dynamic>> buildTransaction({ + required List<_i33.SigningData>? utxoSigningData, required List<String>? recipients, required List<int>? satoshiAmounts, }) => @@ -1372,10 +1385,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i25.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i25.Future<Map<String, dynamic>>); @override - _i24.Future<void> fullRescan( + _i25.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -1387,11 +1400,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { maxNumberOfIndexesToCheck, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<_i15.Amount> estimateFeeFor( + _i25.Future<_i15.Amount> estimateFeeFor( _i15.Amount? amount, int? feeRate, ) => @@ -1403,7 +1416,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { feeRate, ], ), - returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i25.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #estimateFeeFor, @@ -1413,7 +1426,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { ], ), )), - ) as _i24.Future<_i15.Amount>); + ) as _i25.Future<_i15.Amount>); @override _i15.Amount roughFeeEstimate( int? inputCount, @@ -1442,32 +1455,32 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { ), ) as _i15.Amount); @override - _i24.Future<_i15.Amount> sweepAllEstimate(int? feeRate) => + _i25.Future<_i15.Amount> sweepAllEstimate(int? feeRate) => (super.noSuchMethod( Invocation.method( #sweepAllEstimate, [feeRate], ), - returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i25.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #sweepAllEstimate, [feeRate], ), )), - ) as _i24.Future<_i15.Amount>); + ) as _i25.Future<_i15.Amount>); @override - _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i25.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override void initCache( String? walletId, - _i23.Coin? coin, + _i24.Coin? coin, ) => super.noSuchMethod( Invocation.method( @@ -1480,14 +1493,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<void> updateCachedId(String? id) => (super.noSuchMethod( + _i25.Future<void> updateCachedId(String? id) => (super.noSuchMethod( Invocation.method( #updateCachedId, [id], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override int getCachedChainHeight() => (super.noSuchMethod( Invocation.method( @@ -1497,14 +1510,14 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { returnValue: 0, ) as int); @override - _i24.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( + _i25.Future<void> updateCachedChainHeight(int? height) => (super.noSuchMethod( Invocation.method( #updateCachedChainHeight, [height], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override bool getCachedIsFavorite() => (super.noSuchMethod( Invocation.method( @@ -1514,15 +1527,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { returnValue: false, ) as bool); @override - _i24.Future<void> updateCachedIsFavorite(bool? isFavorite) => + _i25.Future<void> updateCachedIsFavorite(bool? isFavorite) => (super.noSuchMethod( Invocation.method( #updateCachedIsFavorite, [isFavorite], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override _i13.Balance getCachedBalance() => (super.noSuchMethod( Invocation.method( @@ -1538,15 +1551,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { ), ) as _i13.Balance); @override - _i24.Future<void> updateCachedBalance(_i13.Balance? balance) => + _i25.Future<void> updateCachedBalance(_i13.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalance, [balance], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override _i13.Balance getCachedBalanceSecondary() => (super.noSuchMethod( Invocation.method( @@ -1562,15 +1575,15 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { ), ) as _i13.Balance); @override - _i24.Future<void> updateCachedBalanceSecondary(_i13.Balance? balance) => + _i25.Future<void> updateCachedBalanceSecondary(_i13.Balance? balance) => (super.noSuchMethod( Invocation.method( #updateCachedBalanceSecondary, [balance], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override List<String> getWalletTokenContractAddresses() => (super.noSuchMethod( Invocation.method( @@ -1580,16 +1593,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { returnValue: <String>[], ) as List<String>); @override - _i24.Future<void> updateWalletTokenContractAddresses( + _i25.Future<void> updateWalletTokenContractAddresses( List<String>? contractAddresses) => (super.noSuchMethod( Invocation.method( #updateWalletTokenContractAddresses, [contractAddresses], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override void initWalletDB({_i8.MainDB? mockableOverride}) => super.noSuchMethod( Invocation.method( @@ -1600,11 +1613,45 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>> parseTransaction( + _i25.Future<_i16.TransactionV2> getTransaction( + String? txHash, + _i24.Coin? coin, + String? walletId, + _i12.CachedElectrumX? cachedElectrumX, [ + String? debugTitle, + ]) => + (super.noSuchMethod( + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + returnValue: + _i25.Future<_i16.TransactionV2>.value(_FakeTransactionV2_14( + this, + Invocation.method( + #getTransaction, + [ + txHash, + coin, + walletId, + cachedElectrumX, + debugTitle, + ], + ), + )), + ) as _i25.Future<_i16.TransactionV2>); + @override + _i25.Future<_i17.Tuple2<_i19.Transaction, _i19.Address>> parseTransaction( Map<String, dynamic>? txData, dynamic electrumxClient, - List<_i18.Address>? myAddresses, - _i23.Coin? coin, + List<_i19.Address>? myAddresses, + _i24.Coin? coin, int? minConfirms, String? walletId, ) => @@ -1621,8 +1668,8 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { ], ), returnValue: - _i24.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>.value( - _FakeTuple2_14<_i18.Transaction, _i18.Address>( + _i25.Future<_i17.Tuple2<_i19.Transaction, _i19.Address>>.value( + _FakeTuple2_15<_i19.Transaction, _i19.Address>( this, Invocation.method( #parseTransaction, @@ -1636,37 +1683,37 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { ], ), )), - ) as _i24.Future<_i16.Tuple2<_i18.Transaction, _i18.Address>>); + ) as _i25.Future<_i17.Tuple2<_i19.Transaction, _i19.Address>>); @override void initPaynymWalletInterface({ required String? walletId, required String? walletName, required _i14.NetworkType? network, - required _i23.Coin? coin, + required _i24.Coin? coin, required _i8.MainDB? db, required _i11.ElectrumX? electrumXClient, - required _i20.SecureStorageInterface? secureStorage, + required _i21.SecureStorageInterface? secureStorage, required int? dustLimit, required int? dustLimitP2PKH, required int? minConfirms, - required _i24.Future<String?> Function()? getMnemonicString, - required _i24.Future<String?> Function()? getMnemonicPassphrase, - required _i24.Future<int> Function()? getChainHeight, - required _i24.Future<String> Function()? getCurrentChangeAddress, + required _i25.Future<String?> Function()? getMnemonicString, + required _i25.Future<String?> Function()? getMnemonicPassphrase, + required _i25.Future<int> Function()? getChainHeight, + required _i25.Future<String> Function()? getCurrentChangeAddress, required int Function({ required int feeRatePerKB, required int vSize, })? estimateTxFee, - required _i24.Future<Map<String, dynamic>> Function({ + required _i25.Future<Map<String, dynamic>> Function({ required String address, required _i15.Amount amount, Map<String, dynamic>? args, })? prepareSend, - required _i24.Future<int> Function({required String address})? getTxCount, - required _i24.Future<List<_i32.SigningData>> Function(List<_i18.UTXO>)? + required _i25.Future<int> Function({required String address})? getTxCount, + required _i25.Future<List<_i33.SigningData>> Function(List<_i19.UTXO>)? fetchBuildTxData, - required _i24.Future<void> Function()? refresh, - required _i24.Future<void> Function()? checkChangeAddressForTransactions, + required _i25.Future<void> Function()? refresh, + required _i25.Future<void> Function()? checkChangeAddressForTransactions, }) => super.noSuchMethod( Invocation.method( @@ -1699,21 +1746,21 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<_i17.BIP32> getBip47BaseNode() => (super.noSuchMethod( + _i25.Future<_i18.BIP32> getBip47BaseNode() => (super.noSuchMethod( Invocation.method( #getBip47BaseNode, [], ), - returnValue: _i24.Future<_i17.BIP32>.value(_FakeBIP32_15( + returnValue: _i25.Future<_i18.BIP32>.value(_FakeBIP32_16( this, Invocation.method( #getBip47BaseNode, [], ), )), - ) as _i24.Future<_i17.BIP32>); + ) as _i25.Future<_i18.BIP32>); @override - _i24.Future<_i29.Uint8List> getPrivateKeyForPaynymReceivingAddress({ + _i25.Future<_i30.Uint8List> getPrivateKeyForPaynymReceivingAddress({ required String? paymentCodeString, required int? index, }) => @@ -1726,11 +1773,11 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { #index: index, }, ), - returnValue: _i24.Future<_i29.Uint8List>.value(_i29.Uint8List(0)), - ) as _i24.Future<_i29.Uint8List>); + returnValue: _i25.Future<_i30.Uint8List>.value(_i30.Uint8List(0)), + ) as _i25.Future<_i30.Uint8List>); @override - _i24.Future<_i18.Address> currentReceivingPaynymAddress({ - required _i19.PaymentCode? sender, + _i25.Future<_i19.Address> currentReceivingPaynymAddress({ + required _i20.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1742,7 +1789,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i24.Future<_i18.Address>.value(_FakeAddress_16( + returnValue: _i25.Future<_i19.Address>.value(_FakeAddress_17( this, Invocation.method( #currentReceivingPaynymAddress, @@ -1753,10 +1800,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { }, ), )), - ) as _i24.Future<_i18.Address>); + ) as _i25.Future<_i19.Address>); @override - _i24.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ - required _i19.PaymentCode? sender, + _i25.Future<void> checkCurrentPaynymReceivingAddressForTransactions({ + required _i20.PaymentCode? sender, required bool? isSegwit, }) => (super.noSuchMethod( @@ -1768,42 +1815,42 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { #isSegwit: isSegwit, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => + _i25.Future<void> checkAllCurrentReceivingPaynymAddressesForTransactions() => (super.noSuchMethod( Invocation.method( #checkAllCurrentReceivingPaynymAddressesForTransactions, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<_i17.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( + _i25.Future<_i18.BIP32> deriveNotificationBip32Node() => (super.noSuchMethod( Invocation.method( #deriveNotificationBip32Node, [], ), - returnValue: _i24.Future<_i17.BIP32>.value(_FakeBIP32_15( + returnValue: _i25.Future<_i18.BIP32>.value(_FakeBIP32_16( this, Invocation.method( #deriveNotificationBip32Node, [], ), )), - ) as _i24.Future<_i17.BIP32>); + ) as _i25.Future<_i18.BIP32>); @override - _i24.Future<_i19.PaymentCode> getPaymentCode({required bool? isSegwit}) => + _i25.Future<_i20.PaymentCode> getPaymentCode({required bool? isSegwit}) => (super.noSuchMethod( Invocation.method( #getPaymentCode, [], {#isSegwit: isSegwit}, ), - returnValue: _i24.Future<_i19.PaymentCode>.value(_FakePaymentCode_17( + returnValue: _i25.Future<_i20.PaymentCode>.value(_FakePaymentCode_18( this, Invocation.method( #getPaymentCode, @@ -1811,28 +1858,28 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { {#isSegwit: isSegwit}, ), )), - ) as _i24.Future<_i19.PaymentCode>); + ) as _i25.Future<_i20.PaymentCode>); @override - _i24.Future<_i29.Uint8List> signWithNotificationKey(_i29.Uint8List? data) => + _i25.Future<_i30.Uint8List> signWithNotificationKey(_i30.Uint8List? data) => (super.noSuchMethod( Invocation.method( #signWithNotificationKey, [data], ), - returnValue: _i24.Future<_i29.Uint8List>.value(_i29.Uint8List(0)), - ) as _i24.Future<_i29.Uint8List>); + returnValue: _i25.Future<_i30.Uint8List>.value(_i30.Uint8List(0)), + ) as _i25.Future<_i30.Uint8List>); @override - _i24.Future<String> signStringWithNotificationKey(String? data) => + _i25.Future<String> signStringWithNotificationKey(String? data) => (super.noSuchMethod( Invocation.method( #signStringWithNotificationKey, [data], ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override - _i24.Future<Map<String, dynamic>> preparePaymentCodeSend({ - required _i19.PaymentCode? paymentCode, + _i25.Future<Map<String, dynamic>> preparePaymentCodeSend({ + required _i20.PaymentCode? paymentCode, required bool? isSegwit, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -1849,13 +1896,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i25.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i25.Future<Map<String, dynamic>>); @override - _i24.Future<_i18.Address> nextUnusedSendAddressFrom({ - required _i19.PaymentCode? pCode, + _i25.Future<_i19.Address> nextUnusedSendAddressFrom({ + required _i20.PaymentCode? pCode, required bool? isSegwit, - required _i17.BIP32? privateKeyNode, + required _i18.BIP32? privateKeyNode, int? startIndex = 0, }) => (super.noSuchMethod( @@ -1869,7 +1916,7 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { #startIndex: startIndex, }, ), - returnValue: _i24.Future<_i18.Address>.value(_FakeAddress_16( + returnValue: _i25.Future<_i19.Address>.value(_FakeAddress_17( this, Invocation.method( #nextUnusedSendAddressFrom, @@ -1882,13 +1929,13 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { }, ), )), - ) as _i24.Future<_i18.Address>); + ) as _i25.Future<_i19.Address>); @override - _i24.Future<Map<String, dynamic>> prepareNotificationTx({ + _i25.Future<Map<String, dynamic>> prepareNotificationTx({ required int? selectedTxFeeRate, required String? targetPaymentCodeString, int? additionalOutputs = 0, - List<_i18.UTXO>? utxos, + List<_i19.UTXO>? utxos, }) => (super.noSuchMethod( Invocation.method( @@ -1902,10 +1949,10 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i25.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i25.Future<Map<String, dynamic>>); @override - _i24.Future<String> broadcastNotificationTx( + _i25.Future<String> broadcastNotificationTx( {required Map<String, dynamic>? preparedTx}) => (super.noSuchMethod( Invocation.method( @@ -1913,62 +1960,62 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { [], {#preparedTx: preparedTx}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override - _i24.Future<bool> hasConnected(String? paymentCodeString) => + _i25.Future<bool> hasConnected(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #hasConnected, [paymentCodeString], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override - _i24.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransaction( - {required _i18.Transaction? transaction}) => + _i25.Future<_i20.PaymentCode?> unBlindedPaymentCodeFromTransaction( + {required _i19.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransaction, [], {#transaction: transaction}, ), - returnValue: _i24.Future<_i19.PaymentCode?>.value(), - ) as _i24.Future<_i19.PaymentCode?>); + returnValue: _i25.Future<_i20.PaymentCode?>.value(), + ) as _i25.Future<_i20.PaymentCode?>); @override - _i24.Future<_i19.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( - {required _i18.Transaction? transaction}) => + _i25.Future<_i20.PaymentCode?> unBlindedPaymentCodeFromTransactionBad( + {required _i19.Transaction? transaction}) => (super.noSuchMethod( Invocation.method( #unBlindedPaymentCodeFromTransactionBad, [], {#transaction: transaction}, ), - returnValue: _i24.Future<_i19.PaymentCode?>.value(), - ) as _i24.Future<_i19.PaymentCode?>); + returnValue: _i25.Future<_i20.PaymentCode?>.value(), + ) as _i25.Future<_i20.PaymentCode?>); @override - _i24.Future<List<_i19.PaymentCode>> + _i25.Future<List<_i20.PaymentCode>> getAllPaymentCodesFromNotificationTransactions() => (super.noSuchMethod( Invocation.method( #getAllPaymentCodesFromNotificationTransactions, [], ), returnValue: - _i24.Future<List<_i19.PaymentCode>>.value(<_i19.PaymentCode>[]), - ) as _i24.Future<List<_i19.PaymentCode>>); + _i25.Future<List<_i20.PaymentCode>>.value(<_i20.PaymentCode>[]), + ) as _i25.Future<List<_i20.PaymentCode>>); @override - _i24.Future<void> checkForNotificationTransactionsTo( + _i25.Future<void> checkForNotificationTransactionsTo( Set<String>? otherCodeStrings) => (super.noSuchMethod( Invocation.method( #checkForNotificationTransactionsTo, [otherCodeStrings], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> restoreAllHistory({ + _i25.Future<void> restoreAllHistory({ required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, required Set<String>? paymentCodeStrings, @@ -1983,12 +2030,12 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { #paymentCodeStrings: paymentCodeStrings, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> restoreHistoryWith({ - required _i19.PaymentCode? other, + _i25.Future<void> restoreHistoryWith({ + required _i20.PaymentCode? other, required bool? checkSegwitAsWell, required int? maxUnusedAddressGap, required int? maxNumberOfIndexesToCheck, @@ -2004,58 +2051,58 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { #maxNumberOfIndexesToCheck: maxNumberOfIndexesToCheck, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<_i18.Address> getMyNotificationAddress() => (super.noSuchMethod( + _i25.Future<_i19.Address> getMyNotificationAddress() => (super.noSuchMethod( Invocation.method( #getMyNotificationAddress, [], ), - returnValue: _i24.Future<_i18.Address>.value(_FakeAddress_16( + returnValue: _i25.Future<_i19.Address>.value(_FakeAddress_17( this, Invocation.method( #getMyNotificationAddress, [], ), )), - ) as _i24.Future<_i18.Address>); + ) as _i25.Future<_i19.Address>); @override - _i24.Future<List<String>> lookupKey(String? paymentCodeString) => + _i25.Future<List<String>> lookupKey(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #lookupKey, [paymentCodeString], ), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i25.Future<List<String>>.value(<String>[]), + ) as _i25.Future<List<String>>); @override - _i24.Future<String?> paymentCodeStringByKey(String? key) => + _i25.Future<String?> paymentCodeStringByKey(String? key) => (super.noSuchMethod( Invocation.method( #paymentCodeStringByKey, [key], ), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i25.Future<String?>.value(), + ) as _i25.Future<String?>); @override - _i24.Future<String> storeCode(String? paymentCodeString) => + _i25.Future<String> storeCode(String? paymentCodeString) => (super.noSuchMethod( Invocation.method( #storeCode, [paymentCodeString], ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override void initCoinControlInterface({ required String? walletId, required String? walletName, - required _i23.Coin? coin, + required _i24.Coin? coin, required _i8.MainDB? db, - required _i24.Future<int> Function()? getChainHeight, - required _i24.Future<void> Function(_i13.Balance)? refreshedBalanceCallback, + required _i25.Future<int> Function()? getChainHeight, + required _i25.Future<void> Function(_i13.Balance)? refreshedBalanceCallback, }) => super.noSuchMethod( Invocation.method( @@ -2073,16 +2120,16 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { returnValueForMissingStub: null, ); @override - _i24.Future<void> refreshBalance({bool? notify = false}) => + _i25.Future<void> refreshBalance({bool? notify = false}) => (super.noSuchMethod( Invocation.method( #refreshBalance, [], {#notify: notify}, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); } /// A class which mocks [NodeService]. @@ -2090,41 +2137,41 @@ class MockBitcoinWallet extends _i1.Mock implements _i30.BitcoinWallet { /// See the documentation for Mockito's code generation for more information. class MockNodeService extends _i1.Mock implements _i3.NodeService { @override - _i20.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( + _i21.SecureStorageInterface get secureStorageInterface => (super.noSuchMethod( Invocation.getter(#secureStorageInterface), - returnValue: _FakeSecureStorageInterface_18( + returnValue: _FakeSecureStorageInterface_19( this, Invocation.getter(#secureStorageInterface), ), - ) as _i20.SecureStorageInterface); + ) as _i21.SecureStorageInterface); @override - List<_i33.NodeModel> get primaryNodes => (super.noSuchMethod( + List<_i34.NodeModel> get primaryNodes => (super.noSuchMethod( Invocation.getter(#primaryNodes), - returnValue: <_i33.NodeModel>[], - ) as List<_i33.NodeModel>); + returnValue: <_i34.NodeModel>[], + ) as List<_i34.NodeModel>); @override - List<_i33.NodeModel> get nodes => (super.noSuchMethod( + List<_i34.NodeModel> get nodes => (super.noSuchMethod( Invocation.getter(#nodes), - returnValue: <_i33.NodeModel>[], - ) as List<_i33.NodeModel>); + returnValue: <_i34.NodeModel>[], + ) as List<_i34.NodeModel>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i24.Future<void> updateDefaults() => (super.noSuchMethod( + _i25.Future<void> updateDefaults() => (super.noSuchMethod( Invocation.method( #updateDefaults, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> setPrimaryNodeFor({ - required _i23.Coin? coin, - required _i33.NodeModel? node, + _i25.Future<void> setPrimaryNodeFor({ + required _i24.Coin? coin, + required _i34.NodeModel? node, bool? shouldNotifyListeners = false, }) => (super.noSuchMethod( @@ -2137,44 +2184,44 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { #shouldNotifyListeners: shouldNotifyListeners, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i33.NodeModel? getPrimaryNodeFor({required _i23.Coin? coin}) => + _i34.NodeModel? getPrimaryNodeFor({required _i24.Coin? coin}) => (super.noSuchMethod(Invocation.method( #getPrimaryNodeFor, [], {#coin: coin}, - )) as _i33.NodeModel?); + )) as _i34.NodeModel?); @override - List<_i33.NodeModel> getNodesFor(_i23.Coin? coin) => (super.noSuchMethod( + List<_i34.NodeModel> getNodesFor(_i24.Coin? coin) => (super.noSuchMethod( Invocation.method( #getNodesFor, [coin], ), - returnValue: <_i33.NodeModel>[], - ) as List<_i33.NodeModel>); + returnValue: <_i34.NodeModel>[], + ) as List<_i34.NodeModel>); @override - _i33.NodeModel? getNodeById({required String? id}) => + _i34.NodeModel? getNodeById({required String? id}) => (super.noSuchMethod(Invocation.method( #getNodeById, [], {#id: id}, - )) as _i33.NodeModel?); + )) as _i34.NodeModel?); @override - List<_i33.NodeModel> failoverNodesFor({required _i23.Coin? coin}) => + List<_i34.NodeModel> failoverNodesFor({required _i24.Coin? coin}) => (super.noSuchMethod( Invocation.method( #failoverNodesFor, [], {#coin: coin}, ), - returnValue: <_i33.NodeModel>[], - ) as List<_i33.NodeModel>); + returnValue: <_i34.NodeModel>[], + ) as List<_i34.NodeModel>); @override - _i24.Future<void> add( - _i33.NodeModel? node, + _i25.Future<void> add( + _i34.NodeModel? node, String? password, bool? shouldNotifyListeners, ) => @@ -2187,11 +2234,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> delete( + _i25.Future<void> delete( String? id, bool? shouldNotifyListeners, ) => @@ -2203,11 +2250,11 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> setEnabledState( + _i25.Future<void> setEnabledState( String? id, bool? enabled, bool? shouldNotifyListeners, @@ -2221,12 +2268,12 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> edit( - _i33.NodeModel? editedNode, + _i25.Future<void> edit( + _i34.NodeModel? editedNode, String? password, bool? shouldNotifyListeners, ) => @@ -2239,20 +2286,20 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { shouldNotifyListeners, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> updateCommunityNodes() => (super.noSuchMethod( + _i25.Future<void> updateCommunityNodes() => (super.noSuchMethod( Invocation.method( #updateCommunityNodes, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i27.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2260,7 +2307,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i27.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2303,23 +2350,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i21.CoinServiceAPI get wallet => (super.noSuchMethod( + _i22.CoinServiceAPI get wallet => (super.noSuchMethod( Invocation.getter(#wallet), - returnValue: _FakeCoinServiceAPI_19( + returnValue: _FakeCoinServiceAPI_20( this, Invocation.getter(#wallet), ), - ) as _i21.CoinServiceAPI); + ) as _i22.CoinServiceAPI); @override bool get hasBackgroundRefreshListener => (super.noSuchMethod( Invocation.getter(#hasBackgroundRefreshListener), returnValue: false, ) as bool); @override - _i23.Coin get coin => (super.noSuchMethod( + _i24.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i23.Coin.bitcoin, - ) as _i23.Coin); + returnValue: _i24.Coin.bitcoin, + ) as _i24.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2352,23 +2399,23 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i24.Future<_i10.FeeObject> get fees => (super.noSuchMethod( + _i25.Future<_i10.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i24.Future<_i10.FeeObject>.value(_FakeFeeObject_7( + returnValue: _i25.Future<_i10.FeeObject>.value(_FakeFeeObject_7( this, Invocation.getter(#fees), )), - ) as _i24.Future<_i10.FeeObject>); + ) as _i25.Future<_i10.FeeObject>); @override - _i24.Future<int> get maxFee => (super.noSuchMethod( + _i25.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i25.Future<int>.value(0), + ) as _i25.Future<int>); @override - _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i25.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override _i13.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2378,16 +2425,16 @@ class MockManager extends _i1.Mock implements _i6.Manager { ), ) as _i13.Balance); @override - _i24.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( + _i25.Future<List<_i19.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i24.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), - ) as _i24.Future<List<_i18.Transaction>>); + _i25.Future<List<_i19.Transaction>>.value(<_i19.Transaction>[]), + ) as _i25.Future<List<_i19.Transaction>>); @override - _i24.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( + _i25.Future<List<_i19.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i24.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), - ) as _i24.Future<List<_i18.UTXO>>); + returnValue: _i25.Future<List<_i19.UTXO>>.value(<_i19.UTXO>[]), + ) as _i25.Future<List<_i19.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2407,15 +2454,15 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: '', ) as String); @override - _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i25.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i25.Future<List<String>>.value(<String>[]), + ) as _i25.Future<List<String>>); @override - _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i25.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i25.Future<String?>.value(), + ) as _i25.Future<String?>); @override bool get isConnected => (super.noSuchMethod( Invocation.getter(#isConnected), @@ -2452,6 +2499,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override + bool get hasFusionSupport => (super.noSuchMethod( + Invocation.getter(#hasFusionSupport), + returnValue: false, + ) as bool); + @override int get rescanOnOpenVersion => (super.noSuchMethod( Invocation.getter(#rescanOnOpenVersion), returnValue: 0, @@ -2462,24 +2514,24 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i24.Future<String> get xpub => (super.noSuchMethod( + _i25.Future<String> get xpub => (super.noSuchMethod( Invocation.getter(#xpub), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override bool get hasListeners => (super.noSuchMethod( Invocation.getter(#hasListeners), returnValue: false, ) as bool); @override - _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i25.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override void dispose() => super.noSuchMethod( Invocation.method( @@ -2489,7 +2541,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - _i24.Future<Map<String, dynamic>> prepareSend({ + _i25.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -2505,27 +2557,27 @@ class MockManager extends _i1.Mock implements _i6.Manager { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i25.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i25.Future<Map<String, dynamic>>); @override - _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i25.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override - _i24.Future<void> refresh() => (super.noSuchMethod( + _i25.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2535,35 +2587,35 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValue: false, ) as bool); @override - _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i25.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override - _i24.Future<void> initializeNew( + _i25.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> initializeExisting() => (super.noSuchMethod( + _i25.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> recoverFromMnemonic({ + _i25.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -2582,20 +2634,20 @@ class MockManager extends _i1.Mock implements _i6.Manager { #height: height, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> exitCurrentWallet() => (super.noSuchMethod( + _i25.Future<void> exitCurrentWallet() => (super.noSuchMethod( Invocation.method( #exitCurrentWallet, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> fullRescan( + _i25.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2607,11 +2659,11 @@ class MockManager extends _i1.Mock implements _i6.Manager { maxNumberOfIndexesToCheck, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<_i15.Amount> estimateFeeFor( + _i25.Future<_i15.Amount> estimateFeeFor( _i15.Amount? amount, int? feeRate, ) => @@ -2623,7 +2675,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { feeRate, ], ), - returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i25.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #estimateFeeFor, @@ -2633,26 +2685,26 @@ class MockManager extends _i1.Mock implements _i6.Manager { ], ), )), - ) as _i24.Future<_i15.Amount>); + ) as _i25.Future<_i15.Amount>); @override - _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i25.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override - _i24.Future<void> resetRescanOnOpen() => (super.noSuchMethod( + _i25.Future<void> resetRescanOnOpen() => (super.noSuchMethod( Invocation.method( #resetRescanOnOpen, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - void addListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void addListener(_i27.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #addListener, [listener], @@ -2660,7 +2712,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { returnValueForMissingStub: null, ); @override - void removeListener(_i26.VoidCallback? listener) => super.noSuchMethod( + void removeListener(_i27.VoidCallback? listener) => super.noSuchMethod( Invocation.method( #removeListener, [listener], @@ -2680,7 +2732,7 @@ class MockManager extends _i1.Mock implements _i6.Manager { /// A class which mocks [CoinServiceAPI]. /// /// See the documentation for Mockito's code generation for more information. -class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { +class MockCoinServiceAPI extends _i1.Mock implements _i22.CoinServiceAPI { @override set onIsActiveWalletChanged(void Function(bool)? _onIsActiveWalletChanged) => super.noSuchMethod( @@ -2691,10 +2743,10 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i23.Coin get coin => (super.noSuchMethod( + _i24.Coin get coin => (super.noSuchMethod( Invocation.getter(#coin), - returnValue: _i23.Coin.bitcoin, - ) as _i23.Coin); + returnValue: _i24.Coin.bitcoin, + ) as _i24.Coin); @override bool get isRefreshing => (super.noSuchMethod( Invocation.getter(#isRefreshing), @@ -2727,23 +2779,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValueForMissingStub: null, ); @override - _i24.Future<_i10.FeeObject> get fees => (super.noSuchMethod( + _i25.Future<_i10.FeeObject> get fees => (super.noSuchMethod( Invocation.getter(#fees), - returnValue: _i24.Future<_i10.FeeObject>.value(_FakeFeeObject_7( + returnValue: _i25.Future<_i10.FeeObject>.value(_FakeFeeObject_7( this, Invocation.getter(#fees), )), - ) as _i24.Future<_i10.FeeObject>); + ) as _i25.Future<_i10.FeeObject>); @override - _i24.Future<int> get maxFee => (super.noSuchMethod( + _i25.Future<int> get maxFee => (super.noSuchMethod( Invocation.getter(#maxFee), - returnValue: _i24.Future<int>.value(0), - ) as _i24.Future<int>); + returnValue: _i25.Future<int>.value(0), + ) as _i25.Future<int>); @override - _i24.Future<String> get currentReceivingAddress => (super.noSuchMethod( + _i25.Future<String> get currentReceivingAddress => (super.noSuchMethod( Invocation.getter(#currentReceivingAddress), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override _i13.Balance get balance => (super.noSuchMethod( Invocation.getter(#balance), @@ -2753,16 +2805,16 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { ), ) as _i13.Balance); @override - _i24.Future<List<_i18.Transaction>> get transactions => (super.noSuchMethod( + _i25.Future<List<_i19.Transaction>> get transactions => (super.noSuchMethod( Invocation.getter(#transactions), returnValue: - _i24.Future<List<_i18.Transaction>>.value(<_i18.Transaction>[]), - ) as _i24.Future<List<_i18.Transaction>>); + _i25.Future<List<_i19.Transaction>>.value(<_i19.Transaction>[]), + ) as _i25.Future<List<_i19.Transaction>>); @override - _i24.Future<List<_i18.UTXO>> get utxos => (super.noSuchMethod( + _i25.Future<List<_i19.UTXO>> get utxos => (super.noSuchMethod( Invocation.getter(#utxos), - returnValue: _i24.Future<List<_i18.UTXO>>.value(<_i18.UTXO>[]), - ) as _i24.Future<List<_i18.UTXO>>); + returnValue: _i25.Future<List<_i19.UTXO>>.value(<_i19.UTXO>[]), + ) as _i25.Future<List<_i19.UTXO>>); @override set walletName(String? newName) => super.noSuchMethod( Invocation.setter( @@ -2782,20 +2834,20 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValue: '', ) as String); @override - _i24.Future<List<String>> get mnemonic => (super.noSuchMethod( + _i25.Future<List<String>> get mnemonic => (super.noSuchMethod( Invocation.getter(#mnemonic), - returnValue: _i24.Future<List<String>>.value(<String>[]), - ) as _i24.Future<List<String>>); + returnValue: _i25.Future<List<String>>.value(<String>[]), + ) as _i25.Future<List<String>>); @override - _i24.Future<String?> get mnemonicString => (super.noSuchMethod( + _i25.Future<String?> get mnemonicString => (super.noSuchMethod( Invocation.getter(#mnemonicString), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i25.Future<String?>.value(), + ) as _i25.Future<String?>); @override - _i24.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( + _i25.Future<String?> get mnemonicPassphrase => (super.noSuchMethod( Invocation.getter(#mnemonicPassphrase), - returnValue: _i24.Future<String?>.value(), - ) as _i24.Future<String?>); + returnValue: _i25.Future<String?>.value(), + ) as _i25.Future<String?>); @override bool get hasCalledExit => (super.noSuchMethod( Invocation.getter(#hasCalledExit), @@ -2812,7 +2864,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValue: 0, ) as int); @override - _i24.Future<Map<String, dynamic>> prepareSend({ + _i25.Future<Map<String, dynamic>> prepareSend({ required String? address, required _i15.Amount? amount, Map<String, dynamic>? args, @@ -2828,36 +2880,36 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { }, ), returnValue: - _i24.Future<Map<String, dynamic>>.value(<String, dynamic>{}), - ) as _i24.Future<Map<String, dynamic>>); + _i25.Future<Map<String, dynamic>>.value(<String, dynamic>{}), + ) as _i25.Future<Map<String, dynamic>>); @override - _i24.Future<String> confirmSend({required Map<String, dynamic>? txData}) => + _i25.Future<String> confirmSend({required Map<String, dynamic>? txData}) => (super.noSuchMethod( Invocation.method( #confirmSend, [], {#txData: txData}, ), - returnValue: _i24.Future<String>.value(''), - ) as _i24.Future<String>); + returnValue: _i25.Future<String>.value(''), + ) as _i25.Future<String>); @override - _i24.Future<void> refresh() => (super.noSuchMethod( + _i25.Future<void> refresh() => (super.noSuchMethod( Invocation.method( #refresh, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( + _i25.Future<void> updateNode(bool? shouldRefresh) => (super.noSuchMethod( Invocation.method( #updateNode, [shouldRefresh], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override bool validateAddress(String? address) => (super.noSuchMethod( Invocation.method( @@ -2867,15 +2919,15 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { returnValue: false, ) as bool); @override - _i24.Future<bool> testNetworkConnection() => (super.noSuchMethod( + _i25.Future<bool> testNetworkConnection() => (super.noSuchMethod( Invocation.method( #testNetworkConnection, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override - _i24.Future<void> recoverFromMnemonic({ + _i25.Future<void> recoverFromMnemonic({ required String? mnemonic, String? mnemonicPassphrase, required int? maxUnusedAddressGap, @@ -2894,40 +2946,40 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { #height: height, }, ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> initializeNew( + _i25.Future<void> initializeNew( ({String mnemonicPassphrase, int wordCount})? data) => (super.noSuchMethod( Invocation.method( #initializeNew, [data], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> initializeExisting() => (super.noSuchMethod( + _i25.Future<void> initializeExisting() => (super.noSuchMethod( Invocation.method( #initializeExisting, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> exit() => (super.noSuchMethod( + _i25.Future<void> exit() => (super.noSuchMethod( Invocation.method( #exit, [], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<void> fullRescan( + _i25.Future<void> fullRescan( int? maxUnusedAddressGap, int? maxNumberOfIndexesToCheck, ) => @@ -2939,11 +2991,11 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { maxNumberOfIndexesToCheck, ], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); @override - _i24.Future<_i15.Amount> estimateFeeFor( + _i25.Future<_i15.Amount> estimateFeeFor( _i15.Amount? amount, int? feeRate, ) => @@ -2955,7 +3007,7 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { feeRate, ], ), - returnValue: _i24.Future<_i15.Amount>.value(_FakeAmount_13( + returnValue: _i25.Future<_i15.Amount>.value(_FakeAmount_13( this, Invocation.method( #estimateFeeFor, @@ -2965,23 +3017,23 @@ class MockCoinServiceAPI extends _i1.Mock implements _i21.CoinServiceAPI { ], ), )), - ) as _i24.Future<_i15.Amount>); + ) as _i25.Future<_i15.Amount>); @override - _i24.Future<bool> generateNewAddress() => (super.noSuchMethod( + _i25.Future<bool> generateNewAddress() => (super.noSuchMethod( Invocation.method( #generateNewAddress, [], ), - returnValue: _i24.Future<bool>.value(false), - ) as _i24.Future<bool>); + returnValue: _i25.Future<bool>.value(false), + ) as _i25.Future<bool>); @override - _i24.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => + _i25.Future<void> updateSentCachedTxData(Map<String, dynamic>? txData) => (super.noSuchMethod( Invocation.method( #updateSentCachedTxData, [txData], ), - returnValue: _i24.Future<void>.value(), - returnValueForMissingStub: _i24.Future<void>.value(), - ) as _i24.Future<void>); + returnValue: _i25.Future<void>.value(), + returnValueForMissingStub: _i25.Future<void>.value(), + ) as _i25.Future<void>); } From d5c492303162deed62b30454e870ccd1064cf3fc Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 12:52:21 -0500 Subject: [PATCH 284/379] refactor maxConsecutiveFusionRoundsFailed->failed --- lib/models/fusion_progress_ui_state.dart | 15 +++++++++------ lib/services/mixins/fusion_wallet_interface.dart | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 60217b2d6..78c32bead 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -109,7 +109,7 @@ class FusionProgressUIState extends ChangeNotifier { void incrementFusionRoundsCompleted() { _fusionRoundsCompleted++; _fusionRoundsFailed = 0; // Reset failed round count on success. - _maxConsecutiveFusionRoundsFailed = false; // Reset failed flag on success. + _failed = false; // Reset failed flag on success. notifyListeners(); } @@ -129,11 +129,14 @@ class FusionProgressUIState extends ChangeNotifier { /// A flag indicating that fusion has stopped because the maximum number of /// consecutive failed fusion rounds has been reached. - bool _maxConsecutiveFusionRoundsFailed = false; - bool get maxConsecutiveFusionRoundsFailed => - _maxConsecutiveFusionRoundsFailed; - set maxConsecutiveFusionRoundsFailed(bool maxConsecutiveFusionRoundsFailed) { - _maxConsecutiveFusionRoundsFailed = maxConsecutiveFusionRoundsFailed; + /// + /// Set from the interface. I didn't want to have to configure + /// + /// Used to be named maxConsecutiveFusionRoundsFailed. + bool _failed = true; + bool get failed => _failed; + set failed(bool failed) { + _failed = failed; notifyListeners(); } } diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 6bcb86817..28eb61082 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -572,7 +572,7 @@ mixin FusionWalletInterface { // If we fail too many times in a row, stop trying. if (_failedFuseCount >= maxFailedFuseCount) { _stopRequested = true; - _uiState?.maxConsecutiveFusionRoundsFailed = true; + _uiState?.failed = true; } } finally { // Increment the number of successfully completed fusion rounds. From e9717c7aa7a9aa87481693de1d815f1b52dc97ba Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 12:52:38 -0500 Subject: [PATCH 285/379] show try again and fuse again buttons based on uiState --- .../cashfusion/fusion_progress_view.dart | 42 +++++++++++++++++-- .../cashfusion/sub_widgets/fusion_dialog.dart | 39 ++++++++++++++++- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index c51225f21..bd5757405 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -8,9 +8,13 @@ * */ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart'; +import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; +import 'package:stackwallet/providers/global/prefs_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/themes/stack_colors.dart'; @@ -126,12 +130,32 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { FusionProgress( walletId: widget.walletId, ), - const Spacer(), + if (ref + .watch(fusionProgressUIStateProvider( + widget.walletId)) + .succeeded) + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Fuse again", + onPressed: () => _fuseAgain, + ), + ), + if (ref + .watch(fusionProgressUIStateProvider( + widget.walletId)) + .failed) + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Try again", + onPressed: () => _fuseAgain, + ), + ), + // if (!_succeeded! && !_failed!) const Spacer(), const SizedBox( height: 16, ), - // TODO: various button states - // tempt only show cancel button SecondaryButton( label: "Cancel", onPressed: () async { @@ -155,4 +179,16 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { ), ); } + + /// Fuse again. + void _fuseAgain() async { + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + final fusionInfo = ref.read(prefsChangeNotifierProvider).fusionServerInfo; + + unawaited(fusionWallet.fuse(fusionInfo: fusionInfo)); + } } diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 0d7e8f92b..78fae11ab 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -1,6 +1,10 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart'; +import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provider.dart'; +import 'package:stackwallet/providers/global/prefs_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; import 'package:stackwallet/utilities/show_loading.dart'; @@ -175,8 +179,27 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), Row( children: [ - // spacer can be replaced with a button inside an expanded if a second button is wanted here - const Spacer(), + if (ref + .watch(fusionProgressUIStateProvider(widget.walletId)) + .succeeded) + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Fuse again", + onPressed: () => _fuseAgain, + ), + ), + if (ref + .watch(fusionProgressUIStateProvider(widget.walletId)) + .failed) + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Try again", + onPressed: () => _fuseAgain, + ), + ), + // if (!_succeeded! && !_failed!) const Spacer(), const SizedBox( width: 16, ), @@ -204,4 +227,16 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), ); } + + /// Fuse again. + void _fuseAgain() async { + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + final fusionInfo = ref.read(prefsChangeNotifierProvider).fusionServerInfo; + + unawaited(fusionWallet.fuse(fusionInfo: fusionInfo)); + } } From 247561ad6b511998e7ef9b2f7dcd3f616f754a57 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 12:54:22 -0500 Subject: [PATCH 286/379] add responsive spacer --- lib/pages/cashfusion/fusion_progress_view.dart | 18 +++++++++--------- .../cashfusion/sub_widgets/fusion_dialog.dart | 16 +++++++++------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index bd5757405..0ffc1e2e5 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -89,6 +89,12 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { @override Widget build(BuildContext context) { + bool _succeeded = + ref.watch(fusionProgressUIStateProvider(widget.walletId)).succeeded; + + bool _failed = + ref.watch(fusionProgressUIStateProvider(widget.walletId)).failed; + return WillPopScope( onWillPop: () async { return await _requestAndProcessCancel(); @@ -130,10 +136,7 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { FusionProgress( walletId: widget.walletId, ), - if (ref - .watch(fusionProgressUIStateProvider( - widget.walletId)) - .succeeded) + if (_succeeded) Expanded( child: PrimaryButton( buttonHeight: ButtonHeight.m, @@ -141,10 +144,7 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { onPressed: () => _fuseAgain, ), ), - if (ref - .watch(fusionProgressUIStateProvider( - widget.walletId)) - .failed) + if (_failed) Expanded( child: PrimaryButton( buttonHeight: ButtonHeight.m, @@ -152,7 +152,7 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { onPressed: () => _fuseAgain, ), ), - // if (!_succeeded! && !_failed!) const Spacer(), + if (!_succeeded! && !_failed!) const Spacer(), const SizedBox( height: 16, ), diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 78fae11ab..a67fd0b3d 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -136,6 +136,12 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { @override Widget build(BuildContext context) { + bool _succeeded = + ref.watch(fusionProgressUIStateProvider(widget.walletId)).succeeded; + + bool _failed = + ref.watch(fusionProgressUIStateProvider(widget.walletId)).failed; + return DesktopDialog( maxHeight: 600, child: SingleChildScrollView( @@ -179,9 +185,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), Row( children: [ - if (ref - .watch(fusionProgressUIStateProvider(widget.walletId)) - .succeeded) + if (_succeeded) Expanded( child: PrimaryButton( buttonHeight: ButtonHeight.m, @@ -189,9 +193,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { onPressed: () => _fuseAgain, ), ), - if (ref - .watch(fusionProgressUIStateProvider(widget.walletId)) - .failed) + if (_failed) Expanded( child: PrimaryButton( buttonHeight: ButtonHeight.m, @@ -199,7 +201,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { onPressed: () => _fuseAgain, ), ), - // if (!_succeeded! && !_failed!) const Spacer(), + if (!_succeeded! && !_failed!) const Spacer(), const SizedBox( width: 16, ), From 9c67ccdc3e5b45332b98e785e774cf1685921ecb Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 14:43:07 -0500 Subject: [PATCH 287/379] add mobile fusion round count on success --- .../cashfusion/fusion_progress_view.dart | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 0ffc1e2e5..752a40788 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -25,6 +25,7 @@ import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/rounded_container.dart'; import 'package:stackwallet/widgets/stack_dialog.dart'; class FusionProgressView extends ConsumerStatefulWidget { @@ -95,6 +96,10 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { bool _failed = ref.watch(fusionProgressUIStateProvider(widget.walletId)).failed; + int _fusionRoundsCompleted = ref + .watch(fusionProgressUIStateProvider(widget.walletId)) + .fusionRoundsCompleted; + return WillPopScope( onWillPop: () async { return await _requestAndProcessCancel(); @@ -133,6 +138,27 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { padding: const EdgeInsets.all(16), child: Column( children: [ + // TODO if (_succeeded but roundCount > roundCount) + // show "Fusion completed" as snackBarBackSuccess. + if (_succeeded) + RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackInfo, + child: Text( + "Fusion rounds completed: $_fusionRoundsCompleted", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextInfo, + ), + textAlign: TextAlign.center, + ), + ), + if (_succeeded) + const SizedBox( + height: 20, + ), FusionProgress( walletId: widget.walletId, ), From b87812f167ac72bc0ad428c028c9e0d8832c3e9c Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 14:50:30 -0500 Subject: [PATCH 288/379] add fusion round readout to desktop and persist mobile message --- .../cashfusion/fusion_progress_view.dart | 4 +- .../cashfusion/sub_widgets/fusion_dialog.dart | 45 +++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 752a40788..6bdfe3a76 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -140,7 +140,7 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { children: [ // TODO if (_succeeded but roundCount > roundCount) // show "Fusion completed" as snackBarBackSuccess. - if (_succeeded) + if (_fusionRoundsCompleted > 0) RoundedContainer( color: Theme.of(context) .extension<StackColors>()! @@ -155,7 +155,7 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { textAlign: TextAlign.center, ), ), - if (_succeeded) + if (_fusionRoundsCompleted > 0) const SizedBox( height: 20, ), diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index a67fd0b3d..3aefdfd69 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -7,12 +7,14 @@ import 'package:stackwallet/providers/cash_fusion/fusion_progress_ui_state_provi import 'package:stackwallet/providers/global/prefs_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/services/mixins/fusion_wallet_interface.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/show_loading.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/rounded_container.dart'; enum CashFusionStatus { waiting, running, success, failed } @@ -142,6 +144,10 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { bool _failed = ref.watch(fusionProgressUIStateProvider(widget.walletId)).failed; + int _fusionRoundsCompleted = ref + .watch(fusionProgressUIStateProvider(widget.walletId)) + .fusionRoundsCompleted; + return DesktopDialog( maxHeight: 600, child: SingleChildScrollView( @@ -177,6 +183,45 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), child: Column( children: [ + if (_fusionRoundsCompleted > 0) + RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackInfo, + child: Text( + "Fusion rounds completed: $_fusionRoundsCompleted", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextInfo, + ), + textAlign: TextAlign.center, + ), + ), + if (_fusionRoundsCompleted > 0) + const SizedBox( + height: 20, + ), + FusionProgress( + walletId: widget.walletId, + ), + if (_succeeded) + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Fuse again", + onPressed: () => _fuseAgain, + ), + ), + if (_failed) + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Try again", + onPressed: () => _fuseAgain, + ), + ), + if (!_succeeded! && !_failed!) const Spacer(), FusionProgress( walletId: widget.walletId, ), From db9dfd2e5baf613db3e648111697c4ef132a8277 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 16:04:50 -0500 Subject: [PATCH 289/379] disable try again debugging --- lib/models/fusion_progress_ui_state.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 78c32bead..b3ac92196 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -133,7 +133,7 @@ class FusionProgressUIState extends ChangeNotifier { /// Set from the interface. I didn't want to have to configure /// /// Used to be named maxConsecutiveFusionRoundsFailed. - bool _failed = true; + bool _failed = false; bool get failed => _failed; set failed(bool failed) { _failed = failed; From dd2926095b82bc842d77a670a48beba83d3e5eab Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 16:05:01 -0500 Subject: [PATCH 290/379] remove null assertions --- lib/pages/cashfusion/fusion_progress_view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 6bdfe3a76..562fa7b68 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -178,7 +178,7 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { onPressed: () => _fuseAgain, ), ), - if (!_succeeded! && !_failed!) const Spacer(), + if (!_succeeded && !_failed) const Spacer(), const SizedBox( height: 16, ), From 893d1f783cccab9d2fcacce3b461e587087402c8 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 16:05:45 -0500 Subject: [PATCH 291/379] expand round completed message --- .../cashfusion/sub_widgets/fusion_dialog.dart | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 3aefdfd69..46cac5aa4 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -184,18 +184,20 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { child: Column( children: [ if (_fusionRoundsCompleted > 0) - RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackInfo, - child: Text( - "Fusion rounds completed: $_fusionRoundsCompleted", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextInfo, + Expanded( + child: RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackInfo, + child: Text( + "Fusion rounds completed: $_fusionRoundsCompleted", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextInfo, + ), + textAlign: TextAlign.center, ), - textAlign: TextAlign.center, ), ), if (_fusionRoundsCompleted > 0) From b2b6777a699f5c124a30c414166e5c41fae0211a Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 16:06:31 -0500 Subject: [PATCH 292/379] remove duplicate FusionProgress --- .../cashfusion/sub_widgets/fusion_dialog.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 46cac5aa4..90d0c02ae 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -224,9 +224,6 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), ), if (!_succeeded! && !_failed!) const Spacer(), - FusionProgress( - walletId: widget.walletId, - ), const SizedBox( height: 12, ), From 0406e5f6f89dfecee829872b618f713cb2ec69da Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 16:08:29 -0500 Subject: [PATCH 293/379] remove problematic spacers what's the issue here? the check or the spacer? so weird. --- .../cashfusion/sub_widgets/fusion_dialog.dart | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 90d0c02ae..0098b03d7 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -223,7 +223,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { onPressed: () => _fuseAgain, ), ), - if (!_succeeded! && !_failed!) const Spacer(), + // if (!_succeeded && !_failed) const Spacer(), const SizedBox( height: 12, ), @@ -237,6 +237,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { onPressed: () => _fuseAgain, ), ), + if (_succeeded) const Spacer(), if (_failed) Expanded( child: PrimaryButton( @@ -245,10 +246,12 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { onPressed: () => _fuseAgain, ), ), - if (!_succeeded! && !_failed!) const Spacer(), - const SizedBox( - width: 16, - ), + if (_failed) const Spacer(), + // if (!_succeeded && !_failed) const Spacer(), + // if (!_succeeded && !_failed) + // const SizedBox( + // width: 16, + // ), Expanded( child: SecondaryButton( buttonHeight: ButtonHeight.m, From 3678cc1a4262b180cb5c9c4d789b26c8fbb25deb Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 16:26:56 -0500 Subject: [PATCH 294/379] make `ref.watch`ers final, expand mobile fusion success message --- .../cashfusion/fusion_progress_view.dart | 31 ++++++++++--------- .../cashfusion/sub_widgets/fusion_dialog.dart | 18 +++++------ 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 562fa7b68..f7e1ff45c 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -90,13 +90,13 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { @override Widget build(BuildContext context) { - bool _succeeded = + final bool _succeeded = ref.watch(fusionProgressUIStateProvider(widget.walletId)).succeeded; - bool _failed = + final bool _failed = ref.watch(fusionProgressUIStateProvider(widget.walletId)).failed; - int _fusionRoundsCompleted = ref + final int _fusionRoundsCompleted = ref .watch(fusionProgressUIStateProvider(widget.walletId)) .fusionRoundsCompleted; @@ -141,18 +141,21 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { // TODO if (_succeeded but roundCount > roundCount) // show "Fusion completed" as snackBarBackSuccess. if (_fusionRoundsCompleted > 0) - RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackInfo, - child: Text( - "Fusion rounds completed: $_fusionRoundsCompleted", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextInfo, + Expanded( + child: RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackInfo, + child: Text( + "Fusion rounds completed: $_fusionRoundsCompleted", + style: + STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextInfo, + ), + textAlign: TextAlign.center, ), - textAlign: TextAlign.center, ), ), if (_fusionRoundsCompleted > 0) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 0098b03d7..e0c9d1527 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -138,13 +138,13 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { @override Widget build(BuildContext context) { - bool _succeeded = + final bool _succeeded = ref.watch(fusionProgressUIStateProvider(widget.walletId)).succeeded; - bool _failed = + final bool _failed = ref.watch(fusionProgressUIStateProvider(widget.walletId)).failed; - int _fusionRoundsCompleted = ref + final int _fusionRoundsCompleted = ref .watch(fusionProgressUIStateProvider(widget.walletId)) .fusionRoundsCompleted; @@ -223,7 +223,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { onPressed: () => _fuseAgain, ), ), - // if (!_succeeded && !_failed) const Spacer(), + if (!_succeeded && !_failed) const Spacer(), const SizedBox( height: 12, ), @@ -247,11 +247,11 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), ), if (_failed) const Spacer(), - // if (!_succeeded && !_failed) const Spacer(), - // if (!_succeeded && !_failed) - // const SizedBox( - // width: 16, - // ), + if (!_succeeded && !_failed) const Spacer(), + if (!_succeeded && !_failed) + const SizedBox( + width: 16, + ), Expanded( child: SecondaryButton( buttonHeight: ButtonHeight.m, From 35d1c3589252bab29e5ff55da2a23c416a23502a Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 16:35:32 -0500 Subject: [PATCH 295/379] desktop cashfusion ui fixes --- .../cashfusion/sub_widgets/fusion_dialog.dart | 27 ++++++------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index e0c9d1527..8c747d3a7 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -207,23 +207,6 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { FusionProgress( walletId: widget.walletId, ), - if (_succeeded) - Expanded( - child: PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Fuse again", - onPressed: () => _fuseAgain, - ), - ), - if (_failed) - Expanded( - child: PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Try again", - onPressed: () => _fuseAgain, - ), - ), - if (!_succeeded && !_failed) const Spacer(), const SizedBox( height: 12, ), @@ -237,7 +220,10 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { onPressed: () => _fuseAgain, ), ), - if (_succeeded) const Spacer(), + if (_succeeded) + const SizedBox( + width: 16, + ), if (_failed) Expanded( child: PrimaryButton( @@ -246,7 +232,10 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { onPressed: () => _fuseAgain, ), ), - if (_failed) const Spacer(), + if (_failed) + const SizedBox( + width: 16, + ), if (!_succeeded && !_failed) const Spacer(), if (!_succeeded && !_failed) const SizedBox( From c1cfe080a0e9b0b6216a47b10988c48313b4d108 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 19 Oct 2023 15:36:47 -0600 Subject: [PATCH 296/379] WIP apply txv2 to bch --- lib/db/isar/main_db.dart | 31 + .../models/blockchain_data/transaction.dart | 3 +- .../models/blockchain_data/transaction.g.dart | 2 + .../models/blockchain_data/v2/input_v2.dart | 2 +- .../blockchain_data/v2/transaction_v2.dart | 42 +- .../blockchain_data/v2/transaction_v2.g.dart | 275 +++++++- .../sub_widgets/transaction_v2_list.dart | 588 ++++++++++++++++++ .../wallet_view/sub_widgets/tx_icon.dart | 88 ++- .../wallet_view/desktop_wallet_view.dart | 20 +- .../coins/bitcoincash/bitcoincash_wallet.dart | 330 ++++------ lib/services/mixins/electrum_x_parsing.dart | 2 + .../coins/firo/firo_wallet_test.mocks.dart | 12 + .../transaction_card_test.mocks.dart | 12 + 13 files changed, 1160 insertions(+), 247 deletions(-) create mode 100644 lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart index 796914117..61ec51545 100644 --- a/lib/db/isar/main_db.dart +++ b/lib/db/isar/main_db.dart @@ -13,6 +13,7 @@ import 'package:flutter_native_splash/cli_commands.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/exceptions/main_db/main_db_exception.dart'; import 'package:stackwallet/models/isar/models/block_explorer.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/models/isar/models/contact_entry.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/models/isar/ordinal.dart'; @@ -57,6 +58,7 @@ class MainDB { ContactEntrySchema, OrdinalSchema, LelantusCoinSchema, + TransactionV2Schema, ], directory: (await StackFileSystem.applicationIsarDirectory()).path, // inspector: kDebugMode, @@ -506,6 +508,35 @@ class MainDB { } } + Future<List<int>> updateOrPutTransactionV2s( + List<TransactionV2> transactions, + ) async { + try { + List<int> ids = []; + await isar.writeTxn(() async { + for (final tx in transactions) { + final storedTx = await isar.transactionV2s + .where() + .txidWalletIdEqualTo(tx.txid, tx.walletId) + .findFirst(); + + Id id; + if (storedTx == null) { + id = await isar.transactionV2s.put(tx); + } else { + tx.id = storedTx.id; + await isar.transactionV2s.delete(storedTx.id); + id = await isar.transactionV2s.put(tx); + } + ids.add(id); + } + }); + return ids; + } catch (e) { + throw MainDBException("failed updateOrPutAddresses: $transactions", e); + } + } + // ========== Ethereum ======================================================= // eth contracts diff --git a/lib/models/isar/models/blockchain_data/transaction.dart b/lib/models/isar/models/blockchain_data/transaction.dart index a5a814786..ecd7d51c8 100644 --- a/lib/models/isar/models/blockchain_data/transaction.dart +++ b/lib/models/isar/models/blockchain_data/transaction.dart @@ -251,5 +251,6 @@ enum TransactionSubType { bip47Notification, // bip47 payment code notification transaction flag mint, // firo specific join, // firo specific - ethToken; // eth token + ethToken, // eth token + cashFusion; } diff --git a/lib/models/isar/models/blockchain_data/transaction.g.dart b/lib/models/isar/models/blockchain_data/transaction.g.dart index c11649ddb..cd9132576 100644 --- a/lib/models/isar/models/blockchain_data/transaction.g.dart +++ b/lib/models/isar/models/blockchain_data/transaction.g.dart @@ -364,6 +364,7 @@ const _TransactionsubTypeEnumValueMap = { 'mint': 2, 'join': 3, 'ethToken': 4, + 'cashFusion': 5, }; const _TransactionsubTypeValueEnumMap = { 0: TransactionSubType.none, @@ -371,6 +372,7 @@ const _TransactionsubTypeValueEnumMap = { 2: TransactionSubType.mint, 3: TransactionSubType.join, 4: TransactionSubType.ethToken, + 5: TransactionSubType.cashFusion, }; const _TransactiontypeEnumValueMap = { 'outgoing': 0, diff --git a/lib/models/isar/models/blockchain_data/v2/input_v2.dart b/lib/models/isar/models/blockchain_data/v2/input_v2.dart index f604b75af..44a54ce19 100644 --- a/lib/models/isar/models/blockchain_data/v2/input_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/input_v2.dart @@ -72,7 +72,7 @@ class InputV2 { InputV2() ..scriptSigHex = scriptSigHex ..sequence = sequence - ..sequence = sequence + ..outpoint = outpoint ..addresses = List.unmodifiable(addresses) ..valueStringSats = valueStringSats ..witness = witness diff --git a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart index f98ca53ea..cebc5d5d9 100644 --- a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart @@ -1,14 +1,17 @@ import 'dart:math'; import 'package:isar/isar.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/v2/input_v2.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/v2/output_v2.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; part 'transaction_v2.g.dart'; @Collection() class TransactionV2 { - final Id id = Isar.autoIncrement; + Id id = Isar.autoIncrement; @Index() final String walletId; @@ -28,6 +31,12 @@ class TransactionV2 { final List<InputV2> inputs; final List<OutputV2> outputs; + @enumerated + final TransactionType type; + + @enumerated + final TransactionSubType subType; + TransactionV2({ required this.walletId, required this.blockHash, @@ -38,6 +47,8 @@ class TransactionV2 { required this.inputs, required this.outputs, required this.version, + required this.type, + required this.subType, }); int getConfirmations(int currentChainHeight) { @@ -50,12 +61,32 @@ class TransactionV2 { return confirmations >= minimumConfirms; } + Amount getFee({required Coin coin}) { + final inSum = + inputs.map((e) => e.value).reduce((value, element) => value += element); + final outSum = outputs + .map((e) => e.value) + .reduce((value, element) => value += element); + + return Amount(rawValue: inSum - outSum, fractionDigits: coin.decimals); + } + + Amount getAmount({required Coin coin}) { + final outSum = outputs + .map((e) => e.value) + .reduce((value, element) => value += element); + + return Amount(rawValue: outSum, fractionDigits: coin.decimals); + } + @override String toString() { return 'TransactionV2(\n' ' walletId: $walletId,\n' ' hash: $hash,\n' ' txid: $txid,\n' + ' type: $type,\n' + ' subType: $subType,\n' ' timestamp: $timestamp,\n' ' height: $height,\n' ' blockHash: $blockHash,\n' @@ -65,3 +96,12 @@ class TransactionV2 { ')'; } } + +enum TxDirection { + outgoing, + incoming; +} + +enum TxType { + normal, +} diff --git a/lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart b/lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart index 38772d24e..47fd5b936 100644 --- a/lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart +++ b/lib/models/isar/models/blockchain_data/v2/transaction_v2.g.dart @@ -44,23 +44,35 @@ const TransactionV2Schema = CollectionSchema( type: IsarType.objectList, target: r'OutputV2', ), - r'timestamp': PropertySchema( + r'subType': PropertySchema( id: 5, + name: r'subType', + type: IsarType.byte, + enumMap: _TransactionV2subTypeEnumValueMap, + ), + r'timestamp': PropertySchema( + id: 6, name: r'timestamp', type: IsarType.long, ), r'txid': PropertySchema( - id: 6, + id: 7, name: r'txid', type: IsarType.string, ), + r'type': PropertySchema( + id: 8, + name: r'type', + type: IsarType.byte, + enumMap: _TransactionV2typeEnumValueMap, + ), r'version': PropertySchema( - id: 7, + id: 9, name: r'version', type: IsarType.long, ), r'walletId': PropertySchema( - id: 8, + id: 10, name: r'walletId', type: IsarType.string, ) @@ -183,10 +195,12 @@ void _transactionV2Serialize( OutputV2Schema.serialize, object.outputs, ); - writer.writeLong(offsets[5], object.timestamp); - writer.writeString(offsets[6], object.txid); - writer.writeLong(offsets[7], object.version); - writer.writeString(offsets[8], object.walletId); + writer.writeByte(offsets[5], object.subType.index); + writer.writeLong(offsets[6], object.timestamp); + writer.writeString(offsets[7], object.txid); + writer.writeByte(offsets[8], object.type.index); + writer.writeLong(offsets[9], object.version); + writer.writeString(offsets[10], object.walletId); } TransactionV2 _transactionV2Deserialize( @@ -213,11 +227,17 @@ TransactionV2 _transactionV2Deserialize( OutputV2(), ) ?? [], - timestamp: reader.readLong(offsets[5]), - txid: reader.readString(offsets[6]), - version: reader.readLong(offsets[7]), - walletId: reader.readString(offsets[8]), + subType: + _TransactionV2subTypeValueEnumMap[reader.readByteOrNull(offsets[5])] ?? + TransactionSubType.none, + timestamp: reader.readLong(offsets[6]), + txid: reader.readString(offsets[7]), + type: _TransactionV2typeValueEnumMap[reader.readByteOrNull(offsets[8])] ?? + TransactionType.outgoing, + version: reader.readLong(offsets[9]), + walletId: reader.readString(offsets[10]), ); + object.id = id; return object; } @@ -251,18 +271,54 @@ P _transactionV2DeserializeProp<P>( ) ?? []) as P; case 5: - return (reader.readLong(offset)) as P; + return (_TransactionV2subTypeValueEnumMap[ + reader.readByteOrNull(offset)] ?? + TransactionSubType.none) as P; case 6: - return (reader.readString(offset)) as P; - case 7: return (reader.readLong(offset)) as P; + case 7: + return (reader.readString(offset)) as P; case 8: + return (_TransactionV2typeValueEnumMap[reader.readByteOrNull(offset)] ?? + TransactionType.outgoing) as P; + case 9: + return (reader.readLong(offset)) as P; + case 10: return (reader.readString(offset)) as P; default: throw IsarError('Unknown property with id $propertyId'); } } +const _TransactionV2subTypeEnumValueMap = { + 'none': 0, + 'bip47Notification': 1, + 'mint': 2, + 'join': 3, + 'ethToken': 4, + 'cashFusion': 5, +}; +const _TransactionV2subTypeValueEnumMap = { + 0: TransactionSubType.none, + 1: TransactionSubType.bip47Notification, + 2: TransactionSubType.mint, + 3: TransactionSubType.join, + 4: TransactionSubType.ethToken, + 5: TransactionSubType.cashFusion, +}; +const _TransactionV2typeEnumValueMap = { + 'outgoing': 0, + 'incoming': 1, + 'sentToSelf': 2, + 'unknown': 3, +}; +const _TransactionV2typeValueEnumMap = { + 0: TransactionType.outgoing, + 1: TransactionType.incoming, + 2: TransactionType.sentToSelf, + 3: TransactionType.unknown, +}; + Id _transactionV2GetId(TransactionV2 object) { return object.id; } @@ -272,7 +328,9 @@ List<IsarLinkBase<dynamic>> _transactionV2GetLinks(TransactionV2 object) { } void _transactionV2Attach( - IsarCollection<dynamic> col, Id id, TransactionV2 object) {} + IsarCollection<dynamic> col, Id id, TransactionV2 object) { + object.id = id; +} extension TransactionV2ByIndex on IsarCollection<TransactionV2> { Future<TransactionV2?> getByTxidWalletId(String txid, String walletId) { @@ -1275,6 +1333,62 @@ extension TransactionV2QueryFilter }); } + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + subTypeEqualTo(TransactionSubType value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'subType', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + subTypeGreaterThan( + TransactionSubType value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'subType', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + subTypeLessThan( + TransactionSubType value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'subType', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + subTypeBetween( + TransactionSubType lower, + TransactionSubType upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'subType', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> timestampEqualTo(int value) { return QueryBuilder.apply(this, (query) { @@ -1466,6 +1580,61 @@ extension TransactionV2QueryFilter }); } + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> typeEqualTo( + TransactionType value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'type', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + typeGreaterThan( + TransactionType value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.greaterThan( + include: include, + property: r'type', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> + typeLessThan( + TransactionType value, { + bool include = false, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.lessThan( + include: include, + property: r'type', + value: value, + )); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> typeBetween( + TransactionType lower, + TransactionType upper, { + bool includeLower = true, + bool includeUpper = true, + }) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.between( + property: r'type', + lower: lower, + includeLower: includeLower, + upper: upper, + includeUpper: includeUpper, + )); + }); + } + QueryBuilder<TransactionV2, TransactionV2, QAfterFilterCondition> versionEqualTo(int value) { return QueryBuilder.apply(this, (query) { @@ -1718,6 +1887,18 @@ extension TransactionV2QuerySortBy }); } + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortBySubType() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'subType', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortBySubTypeDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'subType', Sort.desc); + }); + } + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByTimestamp() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'timestamp', Sort.asc); @@ -1743,6 +1924,18 @@ extension TransactionV2QuerySortBy }); } + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByType() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'type', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByTypeDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'type', Sort.desc); + }); + } + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> sortByVersion() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'version', Sort.asc); @@ -1820,6 +2013,18 @@ extension TransactionV2QuerySortThenBy }); } + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenBySubType() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'subType', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenBySubTypeDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'subType', Sort.desc); + }); + } + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByTimestamp() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'timestamp', Sort.asc); @@ -1845,6 +2050,18 @@ extension TransactionV2QuerySortThenBy }); } + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByType() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'type', Sort.asc); + }); + } + + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByTypeDesc() { + return QueryBuilder.apply(this, (query) { + return query.addSortBy(r'type', Sort.desc); + }); + } + QueryBuilder<TransactionV2, TransactionV2, QAfterSortBy> thenByVersion() { return QueryBuilder.apply(this, (query) { return query.addSortBy(r'version', Sort.asc); @@ -1893,6 +2110,12 @@ extension TransactionV2QueryWhereDistinct }); } + QueryBuilder<TransactionV2, TransactionV2, QDistinct> distinctBySubType() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'subType'); + }); + } + QueryBuilder<TransactionV2, TransactionV2, QDistinct> distinctByTimestamp() { return QueryBuilder.apply(this, (query) { return query.addDistinctBy(r'timestamp'); @@ -1906,6 +2129,12 @@ extension TransactionV2QueryWhereDistinct }); } + QueryBuilder<TransactionV2, TransactionV2, QDistinct> distinctByType() { + return QueryBuilder.apply(this, (query) { + return query.addDistinctBy(r'type'); + }); + } + QueryBuilder<TransactionV2, TransactionV2, QDistinct> distinctByVersion() { return QueryBuilder.apply(this, (query) { return query.addDistinctBy(r'version'); @@ -1960,6 +2189,13 @@ extension TransactionV2QueryProperty }); } + QueryBuilder<TransactionV2, TransactionSubType, QQueryOperations> + subTypeProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'subType'); + }); + } + QueryBuilder<TransactionV2, int, QQueryOperations> timestampProperty() { return QueryBuilder.apply(this, (query) { return query.addPropertyName(r'timestamp'); @@ -1972,6 +2208,13 @@ extension TransactionV2QueryProperty }); } + QueryBuilder<TransactionV2, TransactionType, QQueryOperations> + typeProperty() { + return QueryBuilder.apply(this, (query) { + return query.addPropertyName(r'type'); + }); + } + QueryBuilder<TransactionV2, int, QQueryOperations> versionProperty() { return QueryBuilder.apply(this, (query) { return query.addPropertyName(r'version'); diff --git a/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart b/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart new file mode 100644 index 000000000..b82cd3539 --- /dev/null +++ b/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart @@ -0,0 +1,588 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by Cypher Stack on 2023-10-19 + * + */ + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:isar/isar.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/pages/exchange_view/trade_details_view.dart'; +import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart'; +import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart'; +import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; +import 'package:stackwallet/providers/db/main_db_provider.dart'; +import 'package:stackwallet/providers/global/locale_provider.dart'; +import 'package:stackwallet/providers/global/prefs_provider.dart'; +import 'package:stackwallet/providers/global/price_provider.dart'; +import 'package:stackwallet/providers/global/trades_service_provider.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; +import 'package:stackwallet/route_generator.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; +import 'package:stackwallet/utilities/amount/amount_formatter.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/format.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/loading_indicator.dart'; +import 'package:stackwallet/widgets/trade_card.dart'; +import 'package:tuple/tuple.dart'; + +class TransactionsV2List extends ConsumerStatefulWidget { + const TransactionsV2List({ + Key? key, + required this.walletId, + }) : super(key: key); + + final String walletId; + + @override + ConsumerState<TransactionsV2List> createState() => _TransactionsV2ListState(); +} + +class _TxListItem extends ConsumerWidget { + const _TxListItem({ + super.key, + required this.tx, + this.radius, + required this.coin, + }); + + final TransactionV2 tx; + final BorderRadius? radius; + final Coin coin; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final matchingTrades = ref + .read(tradesServiceProvider) + .trades + .where((e) => e.payInTxid == tx.txid || e.payOutTxid == tx.txid); + + if (tx.type == TransactionType.outgoing && matchingTrades.isNotEmpty) { + final trade = matchingTrades.first; + return Container( + decoration: BoxDecoration( + color: Theme.of(context).extension<StackColors>()!.popupBG, + borderRadius: radius, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TransactionCardV2( + key: UniqueKey(), + transaction: tx, + ), + TradeCard( + key: Key(tx.txid + + tx.type.name + + tx.hashCode.toString() + + trade.uuid), // + trade: trade, + onTap: () async { + if (Util.isDesktop) { + await showDialog<void>( + context: context, + builder: (context) => Navigator( + initialRoute: TradeDetailsView.routeName, + onGenerateRoute: RouteGenerator.generateRoute, + onGenerateInitialRoutes: (_, __) { + return [ + FadePageRoute( + DesktopDialog( + maxHeight: null, + maxWidth: 580, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 32, + bottom: 16, + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + "Trade details", + style: STextStyles.desktopH3(context), + ), + DesktopDialogCloseButton( + onPressedOverride: Navigator.of( + context, + rootNavigator: true, + ).pop, + ), + ], + ), + ), + Flexible( + child: TradeDetailsView( + tradeId: trade.tradeId, + // TODO + // transactionIfSentFromStack: tx, + transactionIfSentFromStack: null, + walletName: ref.watch( + walletsChangeNotifierProvider.select( + (value) => value + .getManager(tx.walletId) + .walletName, + ), + ), + walletId: tx.walletId, + ), + ), + ], + ), + ), + const RouteSettings( + name: TradeDetailsView.routeName, + ), + ), + ]; + }, + ), + ); + } else { + unawaited( + Navigator.of(context).pushNamed( + TradeDetailsView.routeName, + arguments: Tuple4( + trade.tradeId, + tx, + tx.walletId, + ref + .read(walletsChangeNotifierProvider) + .getManager(tx.walletId) + .walletName, + ), + ), + ); + } + }, + ) + ], + ), + ); + } else { + return Container( + decoration: BoxDecoration( + color: Theme.of(context).extension<StackColors>()!.popupBG, + borderRadius: radius, + ), + child: TransactionCardV2( + // this may mess with combined firo transactions + key: UniqueKey(), + transaction: tx, + ), + ); + } + } +} + +class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> { + bool _hasLoaded = false; + List<TransactionV2> _transactions = []; + + BorderRadius get _borderRadiusFirst { + return BorderRadius.only( + topLeft: Radius.circular( + Constants.size.circularBorderRadius, + ), + topRight: Radius.circular( + Constants.size.circularBorderRadius, + ), + ); + } + + BorderRadius get _borderRadiusLast { + return BorderRadius.only( + bottomLeft: Radius.circular( + Constants.size.circularBorderRadius, + ), + bottomRight: Radius.circular( + Constants.size.circularBorderRadius, + ), + ); + } + + @override + Widget build(BuildContext context) { + final manager = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(widget.walletId))); + + return FutureBuilder( + future: ref + .watch(mainDBProvider) + .isar + .transactionV2s + .where() + .walletIdEqualTo(widget.walletId) + .sortByTimestampDesc() + .findAll(), + builder: (fbContext, AsyncSnapshot<List<TransactionV2>> snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + _transactions = snapshot.data!; + _hasLoaded = true; + } + if (!_hasLoaded) { + return const Column( + children: [ + Spacer(), + Center( + child: LoadingIndicator( + height: 50, + width: 50, + ), + ), + Spacer( + flex: 4, + ), + ], + ); + } + if (_transactions.isEmpty) { + return const NoTransActionsFound(); + } else { + _transactions.sort((a, b) => b.timestamp - a.timestamp); + return RefreshIndicator( + onRefresh: () async { + final managerProvider = ref + .read(walletsChangeNotifierProvider) + .getManagerProvider(widget.walletId); + if (!ref.read(managerProvider).isRefreshing) { + unawaited(ref.read(managerProvider).refresh()); + } + }, + child: Util.isDesktop + ? ListView.separated( + shrinkWrap: true, + itemBuilder: (context, index) { + BorderRadius? radius; + if (_transactions.length == 1) { + radius = BorderRadius.circular( + Constants.size.circularBorderRadius, + ); + } else if (index == _transactions.length - 1) { + radius = _borderRadiusLast; + } else if (index == 0) { + radius = _borderRadiusFirst; + } + final tx = _transactions[index]; + return _TxListItem( + tx: tx, + coin: manager.coin, + radius: radius, + ); + }, + separatorBuilder: (context, index) { + return Container( + width: double.infinity, + height: 2, + color: Theme.of(context) + .extension<StackColors>()! + .background, + ); + }, + itemCount: _transactions.length, + ) + : ListView.builder( + itemCount: _transactions.length, + itemBuilder: (context, index) { + BorderRadius? radius; + bool shouldWrap = false; + if (_transactions.length == 1) { + radius = BorderRadius.circular( + Constants.size.circularBorderRadius, + ); + } else if (index == _transactions.length - 1) { + radius = _borderRadiusLast; + shouldWrap = true; + } else if (index == 0) { + radius = _borderRadiusFirst; + } + final tx = _transactions[index]; + if (shouldWrap) { + return Column( + children: [ + _TxListItem( + tx: tx, + coin: manager.coin, + radius: radius, + ), + const SizedBox( + height: WalletView.navBarHeight + 14, + ), + ], + ); + } else { + return _TxListItem( + tx: tx, + coin: manager.coin, + radius: radius, + ); + } + }, + ), + ); + } + }, + ); + } +} + +class TransactionCardV2 extends ConsumerStatefulWidget { + const TransactionCardV2({ + Key? key, + required this.transaction, + }) : super(key: key); + + final TransactionV2 transaction; + + @override + ConsumerState<TransactionCardV2> createState() => _TransactionCardStateV2(); +} + +class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> { + late final TransactionV2 _transaction; + late final String walletId; + late final String prefix; + late final String unit; + late final Coin coin; + late final TransactionType txType; + + String whatIsIt( + TransactionType type, + Coin coin, + int currentHeight, + ) { + final confirmedStatus = _transaction.isConfirmed( + currentHeight, + coin.requiredConfirmations, + ); + + if (type == TransactionType.incoming) { + // if (_transaction.isMinting) { + // return "Minting"; + // } else + if (confirmedStatus) { + return "Received"; + } else { + return "Receiving"; + } + } else if (type == TransactionType.outgoing) { + if (confirmedStatus) { + return "Sent"; + } else { + return "Sending"; + } + } else if (type == TransactionType.sentToSelf) { + return "Sent to self"; + } else { + return type.name; + } + } + + @override + void initState() { + _transaction = widget.transaction; + walletId = _transaction.walletId; + + if (Util.isDesktop) { + if (_transaction.type == TransactionType.outgoing) { + prefix = "-"; + } else if (_transaction.type == TransactionType.incoming) { + prefix = "+"; + } else { + prefix = ""; + } + } else { + prefix = ""; + } + coin = ref.read(walletsChangeNotifierProvider).getManager(walletId).coin; + + unit = coin.ticker; + super.initState(); + } + + @override + Widget build(BuildContext context) { + final locale = ref.watch( + localeServiceChangeNotifierProvider.select((value) => value.locale)); + + final baseCurrency = ref + .watch(prefsChangeNotifierProvider.select((value) => value.currency)); + + final price = ref + .watch(priceAnd24hChangeNotifierProvider + .select((value) => value.getPrice(coin))) + .item1; + + final currentHeight = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).currentHeight)); + + final amount = _transaction.getAmount(coin: coin); + + return Material( + color: Theme.of(context).extension<StackColors>()!.popupBG, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(Constants.size.circularBorderRadius), + ), + child: Padding( + padding: const EdgeInsets.all(6), + child: RawMaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + onPressed: () async { + if (Util.isDesktop) { + // TODO + // await showDialog<void>( + // context: context, + // builder: (context) => DesktopDialog( + // maxHeight: MediaQuery.of(context).size.height - 64, + // maxWidth: 580, + // child: TransactionDetailsView( + // transaction: _transaction, + // coin: coin, + // walletId: walletId, + // ), + // ), + // ); + } else { + unawaited( + Navigator.of(context).pushNamed( + TransactionDetailsView.routeName, + arguments: Tuple3( + _transaction, + coin, + walletId, + ), + ), + ); + } + }, + child: Padding( + padding: const EdgeInsets.all(8), + child: Row( + children: [ + TxIcon( + transaction: _transaction, + coin: coin, + currentHeight: currentHeight, + ), + const SizedBox( + width: 14, + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + // crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + whatIsIt( + _transaction.type, + coin, + currentHeight, + ), + style: STextStyles.itemSubtitle12(context), + ), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Builder( + builder: (_) { + return Text( + "$prefix${ref.watch(pAmountFormatter(coin)).format(amount)}", + style: STextStyles.itemSubtitle12(context), + ); + }, + ), + ), + ), + ], + ), + const SizedBox( + height: 4, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + // crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + Format.extractDateFrom(_transaction.timestamp), + style: STextStyles.label(context), + ), + ), + ), + if (ref.watch(prefsChangeNotifierProvider + .select((value) => value.externalCalls))) + const SizedBox( + width: 10, + ), + if (ref.watch(prefsChangeNotifierProvider + .select((value) => value.externalCalls))) + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Builder( + builder: (_) { + return Text( + "$prefix${Amount.fromDecimal( + amount.decimal * price, + fractionDigits: 2, + ).fiatString( + locale: locale, + )} $baseCurrency", + style: STextStyles.label(context), + ); + }, + ), + ), + ), + ], + ), + ], + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/wallet_view/sub_widgets/tx_icon.dart b/lib/pages/wallet_view/sub_widgets/tx_icon.dart index bcf7c3780..4ad06f66e 100644 --- a/lib/pages/wallet_view/sub_widgets/tx_icon.dart +++ b/lib/pages/wallet_view/sub_widgets/tx_icon.dart @@ -13,6 +13,7 @@ import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/models/isar/stack_theme.dart'; import 'package:stackwallet/themes/theme_providers.dart'; @@ -27,15 +28,24 @@ class TxIcon extends ConsumerWidget { required this.coin, }) : super(key: key); - final Transaction transaction; + final Object transaction; final int currentHeight; final Coin coin; static const Size size = Size(32, 32); String _getAssetName( - bool isCancelled, bool isReceived, bool isPending, IThemeAssets assets) { - if (!isReceived && transaction.subType == TransactionSubType.mint) { + bool isCancelled, + bool isReceived, + bool isPending, + TransactionSubType subType, + IThemeAssets assets, + ) { + if (subType == TransactionSubType.cashFusion) { + return Assets.svg.cashFusion; + } + + if (!isReceived && subType == TransactionSubType.mint) { if (isCancelled) { return Assets.svg.anonymizeFailed; } @@ -66,37 +76,61 @@ class TxIcon extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final txIsReceived = transaction.type == TransactionType.incoming; + final bool txIsReceived; + final String assetName; - final assetName = _getAssetName( - transaction.isCancelled, - txIsReceived, - !transaction.isConfirmed( - currentHeight, - coin.requiredConfirmations, - ), - ref.watch(themeAssetsProvider), - ); + if (transaction is Transaction) { + final tx = transaction as Transaction; + txIsReceived = tx.type == TransactionType.incoming; + assetName = _getAssetName( + tx.isCancelled, + txIsReceived, + !tx.isConfirmed( + currentHeight, + coin.requiredConfirmations, + ), + tx.subType, + ref.watch(themeAssetsProvider), + ); + } else if (transaction is TransactionV2) { + final tx = transaction as TransactionV2; + txIsReceived = tx.type == TransactionType.incoming; + assetName = _getAssetName( + false, + txIsReceived, + !tx.isConfirmed( + currentHeight, + coin.requiredConfirmations, + ), + tx.subType, + ref.watch(themeAssetsProvider), + ); + } else { + throw ArgumentError( + "Unknown transaction type ${transaction.runtimeType}", + ); + } return SizedBox( width: size.width, height: size.height, child: Center( - // if it starts with "assets" we assume its local - // TODO: a more thorough check - child: assetName.startsWith("assets") - ? SvgPicture.asset( + // if it starts with "assets" we assume its local + // TODO: a more thorough check + child: assetName.startsWith("assets") + ? SvgPicture.asset( + assetName, + width: size.width, + height: size.height, + ) + : SvgPicture.file( + File( assetName, - width: size.width, - height: size.height, - ) - : SvgPicture.file( - File( - assetName, - ), - width: size.width, - height: size.height, - )), + ), + width: size.width, + height: size.height, + ), + ), ); } } diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart index 0df83088b..3804475eb 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart @@ -19,6 +19,7 @@ import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/pages/add_wallet_views/add_token_view/edit_wallet_tokens_view.dart'; import 'package:stackwallet/pages/special/firo_rescan_recovery_error_dialog.dart'; import 'package:stackwallet/pages/token_view/my_tokens_view.dart'; +import 'package:stackwallet/pages/wallet_view/sub_widgets/transaction_v2_list.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/transactions_list.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions_view.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart'; @@ -514,13 +515,18 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> { ? MyTokensView( walletId: widget.walletId, ) - : TransactionsList( - managerProvider: ref.watch( - walletsChangeNotifierProvider.select( - (value) => value.getManagerProvider( - widget.walletId))), - walletId: widget.walletId, - ), + : coin == Coin.bitcoincash || + coin == Coin.bitcoincashTestnet + ? TransactionsV2List( + walletId: widget.walletId, + ) + : TransactionsList( + managerProvider: ref.watch( + walletsChangeNotifierProvider.select( + (value) => value.getManagerProvider( + widget.walletId))), + walletId: widget.walletId, + ), ), ], ), diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 05aa2c593..4c50cc306 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -19,7 +19,6 @@ import 'package:bip39/bip39.dart' as bip39; import 'package:bitbox/bitbox.dart' as bitbox; import 'package:bitcoindart/bitcoindart.dart'; import 'package:bs58check/bs58check.dart' as bs58check; -import 'package:decimal/decimal.dart'; import 'package:flutter/foundation.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; @@ -28,6 +27,9 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/address.dart' as stack_address; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/input_v2.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/output_v2.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/paymint/fee_object_model.dart'; import 'package:stackwallet/models/signing_data.dart'; @@ -1944,7 +1946,7 @@ class BitcoinCashWallet extends CoinServiceAPI } Future<List<Map<String, dynamic>>> _fetchHistory( - List<String> allAddresses) async { + Iterable<String> allAddresses) async { try { List<Map<String, dynamic>> allTxHashes = []; @@ -1956,9 +1958,10 @@ class BitcoinCashWallet extends CoinServiceAPI if (batches[batchNumber] == null) { batches[batchNumber] = {}; } - final scripthash = _convertToScriptHash(allAddresses[i], _network); + final scripthash = + _convertToScriptHash(allAddresses.elementAt(i), _network); final id = Logger.isTestEnv ? "$i" : const Uuid().v1(); - requestIdToAddressMap[id] = allAddresses[i]; + requestIdToAddressMap[id] = allAddresses.elementAt(i); batches[batchNumber]!.addAll({ id: [scripthash] }); @@ -2024,25 +2027,22 @@ class BitcoinCashWallet extends CoinServiceAPI } }).toSet(); + final allAddressesSet = {...receivingAddresses, ...changeAddresses}; + final List<Map<String, dynamic>> allTxHashes = - await _fetchHistory([...receivingAddresses, ...changeAddresses]); + await _fetchHistory(allAddressesSet); List<Map<String, dynamic>> allTransactions = []; for (final txHash in allTxHashes) { - final storedTx = await db - .getTransactions(walletId) - .filter() - .txidEqualTo(txHash["tx_hash"] as String) + final storedTx = await db.isar.transactionV2s + .where() + .txidWalletIdEqualTo(txHash["tx_hash"] as String, walletId) .findFirst(); if (storedTx == null || - storedTx.address.value == null || - storedTx.height == null || - (storedTx.height != null && storedTx.height! <= 0) - // zero conf messes this up - // !storedTx.isConfirmed(currentHeight, MINIMUM_CONFIRMATIONS) - ) { + storedTx.height == null || + (storedTx.height != null && storedTx.height! <= 0)) { final tx = await cachedElectrumXClient.getTransaction( txHash: txHash["tx_hash"] as String, verbose: true, @@ -2051,225 +2051,167 @@ class BitcoinCashWallet extends CoinServiceAPI // Logging.instance.log("TRANSACTION: ${jsonEncode(tx)}"); if (!_duplicateTxCheck(allTransactions, tx["txid"] as String)) { - tx["address"] = await db - .getAddresses(walletId) - .filter() - .valueEqualTo(txHash["address"] as String) - .findFirst(); tx["height"] = txHash["height"]; allTransactions.add(tx); } } } - // - // Logging.instance.log("addAddresses: $allAddresses", level: LogLevel.Info); - // Logging.instance.log("allTxHashes: $allTxHashes", level: LogLevel.Info); - // - // Logging.instance.log("allTransactions length: ${allTransactions.length}", - // level: LogLevel.Info); - final List<Tuple2<isar_models.Transaction, isar_models.Address?>> txns = []; + final List<TransactionV2> txns = []; for (final txData in allTransactions) { Set<String> inputAddresses = {}; Set<String> outputAddresses = {}; - Amount totalInputValue = Amount( - rawValue: BigInt.from(0), - fractionDigits: coin.decimals, - ); - Amount totalOutputValue = Amount( - rawValue: BigInt.from(0), - fractionDigits: coin.decimals, - ); + // set to true if any inputs were detected as owned by this wallet + bool wasSentFromThisWallet = false; + BigInt amountSentFromThisWallet = BigInt.zero; - Amount amountSentFromWallet = Amount( - rawValue: BigInt.from(0), - fractionDigits: coin.decimals, - ); - Amount amountReceivedInWallet = Amount( - rawValue: BigInt.from(0), - fractionDigits: coin.decimals, - ); - Amount changeAmount = Amount( - rawValue: BigInt.from(0), - fractionDigits: coin.decimals, - ); + // set to true if any outputs were detected as owned by this wallet + bool wasReceivedInThisWallet = false; + BigInt amountReceivedInThisWallet = BigInt.zero; + BigInt changeAmountReceivedInThisWallet = BigInt.zero; // parse inputs - for (final input in txData["vin"] as List) { - final prevTxid = input["txid"] as String; - final prevOut = input["vout"] as int; + final List<InputV2> inputs = []; + for (final jsonInput in txData["vin"] as List) { + final map = Map<String, dynamic>.from(jsonInput as Map); - // fetch input tx to get address - final inputTx = await cachedElectrumXClient.getTransaction( - txHash: prevTxid, - coin: coin, - ); + final List<String> addresses = []; + String valueStringSats = "0"; + OutpointV2? outpoint; - for (final output in inputTx["vout"] as List) { - // check matching output - if (prevOut == output["n"]) { - // get value - final value = Amount.fromDecimal( - Decimal.parse(output["value"].toString()), - fractionDigits: coin.decimals, - ); + final coinbase = map["coinbase"] as String?; - // add value to total - totalInputValue = totalInputValue + value; + if (coinbase == null) { + final txid = map["txid"] as String; + final vout = map["vout"] as int; - // get input(prevOut) address - final address = - output["scriptPubKey"]?["addresses"]?[0] as String? ?? - output["scriptPubKey"]?["address"] as String?; + final inputTx = await cachedElectrumXClient.getTransaction( + txHash: txid, coin: coin); - if (address != null) { - inputAddresses.add(address); + final prevOutJson = Map<String, dynamic>.from( + (inputTx["vout"] as List).firstWhere((e) => e["n"] == vout) + as Map); - // if input was from my wallet, add value to amount sent - if (receivingAddresses.contains(address) || - changeAddresses.contains(address)) { - amountSentFromWallet = amountSentFromWallet + value; - } - } - } - } - } - - // parse outputs - for (final output in txData["vout"] as List) { - // get value - final value = Amount.fromDecimal( - Decimal.parse(output["value"].toString()), - fractionDigits: coin.decimals, - ); - - // add value to total - totalOutputValue += value; - - // get output address - final address = output["scriptPubKey"]?["addresses"]?[0] as String? ?? - output["scriptPubKey"]?["address"] as String?; - if (address != null) { - outputAddresses.add(address); - - // if output was to my wallet, add value to amount received - if (receivingAddresses.contains(address)) { - amountReceivedInWallet += value; - } else if (changeAddresses.contains(address)) { - changeAmount += value; - } - } - } - - final mySentFromAddresses = [ - ...receivingAddresses.intersection(inputAddresses), - ...changeAddresses.intersection(inputAddresses) - ]; - final myReceivedOnAddresses = - receivingAddresses.intersection(outputAddresses); - final myChangeReceivedOnAddresses = - changeAddresses.intersection(outputAddresses); - - final fee = totalInputValue - totalOutputValue; - - // this is the address initially used to fetch the txid - isar_models.Address transactionAddress = - txData["address"] as isar_models.Address; - - isar_models.TransactionType type; - Amount amount; - if (mySentFromAddresses.isNotEmpty && myReceivedOnAddresses.isNotEmpty) { - // tx is sent to self - type = isar_models.TransactionType.sentToSelf; - amount = - amountSentFromWallet - amountReceivedInWallet - fee - changeAmount; - } else if (mySentFromAddresses.isNotEmpty) { - // outgoing tx - type = isar_models.TransactionType.outgoing; - amount = amountSentFromWallet - changeAmount - fee; - - // TODO fix this hack - final diff = outputAddresses.difference(myChangeReceivedOnAddresses); - final possible = - diff.isNotEmpty ? diff.first : myChangeReceivedOnAddresses.first; - - if (transactionAddress.value != possible) { - transactionAddress = isar_models.Address( - walletId: walletId, - value: possible, - publicKey: [], - type: stack_address.AddressType.nonWallet, - derivationIndex: -1, - derivationPath: null, - subType: stack_address.AddressSubType.nonWallet, + final prevOut = OutputV2.fromElectrumXJson( + prevOutJson, + decimalPlaces: coin.decimals, ); + + outpoint = OutpointV2.isarCantDoRequiredInDefaultConstructor( + txid: txid, + vout: vout, + ); + valueStringSats = prevOut.valueStringSats; + addresses.addAll(prevOut.addresses); } - } else { - // incoming tx - type = isar_models.TransactionType.incoming; - amount = amountReceivedInWallet; - } - List<isar_models.Input> inputs = []; - List<isar_models.Output> outputs = []; - - for (final json in txData["vin"] as List) { - bool isCoinBase = json['coinbase'] != null; - final input = isar_models.Input( - txid: json['txid'] as String, - vout: json['vout'] as int? ?? -1, - scriptSig: json['scriptSig']?['hex'] as String?, - scriptSigAsm: json['scriptSig']?['asm'] as String?, - isCoinbase: isCoinBase ? isCoinBase : json['is_coinbase'] as bool?, - sequence: json['sequence'] as int?, - innerRedeemScriptAsm: json['innerRedeemscriptAsm'] as String?, + final input = InputV2.isarCantDoRequiredInDefaultConstructor( + scriptSigHex: map["scriptSig"]?["hex"] as String?, + sequence: map["sequence"] as int?, + outpoint: outpoint, + valueStringSats: valueStringSats, + addresses: addresses, + witness: map["witness"] as String?, + coinbase: coinbase, + innerRedeemScriptAsm: map["innerRedeemscriptAsm"] as String?, ); + inputs.add(input); } - for (final json in txData["vout"] as List) { - final output = isar_models.Output( - scriptPubKey: json['scriptPubKey']?['hex'] as String?, - scriptPubKeyAsm: json['scriptPubKey']?['asm'] as String?, - scriptPubKeyType: json['scriptPubKey']?['type'] as String?, - scriptPubKeyAddress: - json["scriptPubKey"]?["addresses"]?[0] as String? ?? - json['scriptPubKey']['type'] as String, - value: Amount.fromDecimal( - Decimal.parse(json["value"].toString()), - fractionDigits: coin.decimals, - ).raw.toInt(), + for (final input in inputs) { + if (allAddressesSet.intersection(input.addresses.toSet()).isNotEmpty) { + wasSentFromThisWallet = true; + amountSentFromThisWallet += input.value; + } + + inputAddresses.addAll(input.addresses); + } + + // parse outputs + final List<OutputV2> outputs = []; + for (final outputJson in txData["vout"] as List) { + final output = OutputV2.fromElectrumXJson( + Map<String, dynamic>.from(outputJson as Map), + decimalPlaces: coin.decimals, ); outputs.add(output); } - final tx = isar_models.Transaction( + for (final output in outputs) { + if (allAddressesSet + .intersection(output.addresses.toSet()) + .isNotEmpty) {} + + outputAddresses.addAll(output.addresses); + + // if output was to my wallet, add value to amount received + if (receivingAddresses + .intersection(output.addresses.toSet()) + .isNotEmpty) { + wasReceivedInThisWallet = true; + amountReceivedInThisWallet += output.value; + } else if (changeAddresses + .intersection(output.addresses.toSet()) + .isNotEmpty) { + wasReceivedInThisWallet = true; + changeAmountReceivedInThisWallet += output.value; + } + } + + final totalIn = inputs + .map((e) => e.value) + .reduce((value, element) => value += element); + final totalOut = outputs + .map((e) => e.value) + .reduce((value, element) => value += element); + + final fee = totalIn - totalOut; + + isar_models.TransactionType type; + + // at least one input was owned by this wallet + if (wasSentFromThisWallet) { + type = isar_models.TransactionType.outgoing; + + if (wasReceivedInThisWallet) { + if (changeAmountReceivedInThisWallet + amountReceivedInThisWallet == + totalOut) { + // definitely sent all to self + type = isar_models.TransactionType.sentToSelf; + } else if (amountReceivedInThisWallet == BigInt.zero) { + // most likely just a typical send + // do nothing here yet + } + } + } else if (wasReceivedInThisWallet) { + // only found outputs owned by this wallet + type = isar_models.TransactionType.incoming; + } else { + throw Exception("Unexpected tx found: $txData"); + } + + final tx = TransactionV2( walletId: walletId, + blockHash: txData["blockhash"] as String?, + hash: txData["hash"] as String, txid: txData["txid"] as String, + height: txData["height"] as int?, + version: txData["version"] as int, timestamp: txData["blocktime"] as int? ?? - (DateTime.now().millisecondsSinceEpoch ~/ 1000), + DateTime.timestamp().millisecondsSinceEpoch ~/ 1000, + inputs: List.unmodifiable(inputs), + outputs: List.unmodifiable(outputs), type: type, subType: isar_models.TransactionSubType.none, - amount: amount.raw.toInt(), - amountString: amount.toJsonString(), - fee: fee.raw.toInt(), - height: txData["height"] as int?, - isCancelled: false, - isLelantus: false, - slateId: null, - otherData: null, - nonce: null, - inputs: inputs, - outputs: outputs, - numberOfMessages: null, ); - txns.add(Tuple2(tx, transactionAddress)); + txns.add(tx); } - await db.addNewTransactionData(txns, walletId); + await db.updateOrPutTransactionV2s(txns); // quick hack to notify manager to call notifyListeners if // transactions changed diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index 5fe38dfe3..79a74e2a8 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -112,6 +112,8 @@ mixin ElectrumXParsing { DateTime.timestamp().millisecondsSinceEpoch ~/ 1000, inputs: List.unmodifiable(inputs), outputs: List.unmodifiable(outputs), + subType: TransactionSubType.none, + type: TransactionType.unknown, ); } diff --git a/test/services/coins/firo/firo_wallet_test.mocks.dart b/test/services/coins/firo/firo_wallet_test.mocks.dart index 2487bf007..51d443e5a 100644 --- a/test/services/coins/firo/firo_wallet_test.mocks.dart +++ b/test/services/coins/firo/firo_wallet_test.mocks.dart @@ -12,6 +12,8 @@ import 'package:stackwallet/db/isar/main_db.dart' as _i9; import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i6; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i3; import 'package:stackwallet/models/isar/models/block_explorer.dart' as _i11; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart' + as _i14; import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i10; import 'package:stackwallet/models/isar/models/isar_models.dart' as _i12; import 'package:stackwallet/services/transaction_notification_tracker.dart' @@ -1144,6 +1146,16 @@ class MockMainDB extends _i1.Mock implements _i9.MainDB { returnValueForMissingStub: _i5.Future<void>.value(), ) as _i5.Future<void>); @override + _i5.Future<List<int>> updateOrPutTransactionV2s( + List<_i14.TransactionV2>? transactions) => + (super.noSuchMethod( + Invocation.method( + #updateOrPutTransactionV2s, + [transactions], + ), + returnValue: _i5.Future<List<int>>.value(<int>[]), + ) as _i5.Future<List<int>>); + @override _i4.QueryBuilder<_i12.EthContract, _i12.EthContract, _i4.QWhere> getEthContracts() => (super.noSuchMethod( Invocation.method( diff --git a/test/widget_tests/transaction_card_test.mocks.dart b/test/widget_tests/transaction_card_test.mocks.dart index 23748d274..cc6b23b6f 100644 --- a/test/widget_tests/transaction_card_test.mocks.dart +++ b/test/widget_tests/transaction_card_test.mocks.dart @@ -17,6 +17,8 @@ import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart' as _i13; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i12; import 'package:stackwallet/models/balance.dart' as _i9; import 'package:stackwallet/models/isar/models/block_explorer.dart' as _i38; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart' + as _i39; import 'package:stackwallet/models/isar/models/contact_entry.dart' as _i37; import 'package:stackwallet/models/isar/models/isar_models.dart' as _i24; import 'package:stackwallet/models/isar/stack_theme.dart' as _i35; @@ -3590,6 +3592,16 @@ class MockMainDB extends _i1.Mock implements _i14.MainDB { returnValueForMissingStub: _i21.Future<void>.value(), ) as _i21.Future<void>); @override + _i21.Future<List<int>> updateOrPutTransactionV2s( + List<_i39.TransactionV2>? transactions) => + (super.noSuchMethod( + Invocation.method( + #updateOrPutTransactionV2s, + [transactions], + ), + returnValue: _i21.Future<List<int>>.value(<int>[]), + ) as _i21.Future<List<int>>); + @override _i18.QueryBuilder<_i24.EthContract, _i24.EthContract, _i18.QWhere> getEthContracts() => (super.noSuchMethod( Invocation.method( From bd5bd37607b2d847dec5c2b046192dc010de73c3 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 16:38:05 -0500 Subject: [PATCH 297/379] remove outdated comment the function to which this refers has already been removed --- .../cashfusion/desktop_cashfusion_view.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart index 7a2abc6a5..7759d0885 100644 --- a/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart +++ b/lib/pages_desktop_specific/cashfusion/desktop_cashfusion_view.dart @@ -100,7 +100,6 @@ class _DesktopCashFusion extends ConsumerState<DesktopCashFusionView> { fusionInfo: newInfo, ), ); - // unawaited(fusionWallet.stepThruUiStates()); await showDialog<void>( context: context, From 45d21c23041f5b49d736a653b0f4019552cf89dc Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 16:56:16 -0500 Subject: [PATCH 298/379] disable problematic Expand()s --- .../cashfusion/fusion_progress_view.dart | 26 ++++----- .../cashfusion/sub_widgets/fusion_dialog.dart | 53 ++++++++++--------- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index f7e1ff45c..641952113 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -166,21 +166,23 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { walletId: widget.walletId, ), if (_succeeded) - Expanded( - child: PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Fuse again", - onPressed: () => _fuseAgain, - ), + /*Expanded( + child: */ + PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Fuse again", + onPressed: () => _fuseAgain, ), + // ), if (_failed) - Expanded( - child: PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Try again", - onPressed: () => _fuseAgain, - ), + /*Expanded( + child: */ + PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Try again", + onPressed: () => _fuseAgain, ), + // ), if (!_succeeded && !_failed) const Spacer(), const SizedBox( height: 16, diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 8c747d3a7..fc00841d3 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -184,22 +184,23 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { child: Column( children: [ if (_fusionRoundsCompleted > 0) - Expanded( - child: RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackInfo, - child: Text( - "Fusion rounds completed: $_fusionRoundsCompleted", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextInfo, - ), - textAlign: TextAlign.center, + /*Expanded( + child: */ + RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackInfo, + child: Text( + "Fusion rounds completed: $_fusionRoundsCompleted", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextInfo, ), + textAlign: TextAlign.center, ), ), + // ), if (_fusionRoundsCompleted > 0) const SizedBox( height: 20, @@ -213,25 +214,27 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { Row( children: [ if (_succeeded) - Expanded( - child: PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Fuse again", - onPressed: () => _fuseAgain, - ), + /*Expanded( + child: */ + PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Fuse again", + onPressed: () => _fuseAgain, ), + // ), if (_succeeded) const SizedBox( width: 16, ), if (_failed) - Expanded( - child: PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Try again", - onPressed: () => _fuseAgain, - ), + /*Expanded( + child: */ + PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Try again", + onPressed: () => _fuseAgain, ), + // ), if (_failed) const SizedBox( width: 16, From 8c1df0f2cf281af85ca454048444063c594b93a9 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 16:59:35 -0500 Subject: [PATCH 299/379] only increment successful round count on success --- .../mixins/fusion_wallet_interface.dart | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 28eb61082..9ed0980ab 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -556,6 +556,16 @@ mixin FusionWalletInterface { ? fusion.Utilities.testNet : fusion.Utilities.mainNet, ); + + // Increment the number of successfully completed fusion rounds. + _completedFuseCount++; + + // Do the same for the UI state. This also resets the failed count (for + // the UI state only). + _uiState?.incrementFusionRoundsCompleted(); + + // Also reset the failed count here. + _failedFuseCount = 0; } catch (e, s) { Logging.instance.log( "$e\n$s", @@ -574,16 +584,6 @@ mixin FusionWalletInterface { _stopRequested = true; _uiState?.failed = true; } - } finally { - // Increment the number of successfully completed fusion rounds. - _completedFuseCount++; - - // Do the same for the UI state. This also resets the failed count (for - // the UI state only). - _uiState?.incrementFusionRoundsCompleted(); - - // Also reset the failed count here. - _failedFuseCount = 0; } } } From 7e9baccedbf9c4923c3d27a45a30749dc0039964 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 17:05:28 -0500 Subject: [PATCH 300/379] Refactor "Do not close this window." message out of FusionProgress --- .../cashfusion/fusion_progress_view.dart | 26 ++++++++++++++----- .../cashfusion/sub_widgets/fusion_dialog.dart | 23 +++++++++++++--- .../sub_widgets/fusion_progress.dart | 22 ---------------- 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 641952113..33d9600c2 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -138,8 +138,23 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { padding: const EdgeInsets.all(16), child: Column( children: [ - // TODO if (_succeeded but roundCount > roundCount) - // show "Fusion completed" as snackBarBackSuccess. + if (_fusionRoundsCompleted == 0) + RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackError, + child: Text( + "Do not close this window. If you exit, " + "the process will be canceled.", + style: + STextStyles.smallMed14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextError, + ), + textAlign: TextAlign.center, + ), + ), if (_fusionRoundsCompleted > 0) Expanded( child: RoundedContainer( @@ -158,10 +173,9 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { ), ), ), - if (_fusionRoundsCompleted > 0) - const SizedBox( - height: 20, - ), + const SizedBox( + height: 20, + ), FusionProgress( walletId: widget.walletId, ), diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index fc00841d3..c6cec865a 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -183,6 +183,22 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), child: Column( children: [ + if (_fusionRoundsCompleted == 0) + RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackError, + child: Text( + "Do not close this window. If you exit, " + "the process will be canceled.", + style: STextStyles.smallMed14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextError, + ), + textAlign: TextAlign.center, + ), + ), if (_fusionRoundsCompleted > 0) /*Expanded( child: */ @@ -201,10 +217,9 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { ), ), // ), - if (_fusionRoundsCompleted > 0) - const SizedBox( - height: 20, - ), + const SizedBox( + height: 20, + ), FusionProgress( walletId: widget.walletId, ), diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart index 797fd5761..66c88bf69 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart @@ -21,28 +21,6 @@ class FusionProgress extends ConsumerWidget { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - RoundedContainer( - color: Theme.of(context).extension<StackColors>()!.snackBarBackError, - child: Text( - "Do not close this window. If you exit, " - "the process will be canceled.", - style: Util.isDesktop - ? STextStyles.smallMed14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextError, - ) - : STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextError, - ), - textAlign: TextAlign.center, - ), - ), - const SizedBox( - height: 20, - ), _ProgressItem( iconAsset: Assets.svg.node, label: "Connecting to server", From ad14c16bccdbeda52b085195a1ac0d7346fea3a5 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 19 Oct 2023 16:03:19 -0600 Subject: [PATCH 301/379] util func to check if scriptpubkey is a fusion --- lib/services/coins/bitcoincash/bch_utils.dart | 32 +++++++++++++++++++ .../coins/bitcoincash/bch_utils_test.dart | 21 ++++++++++++ 2 files changed, 53 insertions(+) diff --git a/lib/services/coins/bitcoincash/bch_utils.dart b/lib/services/coins/bitcoincash/bch_utils.dart index 296ecbdab..dfe78a2e8 100644 --- a/lib/services/coins/bitcoincash/bch_utils.dart +++ b/lib/services/coins/bitcoincash/bch_utils.dart @@ -2,8 +2,11 @@ import 'dart:typed_data'; import 'package:bitcoindart/src/utils/constants/op.dart' as op; import 'package:bitcoindart/src/utils/script.dart' as bscript; +import 'package:stackwallet/utilities/extensions/impl/string.dart'; abstract final class BchUtils { + static const FUSE_ID = 'FUZ\x00'; + static bool isSLP(Uint8List scriptPubKey) { const id = [83, 76, 80, 0]; // 'SLP\x00' final decompiled = bscript.decompile(scriptPubKey); @@ -26,4 +29,33 @@ abstract final class BchUtils { return false; } + + static bool isFUZE(Uint8List scriptPubKey) { + final id = FUSE_ID.toUint8ListFromUtf8; + final decompiled = bscript.decompile(scriptPubKey); + + if (decompiled != null && + decompiled.length > 2 && + decompiled.first == op.OPS["OP_RETURN"]) { + // check session hash length. Should be 32 bytes + final sessionHash = decompiled[2]; + if (!(sessionHash is List<int> && sessionHash.length == 32)) { + return false; + } + + final _id = decompiled[1]; + + if (_id is List<int> && _id.length == id.length) { + for (int i = 0; i < id.length; i++) { + if (_id[i] != id[i]) { + return false; + } + } + // lists match! + return true; + } + } + + return false; + } } diff --git a/test/services/coins/bitcoincash/bch_utils_test.dart b/test/services/coins/bitcoincash/bch_utils_test.dart index c25aee4fa..fb2e3220d 100644 --- a/test/services/coins/bitcoincash/bch_utils_test.dart +++ b/test/services/coins/bitcoincash/bch_utils_test.dart @@ -22,4 +22,25 @@ void main() { false, ); }); + + test("script pub key check for fuze is true", () { + expect( + BchUtils.isFUZE("6a0446555a00204d662fb69f34dc23434a61c7bbb65c9f99a247f9c8" + "b377cb4de3cadf7542f8f0" + .toUint8ListFromHex), + true, + ); + }); + + test("script pub key check for fuze is not true", () { + expect( + BchUtils.isFUZE( + "6a04534c500001010747454e45534953044d5430320f4d757461626c652054657374" + "2030321668747470733a2f2f46756c6c537461636b2e63617368200e9a18" + "8911ec0f2ac10cc9425b457d10ba14151a64eb4640f95ed7dab9e8f62601" + "004c00080000000000000001" + .toUint8ListFromHex), + false, + ); + }); } From f96306cb760b05b5741e065e867e3d3f743fcd90 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 19 Oct 2023 16:24:54 -0600 Subject: [PATCH 302/379] mark transactions as fusion txns and use txV2 throughout bch --- lib/db/isar/main_db.dart | 14 +++ .../sub_widgets/transaction_v2_list.dart | 18 ++- .../coins/bitcoincash/bitcoincash_wallet.dart | 106 ++++++++++-------- 3 files changed, 83 insertions(+), 55 deletions(-) diff --git a/lib/db/isar/main_db.dart b/lib/db/isar/main_db.dart index 61ec51545..afff7e870 100644 --- a/lib/db/isar/main_db.dart +++ b/lib/db/isar/main_db.dart @@ -386,6 +386,8 @@ class MainDB { // Future<void> deleteWalletBlockchainData(String walletId) async { final transactionCount = await getTransactions(walletId).count(); + final transactionCountV2 = + await isar.transactionV2s.where().walletIdEqualTo(walletId).count(); final addressCount = await getAddresses(walletId).count(); final utxoCount = await getUTXOs(walletId).count(); final lelantusCoinCount = @@ -404,6 +406,18 @@ class MainDB { await isar.transactions.deleteAll(txnIds); } + // transactions V2 + for (int i = 0; i < transactionCountV2; i += paginateLimit) { + final txnIds = await isar.transactionV2s + .where() + .walletIdEqualTo(walletId) + .offset(i) + .limit(paginateLimit) + .idProperty() + .findAll(); + await isar.transactionV2s.deleteAll(txnIds); + } + // addresses for (int i = 0; i < addressCount; i += paginateLimit) { final addressIds = await getAddresses(walletId) diff --git a/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart b/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart index b82cd3539..15ec84b31 100644 --- a/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart +++ b/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart @@ -367,7 +367,6 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> { late final TransactionType txType; String whatIsIt( - TransactionType type, Coin coin, int currentHeight, ) { @@ -376,7 +375,15 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> { coin.requiredConfirmations, ); - if (type == TransactionType.incoming) { + if (_transaction.subType == TransactionSubType.cashFusion) { + if (confirmedStatus) { + return "Anonymized"; + } else { + return "Anonymizing"; + } + } + + if (_transaction.type == TransactionType.incoming) { // if (_transaction.isMinting) { // return "Minting"; // } else @@ -385,16 +392,16 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> { } else { return "Receiving"; } - } else if (type == TransactionType.outgoing) { + } else if (_transaction.type == TransactionType.outgoing) { if (confirmedStatus) { return "Sent"; } else { return "Sending"; } - } else if (type == TransactionType.sentToSelf) { + } else if (_transaction.type == TransactionType.sentToSelf) { return "Sent to self"; } else { - return type.name; + return _transaction.type.name; } } @@ -506,7 +513,6 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> { fit: BoxFit.scaleDown, child: Text( whatIsIt( - _transaction.type, coin, currentHeight, ), diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 4c50cc306..10bf44a49 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -188,6 +188,7 @@ class BitcoinCashWallet extends CoinServiceAPI @override Future<List<isar_models.UTXO>> get utxos => db.getUTXOs(walletId).findAll(); + @Deprecated("V2 soon (tm)") @override Future<List<isar_models.Transaction>> get transactions => db.getTransactions(walletId).sortByTimestampDesc().findAll(); @@ -793,18 +794,20 @@ class BitcoinCashWallet extends CoinServiceAPI Future<void> getAllTxsToWatch() async { if (_hasCalledExit) return; - List<isar_models.Transaction> unconfirmedTxnsToNotifyPending = []; - List<isar_models.Transaction> unconfirmedTxnsToNotifyConfirmed = []; + List<TransactionV2> unconfirmedTxnsToNotifyPending = []; + List<TransactionV2> unconfirmedTxnsToNotifyConfirmed = []; final currentChainHeight = await chainHeight; - final txCount = await db.getTransactions(walletId).count(); + final txCount = + await db.isar.transactionV2s.where().walletIdEqualTo(walletId).count(); const paginateLimit = 50; for (int i = 0; i < txCount; i += paginateLimit) { - final transactions = await db - .getTransactions(walletId) + final transactions = await db.isar.transactionV2s + .where() + .walletIdEqualTo(walletId) .offset(i) .limit(paginateLimit) .findAll(); @@ -1282,37 +1285,38 @@ class BitcoinCashWallet extends CoinServiceAPI // transactions locally in a good way @override Future<void> updateSentCachedTxData(Map<String, dynamic> txData) async { - final transaction = isar_models.Transaction( - walletId: walletId, - txid: txData["txid"] as String, - timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, - type: isar_models.TransactionType.outgoing, - subType: isar_models.TransactionSubType.none, - // precision may be lost here hence the following amountString - amount: (txData["recipientAmt"] as Amount).raw.toInt(), - amountString: (txData["recipientAmt"] as Amount).toJsonString(), - fee: txData["fee"] as int, - height: null, - isCancelled: false, - isLelantus: false, - otherData: null, - slateId: null, - nonce: null, - inputs: [], - outputs: [], - numberOfMessages: null, - ); - - final address = txData["address"] is String - ? await db.getAddress(walletId, txData["address"] as String) - : null; - - await db.addNewTransactionData( - [ - Tuple2(transaction, address), - ], - walletId, - ); + //. TODO update this to V2 properly + // final transaction = TransactionV2( + // walletId: walletId, + // txid: txData["txid"] as String, + // timestamp: DateTime.now().millisecondsSinceEpoch ~/ 1000, + // type: isar_models.TransactionType.outgoing, + // subType: isar_models.TransactionSubType.none, + // // precision may be lost here hence the following amountString + // amount: (txData["recipientAmt"] as Amount).raw.toInt(), + // amountString: (txData["recipientAmt"] as Amount).toJsonString(), + // fee: txData["fee"] as int, + // height: null, + // isCancelled: false, + // isLelantus: false, + // otherData: null, + // slateId: null, + // nonce: null, + // inputs: [], + // outputs: [], + // numberOfMessages: null, + // ); + // + // final address = txData["address"] is String + // ? await db.getAddress(walletId, txData["address"] as String) + // : null; + // + // await db.addNewTransactionData( + // [ + // Tuple2(transaction, address), + // ], + // walletId, + // ); } bool validateCashAddr(String cashAddr) { @@ -2060,12 +2064,10 @@ class BitcoinCashWallet extends CoinServiceAPI final List<TransactionV2> txns = []; for (final txData in allTransactions) { - Set<String> inputAddresses = {}; - Set<String> outputAddresses = {}; - // set to true if any inputs were detected as owned by this wallet bool wasSentFromThisWallet = false; - BigInt amountSentFromThisWallet = BigInt.zero; + BigInt amountSentFromThisWallet = + BigInt.zero; // unsure if needed. Not used rn // set to true if any outputs were detected as owned by this wallet bool wasReceivedInThisWallet = false; @@ -2126,8 +2128,6 @@ class BitcoinCashWallet extends CoinServiceAPI wasSentFromThisWallet = true; amountSentFromThisWallet += input.value; } - - inputAddresses.addAll(input.addresses); } // parse outputs @@ -2141,12 +2141,6 @@ class BitcoinCashWallet extends CoinServiceAPI } for (final output in outputs) { - if (allAddressesSet - .intersection(output.addresses.toSet()) - .isNotEmpty) {} - - outputAddresses.addAll(output.addresses); - // if output was to my wallet, add value to amount received if (receivingAddresses .intersection(output.addresses.toSet()) @@ -2171,6 +2165,8 @@ class BitcoinCashWallet extends CoinServiceAPI final fee = totalIn - totalOut; isar_models.TransactionType type; + isar_models.TransactionSubType subType = + isar_models.TransactionSubType.none; // at least one input was owned by this wallet if (wasSentFromThisWallet) { @@ -2185,6 +2181,18 @@ class BitcoinCashWallet extends CoinServiceAPI // most likely just a typical send // do nothing here yet } + + // check vout 0 for special scripts + if (outputs.isNotEmpty) { + final output = outputs.first; + + // check for fusion + if (BchUtils.isFUZE(output.scriptPubKeyHex.toUint8ListFromHex)) { + subType = isar_models.TransactionSubType.cashFusion; + } else { + // check other cases here such as SLP or cash tokens etc + } + } } } else if (wasReceivedInThisWallet) { // only found outputs owned by this wallet @@ -2205,7 +2213,7 @@ class BitcoinCashWallet extends CoinServiceAPI inputs: List.unmodifiable(inputs), outputs: List.unmodifiable(outputs), type: type, - subType: isar_models.TransactionSubType.none, + subType: subType, ); txns.add(tx); From 10d172184f56687b87bf34c1a768ab55960c458d Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 19 Oct 2023 17:32:46 -0500 Subject: [PATCH 303/379] uncomment problem-Expanded()s --- .../cashfusion/fusion_progress_view.dart | 54 ++++++------- .../cashfusion/sub_widgets/fusion_dialog.dart | 79 +++++++++---------- 2 files changed, 66 insertions(+), 67 deletions(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 33d9600c2..562ab5c22 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -139,20 +139,22 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { child: Column( children: [ if (_fusionRoundsCompleted == 0) - RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackError, - child: Text( - "Do not close this window. If you exit, " - "the process will be canceled.", - style: - STextStyles.smallMed14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextError, + Expanded( + child: RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackError, + child: Text( + "Do not close this window. If you exit, " + "the process will be canceled.", + style: STextStyles.smallMed14(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextError, + ), + textAlign: TextAlign.center, ), - textAlign: TextAlign.center, ), ), if (_fusionRoundsCompleted > 0) @@ -180,23 +182,21 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { walletId: widget.walletId, ), if (_succeeded) - /*Expanded( - child: */ - PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Fuse again", - onPressed: () => _fuseAgain, + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Fuse again", + onPressed: () => _fuseAgain, + ), ), - // ), if (_failed) - /*Expanded( - child: */ - PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Try again", - onPressed: () => _fuseAgain, + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Try again", + onPressed: () => _fuseAgain, + ), ), - // ), if (!_succeeded && !_failed) const Spacer(), const SizedBox( height: 16, diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index c6cec865a..a3f1911c7 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -184,39 +184,40 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { child: Column( children: [ if (_fusionRoundsCompleted == 0) - RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackError, - child: Text( - "Do not close this window. If you exit, " - "the process will be canceled.", - style: STextStyles.smallMed14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextError, + Expanded( + child: RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackError, + child: Text( + "Do not close this window. If you exit, " + "the process will be canceled.", + style: STextStyles.smallMed14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextError, + ), + textAlign: TextAlign.center, ), - textAlign: TextAlign.center, ), ), if (_fusionRoundsCompleted > 0) - /*Expanded( - child: */ - RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackInfo, - child: Text( - "Fusion rounds completed: $_fusionRoundsCompleted", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextInfo, + Expanded( + child: RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackInfo, + child: Text( + "Fusion rounds completed: $_fusionRoundsCompleted", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextInfo, + ), + textAlign: TextAlign.center, ), - textAlign: TextAlign.center, ), ), - // ), const SizedBox( height: 20, ), @@ -229,27 +230,25 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { Row( children: [ if (_succeeded) - /*Expanded( - child: */ - PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Fuse again", - onPressed: () => _fuseAgain, + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Fuse again", + onPressed: () => _fuseAgain, + ), ), - // ), if (_succeeded) const SizedBox( width: 16, ), if (_failed) - /*Expanded( - child: */ - PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Try again", - onPressed: () => _fuseAgain, + Expanded( + child: PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Try again", + onPressed: () => _fuseAgain, + ), ), - // ), if (_failed) const SizedBox( width: 16, From 3a8511eadebbeece52d8acd9068328774f27f257 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 19 Oct 2023 16:48:15 -0600 Subject: [PATCH 304/379] Expanded hell fix --- .../cashfusion/sub_widgets/fusion_dialog.dart | 58 +++++++++---------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index a3f1911c7..1e6099cd4 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -15,6 +15,7 @@ import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/rounded_container.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; enum CashFusionStatus { waiting, running, success, failed } @@ -182,42 +183,35 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { bottom: 32, ), child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - if (_fusionRoundsCompleted == 0) - Expanded( - child: RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackError, - child: Text( - "Do not close this window. If you exit, " - "the process will be canceled.", - style: STextStyles.smallMed14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextError, + _fusionRoundsCompleted > 0 + ? RoundedWhiteContainer( + child: Text( + "Fusion rounds completed: $_fusionRoundsCompleted", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textSubtitle1, + ), + textAlign: TextAlign.center, ), - textAlign: TextAlign.center, - ), - ), - ), - if (_fusionRoundsCompleted > 0) - Expanded( - child: RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackInfo, - child: Text( - "Fusion rounds completed: $_fusionRoundsCompleted", - style: STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextInfo, + ) + : RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackError, + child: Text( + "Do not close this window. If you exit, " + "the process will be canceled.", + style: STextStyles.smallMed14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextError, + ), + textAlign: TextAlign.center, ), - textAlign: TextAlign.center, ), - ), - ), const SizedBox( height: 20, ), From fb1a9974065976b7e8613df9f6b45ea43bae0ca4 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 19 Oct 2023 16:49:35 -0600 Subject: [PATCH 305/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index cad52f0ee..b93220d2f 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit cad52f0ee123c30cd881482817b4e078f1472d8b +Subproject commit b93220d2f133ac076e7ebe7f433bd6f248721e16 From fd6bb546f7d1f9699bdb9b9a4d3f351997f66519 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 19 Oct 2023 17:10:44 -0600 Subject: [PATCH 306/379] untested fusion ui state update change --- lib/services/mixins/fusion_wallet_interface.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 9ed0980ab..5be8f4747 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -417,6 +417,12 @@ mixin FusionWalletInterface { }) async { // Initial attempt for CashFusion integration goes here. + _updateStatus(status: fusion.FusionStatus.reset); + _updateStatus( + status: fusion.FusionStatus.connecting, + info: "Connecting to the CashFusion server.", + ); + // Use server host and port which ultimately come from text fields. fusion.FusionParams serverParams = fusion.FusionParams( serverHost: fusionInfo.host, @@ -484,6 +490,14 @@ mixin FusionWalletInterface { } while (shouldFuzeAgain()) { + if (_completedFuseCount > 0 || _failedFuseCount > 0) { + _updateStatus(status: fusion.FusionStatus.reset); + _updateStatus( + status: fusion.FusionStatus.connecting, + info: "Connecting to the CashFusion server.", + ); + } + // refresh wallet utxos await _updateWalletUTXOS(); From 1004b2403661c2d5884a1a0ef9838777d7a39539 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 19 Oct 2023 17:10:53 -0600 Subject: [PATCH 307/379] untested fusion ui state update change ref update --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index b93220d2f..77cb4f97a 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit b93220d2f133ac076e7ebe7f433bd6f248721e16 +Subproject commit 77cb4f97a8ed39243a9f5e426124e9c3c73ac2d5 From 5eae1f1a06f5fd2f9411cd4c4265e600349b8c98 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 20 Oct 2023 10:28:49 -0500 Subject: [PATCH 308/379] polish fusion progress item spacing --- .../cashfusion/sub_widgets/fusion_progress.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart index 66c88bf69..f5112e4fc 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart @@ -134,7 +134,7 @@ class _ProgressItem extends StatelessWidget { child: _getIconForState(state.status, context), ), title: label, - subTitle: state.info != null + subTitle: state.info != null && state.info!.isNotEmpty ? Text( state.info!, style: STextStyles.w500_12(context).copyWith( From 1ce572b03aea3dc8f14068f4ffd5e7c2ce390192 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 20 Oct 2023 10:29:08 -0500 Subject: [PATCH 309/379] update fusiondart ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 77cb4f97a..1f4a67084 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 77cb4f97a8ed39243a9f5e426124e9c3c73ac2d5 +Subproject commit 1f4a6708484cc746db34bc36c254c29ead9a4ddb From 8c186d7ae677b94ca19ab66901be7a432143a2af Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Oct 2023 10:38:47 -0600 Subject: [PATCH 310/379] add fusion tx icon --- assets/svg/tx-cashfusion.svg | 11 ++ .../wallet_view/sub_widgets/tx_icon.dart | 2 +- lib/utilities/assets.dart | 1 + pubspec.yaml | 131 +----------------- 4 files changed, 14 insertions(+), 131 deletions(-) create mode 100644 assets/svg/tx-cashfusion.svg diff --git a/assets/svg/tx-cashfusion.svg b/assets/svg/tx-cashfusion.svg new file mode 100644 index 000000000..d9055b6c6 --- /dev/null +++ b/assets/svg/tx-cashfusion.svg @@ -0,0 +1,11 @@ +<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g clip-path="url(#clip0_9211_24577)"> +<circle cx="16" cy="16" r="16" fill="#D2EBE4"/> +<path d="M23.7686 18.576V13.2748C24.4112 13.0568 24.8816 12.4487 24.8816 11.7372C24.8816 10.8422 24.1587 10.1193 23.2637 10.1193C22.8392 10.1193 22.449 10.2915 22.1507 10.5668L17.6298 7.96213C17.6527 7.84739 17.6642 7.73264 17.6642 7.6179C17.6642 6.72289 16.9413 6 16.0463 6C15.1513 6 14.4169 6.72289 14.4169 7.6179C14.4169 7.73264 14.4284 7.83592 14.4513 7.95066L9.88449 10.5898C9.58615 10.3029 9.18455 10.1193 8.73704 10.1193C7.84203 10.1193 7.11914 10.8422 7.11914 11.7372C7.11914 12.4831 7.62402 13.1142 8.32396 13.2978V18.5531C7.63549 18.7367 7.11914 19.3678 7.11914 20.1136C7.11914 21.0086 7.84203 21.7315 8.73704 21.7315C9.1616 21.7315 9.55173 21.5594 9.85006 21.284L14.4743 23.9575C14.4399 24.0952 14.4169 24.2329 14.4169 24.3821C14.4169 25.2771 15.1398 26 16.0348 26C16.9298 26 17.6642 25.2886 17.6642 24.3936C17.6642 24.2444 17.6412 24.1067 17.6068 23.969L22.1851 21.3299C22.472 21.5823 22.8506 21.743 23.2637 21.743C24.1587 21.743 24.8816 21.0201 24.8816 20.1251C24.8816 19.4022 24.4112 18.794 23.7686 18.576ZM22.9539 20.8365C22.69 20.7217 22.4949 20.4693 22.4835 20.1595C22.4835 20.148 22.4835 20.1365 22.4835 20.1251V20.1136C22.4835 20.1021 22.4835 20.0906 22.4835 20.0677C22.4949 19.8153 22.6326 19.5858 22.8392 19.4596C22.8506 19.4481 22.8621 19.4366 22.8851 19.4366C22.8965 19.4366 22.908 19.4251 22.9195 19.4251C23.0228 19.3678 23.149 19.3448 23.2752 19.3448C23.4473 19.3448 23.608 19.4022 23.7456 19.5055C23.7571 19.5169 23.7801 19.5284 23.7915 19.5399C23.9522 19.6776 24.0555 19.8956 24.0555 20.1251C24.0555 20.5496 23.7112 20.9053 23.2752 20.9053C23.1834 20.9053 23.1031 20.8939 23.0228 20.8594C22.9883 20.848 22.9769 20.8365 22.9539 20.8365ZM16.0463 25.1738C15.6332 25.1738 15.289 24.8411 15.266 24.428C15.266 24.4165 15.266 24.4051 15.266 24.4051C15.266 24.3936 15.266 24.3936 15.266 24.3821C15.2775 24.1182 15.4152 23.8887 15.6217 23.751C15.6676 23.7281 15.702 23.7051 15.7479 23.6822C15.7709 23.6707 15.7824 23.6707 15.8053 23.6592C15.8856 23.6363 15.966 23.6248 16.0463 23.6248C16.1266 23.6248 16.2069 23.6363 16.2872 23.6592C16.3102 23.6707 16.3217 23.6707 16.3446 23.6822C16.3905 23.7051 16.4364 23.7281 16.4708 23.751C16.6774 23.8887 16.8151 24.1182 16.8265 24.3821C16.8265 24.3936 16.8265 24.3936 16.8265 24.4051C16.8265 24.4165 16.8265 24.428 16.8265 24.428C16.8036 24.8411 16.4594 25.1738 16.0463 25.1738ZM9.04685 20.8365C8.95506 20.8709 8.85179 20.8939 8.73704 20.8939C8.31249 20.8939 7.95678 20.5496 7.95678 20.1136C7.95678 19.8382 8.09447 19.5972 8.31249 19.4596C8.32396 19.4481 8.33543 19.4366 8.35838 19.4366C8.47313 19.3678 8.59935 19.3333 8.73704 19.3333C8.74852 19.3333 8.77146 19.3333 8.78294 19.3333C8.94358 19.3448 9.08127 19.4022 9.20749 19.4825C9.21897 19.494 9.24192 19.5055 9.25339 19.5169C9.39109 19.6431 9.49436 19.8153 9.5173 20.0103C9.5173 20.0218 9.5173 20.0448 9.5173 20.0677C9.5173 20.0792 9.5173 20.0906 9.5173 20.1136C9.5173 20.148 9.5173 20.171 9.50583 20.2054C9.47141 20.4693 9.31076 20.6873 9.09275 20.8021C9.08127 20.8135 9.05833 20.825 9.04685 20.8365ZM7.96825 11.7372C7.96825 11.3127 8.31249 10.957 8.74852 10.957C8.87473 10.957 8.98948 10.9914 9.10422 11.0373C9.1157 11.0488 9.13865 11.0488 9.15012 11.0602C9.26487 11.1291 9.36814 11.2324 9.43698 11.3586C9.49436 11.4733 9.52878 11.5995 9.52878 11.7372C9.52878 11.7717 9.52878 11.7946 9.5173 11.829C9.5173 11.852 9.5173 11.8635 9.50583 11.8864C9.48288 12.0126 9.42551 12.1159 9.35666 12.2077C9.32224 12.2536 9.28782 12.288 9.25339 12.3224C9.24192 12.3339 9.23044 12.3454 9.20749 12.3569C9.08127 12.4601 8.92063 12.5175 8.73704 12.5175C8.59935 12.5175 8.47313 12.4831 8.35838 12.4142C8.34691 12.4028 8.32396 12.4028 8.31249 12.3913C8.10594 12.2421 7.96825 12.0126 7.96825 11.7372ZM16.0463 6.83764C16.4249 6.83764 16.7347 7.11302 16.8036 7.46873C16.8036 7.49168 16.8151 7.50316 16.8151 7.5261C16.8151 7.56053 16.8265 7.58348 16.8265 7.6179C16.8265 7.90476 16.6774 8.14573 16.4479 8.28342C16.4364 8.29489 16.4135 8.29489 16.402 8.30637C16.3102 8.35227 16.2069 8.38669 16.0922 8.38669C16.0807 8.38669 16.0692 8.38669 16.0463 8.38669C15.9201 8.38669 15.8053 8.35227 15.6906 8.30637C15.6791 8.29489 15.6561 8.29489 15.6447 8.28342C15.5185 8.2031 15.4152 8.09983 15.3463 7.96213C15.289 7.85886 15.266 7.73264 15.266 7.60643C15.266 7.572 15.266 7.54905 15.2775 7.51463C15.2775 7.49168 15.2775 7.48021 15.289 7.45726C15.3463 7.11302 15.6676 6.83764 16.0463 6.83764ZM22.9539 11.0258C23.0457 10.9914 23.149 10.9684 23.2637 10.9684C23.6883 10.9684 24.044 11.3127 24.044 11.7487C24.044 11.9782 23.9407 12.1962 23.7801 12.3339C23.7686 12.3454 23.7571 12.3569 23.7342 12.3683C23.608 12.4716 23.4473 12.529 23.2637 12.529C23.1604 12.529 23.0572 12.506 22.9539 12.4716C22.931 12.4601 22.908 12.4487 22.8736 12.4372C22.8621 12.4257 22.8392 12.4257 22.8277 12.4142C22.6441 12.288 22.5064 12.0929 22.4835 11.8635C22.4835 11.852 22.4835 11.829 22.4835 11.8061C22.4835 11.7946 22.4835 11.7831 22.4835 11.7602C22.4835 11.6225 22.5179 11.4963 22.5753 11.3815C22.6556 11.2438 22.7703 11.1291 22.908 11.0602C22.9195 11.0373 22.9424 11.0258 22.9539 11.0258ZM22.1163 18.9662L17.6068 16.3614C17.6412 16.2238 17.6642 16.0861 17.6642 15.9484C17.6642 15.7992 17.6412 15.6615 17.6068 15.5353L22.1507 12.9191C22.3458 13.1027 22.5753 13.2289 22.8392 13.3092V18.5645C22.5638 18.6334 22.3113 18.7711 22.1163 18.9662ZM10.2976 12.2077H12.0991C12.1794 12.4716 12.3285 12.7011 12.5121 12.8962L9.25339 18.5416V13.2748C9.74679 13.1142 10.1369 12.7126 10.2976 12.2077ZM13.6481 10.957C14.0727 10.957 14.4284 11.3012 14.4284 11.7372C14.4284 11.9208 14.371 12.0815 14.2677 12.2077C14.1415 12.3798 13.9465 12.4945 13.717 12.506C13.694 12.506 13.6711 12.506 13.6481 12.506C13.2236 12.506 12.8678 12.1618 12.8678 11.7258C12.8678 11.5881 12.9023 11.4618 12.9596 11.3471C13.0859 11.1176 13.3383 10.957 13.6252 10.9455C13.6366 10.957 13.6366 10.957 13.6481 10.957ZM13.2465 13.3092C13.3727 13.3437 13.5104 13.3551 13.6481 13.3551C14.3825 13.3551 15.0021 12.8732 15.1972 12.2077H21.6802L17.1823 14.8009C16.8839 14.5141 16.4823 14.3305 16.0348 14.3305C15.1398 14.3305 14.4169 15.0534 14.4169 15.9484C14.4169 16.0975 14.4399 16.2352 14.4743 16.3614L9.97628 18.9547L13.2465 13.3092ZM16.0463 16.7286C15.9201 16.7286 15.8053 16.6942 15.6906 16.6483C15.6676 16.6368 15.6447 16.6254 15.6217 16.6024C15.4152 16.4647 15.266 16.2238 15.266 15.9484C15.266 15.9369 15.266 15.9254 15.266 15.9025C15.289 15.4894 15.6217 15.1681 16.0348 15.1681C16.161 15.1681 16.2758 15.2025 16.3905 15.2484C16.6315 15.3746 16.8036 15.6156 16.8151 15.9025C16.8151 15.9139 16.8151 15.9254 16.8151 15.9484C16.8151 15.9598 16.8151 15.9713 16.8151 15.9943C16.7921 16.4073 16.4594 16.7286 16.0463 16.7286ZM15.2201 11.3586C15.1513 11.0717 15.0021 10.8078 14.807 10.6013L15.6332 9.17843C15.7709 9.21285 15.9086 9.2358 16.0463 9.2358C16.4938 9.2358 16.8954 9.05221 17.1937 8.76535L21.6802 11.3586H15.2201ZM14.0841 10.1767C13.9465 10.1423 13.7973 10.1193 13.6481 10.1193C12.8793 10.1193 12.2368 10.6586 12.0761 11.3701H10.4008L14.8874 8.7883L14.0841 10.1767ZM10.3205 19.7464L14.8988 17.0958C15.0939 17.2909 15.3463 17.44 15.6217 17.5089V22.8216C15.3808 22.8904 15.1627 23.0052 14.9792 23.1658L10.3205 20.4923C10.3435 20.3775 10.3664 20.2513 10.3664 20.1251C10.3664 19.9874 10.3435 19.8612 10.3205 19.7464ZM16.4708 22.833V17.5204C16.7462 17.44 16.9987 17.3024 17.1937 17.1073L21.7032 19.712C21.6688 19.8497 21.6458 19.9874 21.6458 20.1251C21.6458 20.2742 21.6688 20.4119 21.7032 20.5382L17.1249 23.1888C16.9298 23.0166 16.7118 22.9019 16.4708 22.833Z" fill="#00A578"/> +</g> +<defs> +<clipPath id="clip0_9211_24577"> +<rect width="32" height="32" fill="white"/> +</clipPath> +</defs> +</svg> diff --git a/lib/pages/wallet_view/sub_widgets/tx_icon.dart b/lib/pages/wallet_view/sub_widgets/tx_icon.dart index 4ad06f66e..1cff381ee 100644 --- a/lib/pages/wallet_view/sub_widgets/tx_icon.dart +++ b/lib/pages/wallet_view/sub_widgets/tx_icon.dart @@ -42,7 +42,7 @@ class TxIcon extends ConsumerWidget { IThemeAssets assets, ) { if (subType == TransactionSubType.cashFusion) { - return Assets.svg.cashFusion; + return Assets.svg.txCashFusion; } if (!isReceived && subType == TransactionSubType.mint) { diff --git a/lib/utilities/assets.dart b/lib/utilities/assets.dart index 0d7951706..9bb22c805 100644 --- a/lib/utilities/assets.dart +++ b/lib/utilities/assets.dart @@ -206,6 +206,7 @@ class _SVG { String get creditCard => "assets/svg/cc.svg"; String get file => "assets/svg/file.svg"; String get fileUpload => "assets/svg/file-upload.svg"; + String get txCashFusion => "assets/svg/tx-cashfusion.svg"; String get ellipse1 => "assets/svg/Ellipse-43.svg"; String get ellipse2 => "assets/svg/Ellipse-42.svg"; diff --git a/pubspec.yaml b/pubspec.yaml index 95480ff05..372c8588f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -243,136 +243,7 @@ flutter: - assets/images/splash.png - assets/icon/icon.png - google_fonts/ - - assets/svg/circle-check.svg - - assets/svg/clipboard.svg - - assets/images/glasses.png - - assets/images/glasses-hidden.png - - assets/svg/unclaimed.svg - - assets/svg/plus.svg - - assets/svg/gear.svg - - assets/svg/bell.svg - - assets/svg/arrow-left-fa.svg - - assets/svg/copy-fa.svg - - assets/svg/star.svg - - assets/svg/x-circle.svg - - assets/svg/check.svg - - assets/svg/alert-circle.svg - - assets/svg/alert-circle2.svg - - assets/svg/arrow-down-left.svg - - assets/svg/arrow-up-right.svg - - assets/svg/bars.svg - - assets/svg/filter.svg - - assets/svg/pending.svg - - assets/svg/signal-stream.svg - - assets/svg/Ellipse-43.svg - - assets/svg/Ellipse-42.svg - - assets/svg/arrow-rotate.svg - - assets/svg/arrow-rotate2.svg - - assets/svg/qrcode1.svg - - assets/svg/gear-3.svg - - assets/svg/swap.svg - - assets/svg/chevron-down.svg - - assets/svg/chevron-up.svg - - assets/svg/lock-keyhole.svg - - assets/svg/lock-open.svg - - assets/svg/folder-down.svg - - assets/svg/network-wired.svg - - assets/svg/network-wired-2.svg - - assets/svg/address-book.svg - - assets/svg/address-book2.svg - - assets/svg/arrow-right.svg - - assets/svg/delete.svg - - assets/svg/dollar-sign.svg - - assets/svg/sun-bright2.svg - - assets/svg/language2.svg - - assets/svg/pen-solid-fa.svg - - assets/svg/magnifying-glass.svg - - assets/svg/x.svg - - assets/svg/x-fat.svg - - assets/svg/user.svg - - assets/svg/user-plus.svg - - assets/svg/user-minus.svg - - assets/svg/trash.svg - - assets/svg/eye.svg - - assets/svg/eye-slash.svg - - assets/svg/folder.svg - - assets/svg/calendar-days.svg - - assets/svg/circle-question.svg - - assets/svg/info-circle.svg - - assets/svg/key.svg - - assets/svg/node-alt.svg - - assets/svg/signal-problem-alt.svg - - assets/svg/signal-sync-alt.svg - - assets/svg/wallet-settings.svg - - assets/svg/ellipsis-vertical1.svg - - assets/svg/dice-alt.svg - - assets/svg/circle-arrow-up-right2.svg - - assets/svg/loader.svg - - assets/svg/add-backup.svg - - assets/svg/auto-backup.svg - - assets/svg/restore-backup.svg - - assets/svg/sliders-solid.svg - - assets/svg/message-question.svg - - assets/svg/envelope.svg - - assets/svg/share-2.svg - - assets/svg/anonymize.svg - - assets/svg/tx-icon-anonymize.svg - - assets/svg/tx-icon-anonymize-pending.svg - - assets/svg/tx-icon-anonymize-failed.svg - - assets/svg/Polygon.svg - - assets/svg/Button.svg - - assets/svg/enabled-button.svg - - assets/svg/lock-circle.svg - - assets/svg/dollar-sign-circle.svg - - assets/svg/language-circle.svg - - assets/svg/rotate-circle.svg - - assets/svg/sun-circle.svg - - assets/svg/node-circle.svg - - assets/svg/address-book-desktop.svg - - assets/svg/about-desktop.svg - - assets/svg/exchange-desktop.svg - - assets/svg/wallet-desktop.svg - - assets/svg/exit-desktop.svg - - assets/svg/keys.svg - - assets/svg/arrow-down.svg - - assets/svg/plus-circle.svg - - assets/svg/circle-plus-filled.svg - - assets/svg/configuration.svg - - assets/svg/tokens.svg - - assets/svg/circle-plus.svg - - assets/svg/robot-head.svg - - assets/svg/whirlpool.svg - - assets/svg/fingerprint.svg - - assets/svg/faceid.svg - - assets/svg/chevron-right.svg - - assets/svg/minimize.svg - - assets/svg/wallet-fa.svg - - assets/svg/exchange-3.svg - - assets/svg/message-question-1.svg - - assets/svg/drd-icon.svg - - assets/svg/box-auto.svg - - assets/svg/framed-address-book.svg - - assets/svg/framed-gear.svg - - assets/svg/list-ul.svg - - assets/svg/cc.svg - - assets/svg/file.svg - - assets/svg/file-upload.svg - - assets/svg/trocador_rating_a.svg - - assets/svg/trocador_rating_b.svg - - assets/svg/trocador_rating_c.svg - - assets/svg/trocador_rating_d.svg - - assets/svg/send.svg - - assets/svg/ordinal.svg - - assets/svg/monkey.svg - - assets/svg/tor.svg - - assets/svg/tor-circle.svg - - assets/svg/connected-button.svg - - assets/svg/connecting-button.svg - - assets/svg/disconnected-button.svg - - assets/svg/up-from-line.svg - - assets/svg/peers.svg - - assets/svg/fusing.svg - - assets/svg/cashfusion-icon.svg + - assets/svg/ # coin control icons - assets/svg/coin_control/ From 6fb41f13ac65561c7dfad7501fd262095f605a31 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 20 Oct 2023 13:23:13 -0500 Subject: [PATCH 311/379] update status on repeated failure --- lib/services/mixins/fusion_wallet_interface.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 5be8f4747..6dccb7005 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -595,6 +595,9 @@ mixin FusionWalletInterface { // If we fail too many times in a row, stop trying. if (_failedFuseCount >= maxFailedFuseCount) { + _updateStatus( + status: fusion.FusionStatus.failed, + info: "Failed $maxFailedFuseCount times in a row, stopping."); _stopRequested = true; _uiState?.failed = true; } From a4891d8a64a7bf0fa4d8ae4cdbe2809b1e4a35e3 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 20 Oct 2023 13:23:33 -0500 Subject: [PATCH 312/379] add "running" uiState property --- lib/models/fusion_progress_ui_state.dart | 29 ++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index b3ac92196..7f3dafbc0 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -54,6 +54,7 @@ class FusionProgressUIState extends ChangeNotifier { CashFusionState get connecting => _connecting; set connecting(CashFusionState state) { _connecting = state; + _running = true; notifyListeners(); } @@ -62,6 +63,7 @@ class FusionProgressUIState extends ChangeNotifier { CashFusionState get outputs => _outputs; set outputs(CashFusionState state) { _outputs = state; + _running = true; notifyListeners(); } @@ -70,6 +72,7 @@ class FusionProgressUIState extends ChangeNotifier { CashFusionState get peers => _peers; set peers(CashFusionState state) { _peers = state; + _running = true; notifyListeners(); } @@ -78,6 +81,7 @@ class FusionProgressUIState extends ChangeNotifier { CashFusionState get fusing => _fusing; set fusing(CashFusionState state) { _fusing = state; + _updateRunningState(state.status); notifyListeners(); } @@ -86,14 +90,16 @@ class FusionProgressUIState extends ChangeNotifier { CashFusionState get complete => _complete; set complete(CashFusionState state) { _complete = state; + _updateRunningState(state.status); notifyListeners(); } CashFusionState _fusionStatus = CashFusionState(status: CashFusionStatus.waiting, info: null); CashFusionState get fusionState => _fusionStatus; - set fusionState(CashFusionState fusionStatus) { - _fusionStatus = fusionStatus; + set fusionState(CashFusionState state) { + _fusionStatus = state; + _updateRunningState(state.status); notifyListeners(); } @@ -139,4 +145,23 @@ class FusionProgressUIState extends ChangeNotifier { _failed = failed; notifyListeners(); } + + /// A flag indicating that fusion is running. + bool _running = false; + bool get running => _running; + + /// A helper method for setting the running flag. + /// + /// Sets the running flag to true if the status is running. Sets the flag to + /// false if succeeded or failed or the global failed flag is set. + void _updateRunningState(CashFusionStatus status) { + if (status == CashFusionStatus.running) { + _running = true; + } else if (((status == CashFusionStatus.success || + status == CashFusionStatus.failed) && + (done || succeeded)) || + _failed) { + _running = false; + } + } } From 27f8f86b8a21a1b99bd294c06bebfb38984cbfb7 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 20 Oct 2023 13:23:46 -0500 Subject: [PATCH 313/379] don't showLoading on fusion cancel or close if not running --- .../cashfusion/sub_widgets/fusion_dialog.dart | 174 +++++++++--------- 1 file changed, 90 insertions(+), 84 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index 1e6099cd4..fb84da245 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -40,100 +40,106 @@ class FusionDialogView extends ConsumerStatefulWidget { class _FusionDialogViewState extends ConsumerState<FusionDialogView> { Future<bool> _requestAndProcessCancel() async { - final shouldCancel = await showDialog<bool?>( - context: context, - barrierDismissible: false, - builder: (_) => DesktopDialog( - maxWidth: 580, - maxHeight: double.infinity, - child: Padding( - padding: const EdgeInsets.only( - left: 32, - right: 0, - top: 0, - bottom: 32, - ), - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Cancel fusion?", - style: STextStyles.desktopH3(context), - ), - DesktopDialogCloseButton( - onPressedOverride: () => Navigator.of(context).pop(false), - ), - ], - ), - Padding( - padding: const EdgeInsets.only( - left: 0, - right: 32, - top: 0, - bottom: 0, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + if (!ref + .read(fusionProgressUIStateProvider(widget.walletId).notifier) + .running) { + return true; + } else { + bool? shouldCancel = await showDialog<bool?>( + context: context, + barrierDismissible: false, + builder: (_) => DesktopDialog( + maxWidth: 580, + maxHeight: double.infinity, + child: Padding( + padding: const EdgeInsets.only( + left: 32, + right: 0, + top: 0, + bottom: 32, + ), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - "Do you really want to cancel the fusion process?", - style: STextStyles.smallMed14(context), - textAlign: TextAlign.left, + "Cancel fusion?", + style: STextStyles.desktopH3(context), ), - const SizedBox(height: 40), - Row( - children: [ - Expanded( - child: SecondaryButton( - label: "No", - buttonHeight: ButtonHeight.l, - onPressed: () { - Navigator.of(context).pop(false); - }, - ), - ), - const SizedBox(width: 16), - Expanded( - child: PrimaryButton( - label: "Yes", - buttonHeight: ButtonHeight.l, - onPressed: () { - Navigator.of(context).pop(true); - }, - ), - ), - ], + DesktopDialogCloseButton( + onPressedOverride: () => Navigator.of(context).pop(false), ), ], ), - ), - ], + Padding( + padding: const EdgeInsets.only( + left: 0, + right: 32, + top: 0, + bottom: 0, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Do you really want to cancel the fusion process?", + style: STextStyles.smallMed14(context), + textAlign: TextAlign.left, + ), + const SizedBox(height: 40), + Row( + children: [ + Expanded( + child: SecondaryButton( + label: "No", + buttonHeight: ButtonHeight.l, + onPressed: () { + Navigator.of(context).pop(false); + }, + ), + ), + const SizedBox(width: 16), + Expanded( + child: PrimaryButton( + label: "Yes", + buttonHeight: ButtonHeight.l, + onPressed: () { + Navigator.of(context).pop(true); + }, + ), + ), + ], + ), + ], + ), + ), + ], + ), ), ), - ), - ); - - if (shouldCancel == true && mounted) { - final fusionWallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface; - - await showLoading( - whileFuture: Future.wait([ - fusionWallet.stop(), - Future<void>.delayed(const Duration(seconds: 2)), - ]), - context: context, - isDesktop: true, - message: "Stopping fusion", ); - return true; - } else { - return false; + if (shouldCancel == true && mounted) { + final fusionWallet = ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .wallet as FusionWalletInterface; + + await showLoading( + whileFuture: Future.wait([ + fusionWallet.stop(), + Future<void>.delayed(const Duration(seconds: 2)), + ]), + context: context, + isDesktop: true, + message: "Stopping fusion", + ); + + return true; + } else { + return false; + } } } From 9d001c3fbace0d604643bab6c2fd27f9fd5ea83b Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 20 Oct 2023 13:27:17 -0500 Subject: [PATCH 314/379] add running setter and set running to false on exception in fuse --- lib/models/fusion_progress_ui_state.dart | 4 + .../mixins/fusion_wallet_interface.dart | 359 +++++++++--------- 2 files changed, 190 insertions(+), 173 deletions(-) diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 7f3dafbc0..3ce98d488 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -149,6 +149,10 @@ class FusionProgressUIState extends ChangeNotifier { /// A flag indicating that fusion is running. bool _running = false; bool get running => _running; + set running(bool running) { + _running = running; + notifyListeners(); + } /// A helper method for setting the running flag. /// diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 6dccb7005..ebd9d59f5 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -417,191 +417,204 @@ mixin FusionWalletInterface { }) async { // Initial attempt for CashFusion integration goes here. - _updateStatus(status: fusion.FusionStatus.reset); - _updateStatus( - status: fusion.FusionStatus.connecting, - info: "Connecting to the CashFusion server.", - ); + try { + _updateStatus(status: fusion.FusionStatus.reset); + _updateStatus( + status: fusion.FusionStatus.connecting, + info: "Connecting to the CashFusion server.", + ); - // Use server host and port which ultimately come from text fields. - fusion.FusionParams serverParams = fusion.FusionParams( - serverHost: fusionInfo.host, - serverPort: fusionInfo.port, - serverSsl: fusionInfo.ssl, - ); + // Use server host and port which ultimately come from text fields. + fusion.FusionParams serverParams = fusion.FusionParams( + serverHost: fusionInfo.host, + serverPort: fusionInfo.port, + serverSsl: fusionInfo.ssl, + ); - // Instantiate a Fusion object with custom parameters. - _mainFusionObject = fusion.Fusion(serverParams); + // Instantiate a Fusion object with custom parameters. + _mainFusionObject = fusion.Fusion(serverParams); - // Pass wallet functions to the Fusion object - await _mainFusionObject!.initFusion( - getTransactionsByAddress: _getTransactionsByAddress, - getUnusedReservedChangeAddresses: _getUnusedReservedChangeAddresses, - getSocksProxyAddress: _getSocksProxyAddress, - getChainHeight: _getChainHeight, - updateStatusCallback: _updateStatus, - getTransactionJson: (String txid) async => - await _getWalletCachedElectrumX().getTransaction( - coin: _coin, - txHash: txid, - ), - getPrivateKeyForPubKey: _getPrivateKeyForPubKey, - broadcastTransaction: (String txHex) => _getWalletCachedElectrumX() - .electrumXClient - .broadcastTransaction(rawTx: txHex), - unReserveAddresses: (List<fusion.Address> addresses) async { - final List<Future<void>> futures = []; - for (final addr in addresses) { - futures.add( - _db.getAddress(_walletId, addr.address).then( - (address) async { - if (address == null) { - // matching address not found in db so cannot mark as unreserved - // just ignore I guess. Should never actually happen in practice. - // Might be useful check in debugging cases? - return; - } else { - await _unReserveAddress(address); - } - }, - ), - ); - } - await Future.wait(futures); - }, - ); + // Pass wallet functions to the Fusion object + await _mainFusionObject!.initFusion( + getTransactionsByAddress: _getTransactionsByAddress, + getUnusedReservedChangeAddresses: _getUnusedReservedChangeAddresses, + getSocksProxyAddress: _getSocksProxyAddress, + getChainHeight: _getChainHeight, + updateStatusCallback: _updateStatus, + getTransactionJson: (String txid) async => + await _getWalletCachedElectrumX().getTransaction( + coin: _coin, + txHash: txid, + ), + getPrivateKeyForPubKey: _getPrivateKeyForPubKey, + broadcastTransaction: (String txHex) => _getWalletCachedElectrumX() + .electrumXClient + .broadcastTransaction(rawTx: txHex), + unReserveAddresses: (List<fusion.Address> addresses) async { + final List<Future<void>> futures = []; + for (final addr in addresses) { + futures.add( + _db.getAddress(_walletId, addr.address).then( + (address) async { + if (address == null) { + // matching address not found in db so cannot mark as unreserved + // just ignore I guess. Should never actually happen in practice. + // Might be useful check in debugging cases? + return; + } else { + await _unReserveAddress(address); + } + }, + ), + ); + } + await Future.wait(futures); + }, + ); - // Reset internal and UI counts and flag. - _completedFuseCount = 0; - _uiState?.fusionRoundsCompleted = 0; - _failedFuseCount = 0; - _uiState?.fusionRoundsFailed = 0; - _stopRequested = false; + // Reset internal and UI counts and flag. + _completedFuseCount = 0; + _uiState?.fusionRoundsCompleted = 0; + _failedFuseCount = 0; + _uiState?.fusionRoundsFailed = 0; + _stopRequested = false; - bool shouldFuzeAgain() { - if (fusionInfo.rounds <= 0) { - // ignore count if continuous - return !_stopRequested; - } else { - // not continuous - // check to make sure we aren't doing more fusions than requested - return !_stopRequested && _completedFuseCount < fusionInfo.rounds; - } - } - - while (shouldFuzeAgain()) { - if (_completedFuseCount > 0 || _failedFuseCount > 0) { - _updateStatus(status: fusion.FusionStatus.reset); - _updateStatus( - status: fusion.FusionStatus.connecting, - info: "Connecting to the CashFusion server.", - ); - } - - // refresh wallet utxos - await _updateWalletUTXOS(); - - // Add unfrozen stack UTXOs. - final List<UTXO> walletUtxos = await _db - .getUTXOs(_walletId) - .filter() - .isBlockedEqualTo(false) - .and() - .addressIsNotNull() - .findAll(); - - final List<fusion.UtxoDTO> coinList = []; - // Loop through UTXOs, checking and adding valid ones. - for (final utxo in walletUtxos) { - final String addressString = utxo.address!; - final List<String> possibleAddresses = [addressString]; - - if (bitbox.Address.detectFormat(addressString) == - bitbox.Address.formatCashAddr) { - possibleAddresses.add(bitbox.Address.toLegacyAddress(addressString)); + bool shouldFuzeAgain() { + if (fusionInfo.rounds <= 0) { + // ignore count if continuous + return !_stopRequested; } else { - possibleAddresses.add(bitbox.Address.toCashAddress(addressString)); + // not continuous + // check to make sure we aren't doing more fusions than requested + return !_stopRequested && _completedFuseCount < fusionInfo.rounds; } - - // Fetch address to get pubkey - final addr = await _db - .getAddresses(_walletId) - .filter() - .anyOf<String, - QueryBuilder<Address, Address, QAfterFilterCondition>>( - possibleAddresses, (q, e) => q.valueEqualTo(e)) - .and() - .group((q) => q - .subTypeEqualTo(AddressSubType.change) - .or() - .subTypeEqualTo(AddressSubType.receiving)) - .and() - .typeEqualTo(AddressType.p2pkh) - .findFirst(); - - // depending on the address type in the query above this can be null - if (addr == null) { - // A utxo object should always have a non null address. - // If non found then just ignore the UTXO (aka don't fuse it) - Logging.instance.log( - "Ignoring utxo=$utxo for address=\"$addressString\" while selecting UTXOs for Fusion", - level: LogLevel.Info, - ); - continue; - } - - final dto = fusion.UtxoDTO( - txid: utxo.txid, - vout: utxo.vout, - value: utxo.value, - address: utxo.address!, - pubKey: addr.publicKey, - ); - - // Add UTXO to coinList. - coinList.add(dto); } - // Fuse UTXOs. - try { - await _mainFusionObject!.fuse( - inputsFromWallet: coinList, - network: _coin.isTestNet - ? fusion.Utilities.testNet - : fusion.Utilities.mainNet, - ); - - // Increment the number of successfully completed fusion rounds. - _completedFuseCount++; - - // Do the same for the UI state. This also resets the failed count (for - // the UI state only). - _uiState?.incrementFusionRoundsCompleted(); - - // Also reset the failed count here. - _failedFuseCount = 0; - } catch (e, s) { - Logging.instance.log( - "$e\n$s", - level: LogLevel.Error, - ); - // just continue on attempt failure - - // Increment the number of failed fusion rounds. - _failedFuseCount++; - - // Do the same for the UI state. - _uiState?.incrementFusionRoundsFailed(); - - // If we fail too many times in a row, stop trying. - if (_failedFuseCount >= maxFailedFuseCount) { + while (shouldFuzeAgain()) { + if (_completedFuseCount > 0 || _failedFuseCount > 0) { + _updateStatus(status: fusion.FusionStatus.reset); _updateStatus( - status: fusion.FusionStatus.failed, - info: "Failed $maxFailedFuseCount times in a row, stopping."); - _stopRequested = true; - _uiState?.failed = true; + status: fusion.FusionStatus.connecting, + info: "Connecting to the CashFusion server.", + ); + } + + // refresh wallet utxos + await _updateWalletUTXOS(); + + // Add unfrozen stack UTXOs. + final List<UTXO> walletUtxos = await _db + .getUTXOs(_walletId) + .filter() + .isBlockedEqualTo(false) + .and() + .addressIsNotNull() + .findAll(); + + final List<fusion.UtxoDTO> coinList = []; + // Loop through UTXOs, checking and adding valid ones. + for (final utxo in walletUtxos) { + final String addressString = utxo.address!; + final List<String> possibleAddresses = [addressString]; + + if (bitbox.Address.detectFormat(addressString) == + bitbox.Address.formatCashAddr) { + possibleAddresses + .add(bitbox.Address.toLegacyAddress(addressString)); + } else { + possibleAddresses.add(bitbox.Address.toCashAddress(addressString)); + } + + // Fetch address to get pubkey + final addr = await _db + .getAddresses(_walletId) + .filter() + .anyOf<String, + QueryBuilder<Address, Address, QAfterFilterCondition>>( + possibleAddresses, (q, e) => q.valueEqualTo(e)) + .and() + .group((q) => q + .subTypeEqualTo(AddressSubType.change) + .or() + .subTypeEqualTo(AddressSubType.receiving)) + .and() + .typeEqualTo(AddressType.p2pkh) + .findFirst(); + + // depending on the address type in the query above this can be null + if (addr == null) { + // A utxo object should always have a non null address. + // If non found then just ignore the UTXO (aka don't fuse it) + Logging.instance.log( + "Ignoring utxo=$utxo for address=\"$addressString\" while selecting UTXOs for Fusion", + level: LogLevel.Info, + ); + continue; + } + + final dto = fusion.UtxoDTO( + txid: utxo.txid, + vout: utxo.vout, + value: utxo.value, + address: utxo.address!, + pubKey: addr.publicKey, + ); + + // Add UTXO to coinList. + coinList.add(dto); + } + + // Fuse UTXOs. + try { + await _mainFusionObject!.fuse( + inputsFromWallet: coinList, + network: _coin.isTestNet + ? fusion.Utilities.testNet + : fusion.Utilities.mainNet, + ); + + // Increment the number of successfully completed fusion rounds. + _completedFuseCount++; + + // Do the same for the UI state. This also resets the failed count (for + // the UI state only). + _uiState?.incrementFusionRoundsCompleted(); + + // Also reset the failed count here. + _failedFuseCount = 0; + } catch (e, s) { + Logging.instance.log( + "$e\n$s", + level: LogLevel.Error, + ); + // just continue on attempt failure + + // Increment the number of failed fusion rounds. + _failedFuseCount++; + + // Do the same for the UI state. + _uiState?.incrementFusionRoundsFailed(); + + // If we fail too many times in a row, stop trying. + if (_failedFuseCount >= maxFailedFuseCount) { + _updateStatus( + status: fusion.FusionStatus.failed, + info: "Failed $maxFailedFuseCount times in a row, stopping."); + _stopRequested = true; + _uiState?.failed = true; + } } } + } catch (e, s) { + Logging.instance.log( + "$e\n$s", + level: LogLevel.Error, + ); + + // Stop the fusion process and update the UI state. + await _mainFusionObject?.stop(); + _mainFusionObject = null; + _uiState?.running = false; } } From dc64a06698dca18aa3d9d0a5bf422a6de360edc1 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 20 Oct 2023 14:17:33 -0500 Subject: [PATCH 315/379] use proxyInfo in fusiondart --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 1f4a67084..3cc986173 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 1f4a6708484cc746db34bc36c254c29ead9a4ddb +Subproject commit 3cc9861738e94f4c24fc17f272c0bf2be49a5ee7 From 5b9ade5f156a8649b0c8155cddb5398cb83902ab Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Oct 2023 10:53:31 -0600 Subject: [PATCH 316/379] add wallet owns flag to outputv2 --- .../models/blockchain_data/v2/output_v2.dart | 21 +++++++++++++++++++ .../coins/bitcoincash/bitcoincash_wallet.dart | 10 ++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/v2/output_v2.dart b/lib/models/isar/models/blockchain_data/v2/output_v2.dart index b65dc4b23..a94c8dedb 100644 --- a/lib/models/isar/models/blockchain_data/v2/output_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/output_v2.dart @@ -9,6 +9,8 @@ class OutputV2 { late final String valueStringSats; late final List<String> addresses; + late final bool walletOwns; + @ignore BigInt get value => BigInt.parse(valueStringSats); @@ -18,14 +20,31 @@ class OutputV2 { required String scriptPubKeyHex, required String valueStringSats, required List<String> addresses, + required bool walletOwns, }) => OutputV2() ..scriptPubKeyHex = scriptPubKeyHex ..valueStringSats = valueStringSats + ..walletOwns = walletOwns ..addresses = List.unmodifiable(addresses); + OutputV2 copyWith({ + String? scriptPubKeyHex, + String? valueStringSats, + List<String>? addresses, + bool? walletOwns, + }) { + return OutputV2.isarCantDoRequiredInDefaultConstructor( + scriptPubKeyHex: scriptPubKeyHex ?? this.scriptPubKeyHex, + valueStringSats: valueStringSats ?? this.valueStringSats, + addresses: addresses ?? this.addresses, + walletOwns: walletOwns ?? this.walletOwns, + ); + } + static OutputV2 fromElectrumXJson( Map<String, dynamic> json, { + required bool walletOwns, required int decimalPlaces, }) { try { @@ -46,6 +65,7 @@ class OutputV2 { decimalPlaces: decimalPlaces, ), addresses: addresses, + walletOwns: walletOwns, ); } catch (e) { throw Exception("Failed to parse OutputV2 from $json"); @@ -84,6 +104,7 @@ class OutputV2 { @override int get hashCode => Object.hash( scriptPubKeyHex, + addresses, valueStringSats, ); diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 10bf44a49..88f59ec42 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2099,6 +2099,7 @@ class BitcoinCashWallet extends CoinServiceAPI final prevOut = OutputV2.fromElectrumXJson( prevOutJson, decimalPlaces: coin.decimals, + walletOwns: false, // doesn't matter here as this is not saved ); outpoint = OutpointV2.isarCantDoRequiredInDefaultConstructor( @@ -2136,11 +2137,10 @@ class BitcoinCashWallet extends CoinServiceAPI final output = OutputV2.fromElectrumXJson( Map<String, dynamic>.from(outputJson as Map), decimalPlaces: coin.decimals, + // don't know yet if wallet owns. Need addresses first + walletOwns: false, ); - outputs.add(output); - } - for (final output in outputs) { // if output was to my wallet, add value to amount received if (receivingAddresses .intersection(output.addresses.toSet()) @@ -2153,6 +2153,10 @@ class BitcoinCashWallet extends CoinServiceAPI wasReceivedInThisWallet = true; changeAmountReceivedInThisWallet += output.value; } + + outputs.add(wasReceivedInThisWallet + ? output.copyWith(walletOwns: true) + : output); } final totalIn = inputs From f55fd7f05a95c4dc6081c41f3be6a2254755623a Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Oct 2023 10:59:25 -0600 Subject: [PATCH 317/379] add wallet owns flag to inputv2 --- .../models/blockchain_data/v2/input_v2.dart | 30 ++++++++++++++++++- .../coins/bitcoincash/bitcoincash_wallet.dart | 9 +++--- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/v2/input_v2.dart b/lib/models/isar/models/blockchain_data/v2/input_v2.dart index 44a54ce19..f007cade8 100644 --- a/lib/models/isar/models/blockchain_data/v2/input_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/input_v2.dart @@ -54,6 +54,8 @@ class InputV2 { late final String? witness; late final String? innerRedeemScriptAsm; + late final bool walletOwns; + @ignore BigInt get value => BigInt.parse(valueStringSats); @@ -68,6 +70,7 @@ class InputV2 { required String? witness, required String? innerRedeemScriptAsm, required String? coinbase, + required bool walletOwns, }) => InputV2() ..scriptSigHex = scriptSigHex @@ -77,7 +80,32 @@ class InputV2 { ..valueStringSats = valueStringSats ..witness = witness ..innerRedeemScriptAsm = innerRedeemScriptAsm - ..coinbase = coinbase; + ..innerRedeemScriptAsm = innerRedeemScriptAsm + ..walletOwns = walletOwns; + + InputV2 copyWith({ + String? scriptSigHex, + int? sequence, + OutpointV2? outpoint, + List<String>? addresses, + String? valueStringSats, + String? coinbase, + String? witness, + String? innerRedeemScriptAsm, + bool? walletOwns, + }) { + return InputV2.isarCantDoRequiredInDefaultConstructor( + scriptSigHex: scriptSigHex ?? this.scriptSigHex, + sequence: sequence ?? this.sequence, + outpoint: outpoint ?? this.outpoint, + addresses: addresses ?? this.addresses, + valueStringSats: valueStringSats ?? this.valueStringSats, + coinbase: coinbase ?? this.coinbase, + witness: witness ?? this.witness, + innerRedeemScriptAsm: innerRedeemScriptAsm ?? this.innerRedeemScriptAsm, + walletOwns: walletOwns ?? this.walletOwns, + ); + } @override bool operator ==(Object other) { diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 88f59ec42..556ddbcdb 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2119,16 +2119,17 @@ class BitcoinCashWallet extends CoinServiceAPI witness: map["witness"] as String?, coinbase: coinbase, innerRedeemScriptAsm: map["innerRedeemscriptAsm"] as String?, + // don't know yet if wallet owns. Need addresses first + walletOwns: false, ); - inputs.add(input); - } - - for (final input in inputs) { if (allAddressesSet.intersection(input.addresses.toSet()).isNotEmpty) { wasSentFromThisWallet = true; amountSentFromThisWallet += input.value; } + + inputs.add( + wasSentFromThisWallet ? input.copyWith(walletOwns: true) : input); } // parse outputs From 33efc956e9500328a1926ead2808b74c502bfce9 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Oct 2023 11:00:29 -0600 Subject: [PATCH 318/379] clean up --- .../models/blockchain_data/v2/input_v2.dart | 18 +----------------- .../models/blockchain_data/v2/output_v2.dart | 18 +----------------- 2 files changed, 2 insertions(+), 34 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/v2/input_v2.dart b/lib/models/isar/models/blockchain_data/v2/input_v2.dart index f007cade8..7b48ff9e5 100644 --- a/lib/models/isar/models/blockchain_data/v2/input_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/input_v2.dart @@ -107,23 +107,6 @@ class InputV2 { ); } - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is InputV2 && - other.scriptSigHex == scriptSigHex && - other.sequence == sequence && - other.outpoint == outpoint; - } - - @override - int get hashCode => Object.hash( - scriptSigHex, - sequence, - outpoint, - ); - @override String toString() { return 'InputV2(\n' @@ -135,6 +118,7 @@ class InputV2 { ' coinbase: $coinbase,\n' ' witness: $witness,\n' ' innerRedeemScriptAsm: $innerRedeemScriptAsm,\n' + ' walletOwns: $walletOwns,\n' ')'; } } diff --git a/lib/models/isar/models/blockchain_data/v2/output_v2.dart b/lib/models/isar/models/blockchain_data/v2/output_v2.dart index a94c8dedb..30e24539e 100644 --- a/lib/models/isar/models/blockchain_data/v2/output_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/output_v2.dart @@ -91,28 +91,12 @@ class OutputV2 { return valueStringSats; } - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - - return other is OutputV2 && - other.scriptPubKeyHex == scriptPubKeyHex && - _listEquals(other.addresses, addresses) && - other.valueStringSats == valueStringSats; - } - - @override - int get hashCode => Object.hash( - scriptPubKeyHex, - addresses, - valueStringSats, - ); - @override String toString() { return 'OutputV2(\n' ' scriptPubKeyHex: $scriptPubKeyHex,\n' ' value: $value,\n' + ' walletOwns: $walletOwns,\n' ' addresses: $addresses,\n' ')'; } From 8cd7f3fa7f0236af6f98a0361d89ad227d52c0ba Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Oct 2023 11:41:51 -0600 Subject: [PATCH 319/379] clean up, fixes and code gen --- .../models/blockchain_data/v2/input_v2.dart | 2 +- .../models/blockchain_data/v2/input_v2.g.dart | 118 ++++++------------ .../blockchain_data/v2/output_v2.g.dart | 92 ++++---------- lib/services/mixins/electrum_x_parsing.dart | 3 + 4 files changed, 67 insertions(+), 148 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/v2/input_v2.dart b/lib/models/isar/models/blockchain_data/v2/input_v2.dart index 7b48ff9e5..66b1c5ab1 100644 --- a/lib/models/isar/models/blockchain_data/v2/input_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/input_v2.dart @@ -80,7 +80,7 @@ class InputV2 { ..valueStringSats = valueStringSats ..witness = witness ..innerRedeemScriptAsm = innerRedeemScriptAsm - ..innerRedeemScriptAsm = innerRedeemScriptAsm + ..coinbase = coinbase ..walletOwns = walletOwns; InputV2 copyWith({ diff --git a/lib/models/isar/models/blockchain_data/v2/input_v2.g.dart b/lib/models/isar/models/blockchain_data/v2/input_v2.g.dart index b18575a12..eb3bc3cd3 100644 --- a/lib/models/isar/models/blockchain_data/v2/input_v2.g.dart +++ b/lib/models/isar/models/blockchain_data/v2/input_v2.g.dart @@ -346,37 +346,37 @@ const InputV2Schema = Schema( name: r'coinbase', type: IsarType.string, ), - r'hashCode': PropertySchema( - id: 2, - name: r'hashCode', - type: IsarType.long, - ), r'innerRedeemScriptAsm': PropertySchema( - id: 3, + id: 2, name: r'innerRedeemScriptAsm', type: IsarType.string, ), r'outpoint': PropertySchema( - id: 4, + id: 3, name: r'outpoint', type: IsarType.object, target: r'OutpointV2', ), r'scriptSigHex': PropertySchema( - id: 5, + id: 4, name: r'scriptSigHex', type: IsarType.string, ), r'sequence': PropertySchema( - id: 6, + id: 5, name: r'sequence', type: IsarType.long, ), r'valueStringSats': PropertySchema( - id: 7, + id: 6, name: r'valueStringSats', type: IsarType.string, ), + r'walletOwns': PropertySchema( + id: 7, + name: r'walletOwns', + type: IsarType.bool, + ), r'witness': PropertySchema( id: 8, name: r'witness', @@ -446,17 +446,17 @@ void _inputV2Serialize( ) { writer.writeStringList(offsets[0], object.addresses); writer.writeString(offsets[1], object.coinbase); - writer.writeLong(offsets[2], object.hashCode); - writer.writeString(offsets[3], object.innerRedeemScriptAsm); + writer.writeString(offsets[2], object.innerRedeemScriptAsm); writer.writeObject<OutpointV2>( - offsets[4], + offsets[3], allOffsets, OutpointV2Schema.serialize, object.outpoint, ); - writer.writeString(offsets[5], object.scriptSigHex); - writer.writeLong(offsets[6], object.sequence); - writer.writeString(offsets[7], object.valueStringSats); + writer.writeString(offsets[4], object.scriptSigHex); + writer.writeLong(offsets[5], object.sequence); + writer.writeString(offsets[6], object.valueStringSats); + writer.writeBool(offsets[7], object.walletOwns); writer.writeString(offsets[8], object.witness); } @@ -469,15 +469,16 @@ InputV2 _inputV2Deserialize( final object = InputV2(); object.addresses = reader.readStringList(offsets[0]) ?? []; object.coinbase = reader.readStringOrNull(offsets[1]); - object.innerRedeemScriptAsm = reader.readStringOrNull(offsets[3]); + object.innerRedeemScriptAsm = reader.readStringOrNull(offsets[2]); object.outpoint = reader.readObjectOrNull<OutpointV2>( - offsets[4], + offsets[3], OutpointV2Schema.deserialize, allOffsets, ); - object.scriptSigHex = reader.readStringOrNull(offsets[5]); - object.sequence = reader.readLongOrNull(offsets[6]); - object.valueStringSats = reader.readString(offsets[7]); + object.scriptSigHex = reader.readStringOrNull(offsets[4]); + object.sequence = reader.readLongOrNull(offsets[5]); + object.valueStringSats = reader.readString(offsets[6]); + object.walletOwns = reader.readBool(offsets[7]); object.witness = reader.readStringOrNull(offsets[8]); return object; } @@ -494,21 +495,21 @@ P _inputV2DeserializeProp<P>( case 1: return (reader.readStringOrNull(offset)) as P; case 2: - return (reader.readLong(offset)) as P; - case 3: return (reader.readStringOrNull(offset)) as P; - case 4: + case 3: return (reader.readObjectOrNull<OutpointV2>( offset, OutpointV2Schema.deserialize, allOffsets, )) as P; - case 5: + case 4: return (reader.readStringOrNull(offset)) as P; - case 6: + case 5: return (reader.readLongOrNull(offset)) as P; - case 7: + case 6: return (reader.readString(offset)) as P; + case 7: + return (reader.readBool(offset)) as P; case 8: return (reader.readStringOrNull(offset)) as P; default: @@ -884,59 +885,6 @@ extension InputV2QueryFilter }); } - QueryBuilder<InputV2, InputV2, QAfterFilterCondition> hashCodeEqualTo( - int value) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.equalTo( - property: r'hashCode', - value: value, - )); - }); - } - - QueryBuilder<InputV2, InputV2, QAfterFilterCondition> hashCodeGreaterThan( - int value, { - bool include = false, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.greaterThan( - include: include, - property: r'hashCode', - value: value, - )); - }); - } - - QueryBuilder<InputV2, InputV2, QAfterFilterCondition> hashCodeLessThan( - int value, { - bool include = false, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.lessThan( - include: include, - property: r'hashCode', - value: value, - )); - }); - } - - QueryBuilder<InputV2, InputV2, QAfterFilterCondition> hashCodeBetween( - int lower, - int upper, { - bool includeLower = true, - bool includeUpper = true, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.between( - property: r'hashCode', - lower: lower, - includeLower: includeLower, - upper: upper, - includeUpper: includeUpper, - )); - }); - } - QueryBuilder<InputV2, InputV2, QAfterFilterCondition> innerRedeemScriptAsmIsNull() { return QueryBuilder.apply(this, (query) { @@ -1458,6 +1406,16 @@ extension InputV2QueryFilter }); } + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> walletOwnsEqualTo( + bool value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'walletOwns', + value: value, + )); + }); + } + QueryBuilder<InputV2, InputV2, QAfterFilterCondition> witnessIsNull() { return QueryBuilder.apply(this, (query) { return query.addFilterCondition(const FilterCondition.isNull( diff --git a/lib/models/isar/models/blockchain_data/v2/output_v2.g.dart b/lib/models/isar/models/blockchain_data/v2/output_v2.g.dart index 98cc61620..bf966d5ec 100644 --- a/lib/models/isar/models/blockchain_data/v2/output_v2.g.dart +++ b/lib/models/isar/models/blockchain_data/v2/output_v2.g.dart @@ -18,20 +18,20 @@ const OutputV2Schema = Schema( name: r'addresses', type: IsarType.stringList, ), - r'hashCode': PropertySchema( - id: 1, - name: r'hashCode', - type: IsarType.long, - ), r'scriptPubKeyHex': PropertySchema( - id: 2, + id: 1, name: r'scriptPubKeyHex', type: IsarType.string, ), r'valueStringSats': PropertySchema( - id: 3, + id: 2, name: r'valueStringSats', type: IsarType.string, + ), + r'walletOwns': PropertySchema( + id: 3, + name: r'walletOwns', + type: IsarType.bool, ) }, estimateSize: _outputV2EstimateSize, @@ -65,9 +65,9 @@ void _outputV2Serialize( Map<Type, List<int>> allOffsets, ) { writer.writeStringList(offsets[0], object.addresses); - writer.writeLong(offsets[1], object.hashCode); - writer.writeString(offsets[2], object.scriptPubKeyHex); - writer.writeString(offsets[3], object.valueStringSats); + writer.writeString(offsets[1], object.scriptPubKeyHex); + writer.writeString(offsets[2], object.valueStringSats); + writer.writeBool(offsets[3], object.walletOwns); } OutputV2 _outputV2Deserialize( @@ -78,8 +78,9 @@ OutputV2 _outputV2Deserialize( ) { final object = OutputV2(); object.addresses = reader.readStringList(offsets[0]) ?? []; - object.scriptPubKeyHex = reader.readString(offsets[2]); - object.valueStringSats = reader.readString(offsets[3]); + object.scriptPubKeyHex = reader.readString(offsets[1]); + object.valueStringSats = reader.readString(offsets[2]); + object.walletOwns = reader.readBool(offsets[3]); return object; } @@ -93,11 +94,11 @@ P _outputV2DeserializeProp<P>( case 0: return (reader.readStringList(offset) ?? []) as P; case 1: - return (reader.readLong(offset)) as P; + return (reader.readString(offset)) as P; case 2: return (reader.readString(offset)) as P; case 3: - return (reader.readString(offset)) as P; + return (reader.readBool(offset)) as P; default: throw IsarError('Unknown property with id $propertyId'); } @@ -329,59 +330,6 @@ extension OutputV2QueryFilter }); } - QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> hashCodeEqualTo( - int value) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.equalTo( - property: r'hashCode', - value: value, - )); - }); - } - - QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> hashCodeGreaterThan( - int value, { - bool include = false, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.greaterThan( - include: include, - property: r'hashCode', - value: value, - )); - }); - } - - QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> hashCodeLessThan( - int value, { - bool include = false, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.lessThan( - include: include, - property: r'hashCode', - value: value, - )); - }); - } - - QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> hashCodeBetween( - int lower, - int upper, { - bool includeLower = true, - bool includeUpper = true, - }) { - return QueryBuilder.apply(this, (query) { - return query.addFilterCondition(FilterCondition.between( - property: r'hashCode', - lower: lower, - includeLower: includeLower, - upper: upper, - includeUpper: includeUpper, - )); - }); - } - QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> scriptPubKeyHexEqualTo( String value, { @@ -653,6 +601,16 @@ extension OutputV2QueryFilter )); }); } + + QueryBuilder<OutputV2, OutputV2, QAfterFilterCondition> walletOwnsEqualTo( + bool value) { + return QueryBuilder.apply(this, (query) { + return query.addFilterCondition(FilterCondition.equalTo( + property: r'walletOwns', + value: value, + )); + }); + } } extension OutputV2QueryObject diff --git a/lib/services/mixins/electrum_x_parsing.dart b/lib/services/mixins/electrum_x_parsing.dart index 79a74e2a8..acc9c6e76 100644 --- a/lib/services/mixins/electrum_x_parsing.dart +++ b/lib/services/mixins/electrum_x_parsing.dart @@ -67,6 +67,7 @@ mixin ElectrumXParsing { final prevOut = OutputV2.fromElectrumXJson( prevOutJson, decimalPlaces: coin.decimals, + walletOwns: false, ); outpoint = OutpointV2.isarCantDoRequiredInDefaultConstructor( @@ -86,6 +87,7 @@ mixin ElectrumXParsing { witness: map["witness"] as String?, coinbase: coinbase, innerRedeemScriptAsm: map["innerRedeemscriptAsm"] as String?, + walletOwns: false, ); inputs.add(input); @@ -97,6 +99,7 @@ mixin ElectrumXParsing { final output = OutputV2.fromElectrumXJson( Map<String, dynamic>.from(outputJson as Map), decimalPlaces: coin.decimals, + walletOwns: false, ); outputs.add(output); } From 6e258db3443d7bb600f27d983b483e63fdf1dadc Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Oct 2023 12:20:09 -0600 Subject: [PATCH 320/379] fix tx amounts shown --- .../blockchain_data/v2/transaction_v2.dart | 14 ++++++++--- .../sub_widgets/transaction_v2_list.dart | 24 +++++++++++++++++-- .../coins/bitcoincash/bitcoincash_wallet.dart | 14 +++++------ 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart index cebc5d5d9..e03b777ae 100644 --- a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart @@ -71,14 +71,22 @@ class TransactionV2 { return Amount(rawValue: inSum - outSum, fractionDigits: coin.decimals); } - Amount getAmount({required Coin coin}) { + Amount getAmountReceivedThisWallet({required Coin coin}) { final outSum = outputs - .map((e) => e.value) - .reduce((value, element) => value += element); + .where((e) => e.walletOwns) + .fold(BigInt.zero, (p, e) => p + e.value); return Amount(rawValue: outSum, fractionDigits: coin.decimals); } + Amount getAmountSentFromThisWallet({required Coin coin}) { + final inSum = inputs + .where((e) => e.walletOwns) + .fold(BigInt.zero, (p, e) => p + e.value); + + return Amount(rawValue: inSum, fractionDigits: coin.decimals); + } + @override String toString() { return 'TransactionV2(\n' diff --git a/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart b/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart index 15ec84b31..264da6204 100644 --- a/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart +++ b/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart @@ -411,7 +411,8 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> { walletId = _transaction.walletId; if (Util.isDesktop) { - if (_transaction.type == TransactionType.outgoing) { + if (_transaction.type == TransactionType.outgoing && + _transaction.subType != TransactionSubType.cashFusion) { prefix = "-"; } else if (_transaction.type == TransactionType.incoming) { prefix = "+"; @@ -443,7 +444,26 @@ class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> { final currentHeight = ref.watch(walletsChangeNotifierProvider .select((value) => value.getManager(walletId).currentHeight)); - final amount = _transaction.getAmount(coin: coin); + final Amount amount; + + if (_transaction.subType == TransactionSubType.cashFusion) { + amount = _transaction.getAmountReceivedThisWallet(coin: coin); + } else { + switch (_transaction.type) { + case TransactionType.outgoing: + amount = _transaction.getAmountSentFromThisWallet(coin: coin); + break; + + case TransactionType.incoming: + case TransactionType.sentToSelf: + amount = _transaction.getAmountReceivedThisWallet(coin: coin); + break; + + case TransactionType.unknown: + amount = _transaction.getAmountSentFromThisWallet(coin: coin); + break; + } + } return Material( color: Theme.of(context).extension<StackColors>()!.popupBG, diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 556ddbcdb..6c246aae3 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2110,7 +2110,7 @@ class BitcoinCashWallet extends CoinServiceAPI addresses.addAll(prevOut.addresses); } - final input = InputV2.isarCantDoRequiredInDefaultConstructor( + InputV2 input = InputV2.isarCantDoRequiredInDefaultConstructor( scriptSigHex: map["scriptSig"]?["hex"] as String?, sequence: map["sequence"] as int?, outpoint: outpoint, @@ -2126,16 +2126,16 @@ class BitcoinCashWallet extends CoinServiceAPI if (allAddressesSet.intersection(input.addresses.toSet()).isNotEmpty) { wasSentFromThisWallet = true; amountSentFromThisWallet += input.value; + input = input.copyWith(walletOwns: true); } - inputs.add( - wasSentFromThisWallet ? input.copyWith(walletOwns: true) : input); + inputs.add(input); } // parse outputs final List<OutputV2> outputs = []; for (final outputJson in txData["vout"] as List) { - final output = OutputV2.fromElectrumXJson( + OutputV2 output = OutputV2.fromElectrumXJson( Map<String, dynamic>.from(outputJson as Map), decimalPlaces: coin.decimals, // don't know yet if wallet owns. Need addresses first @@ -2148,16 +2148,16 @@ class BitcoinCashWallet extends CoinServiceAPI .isNotEmpty) { wasReceivedInThisWallet = true; amountReceivedInThisWallet += output.value; + output = output.copyWith(walletOwns: true); } else if (changeAddresses .intersection(output.addresses.toSet()) .isNotEmpty) { wasReceivedInThisWallet = true; changeAmountReceivedInThisWallet += output.value; + output = output.copyWith(walletOwns: true); } - outputs.add(wasReceivedInThisWallet - ? output.copyWith(walletOwns: true) - : output); + outputs.add(output); } final totalIn = inputs From 66952789579baf4a9345edf747e56f8aa3b83397 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Oct 2023 12:28:53 -0600 Subject: [PATCH 321/379] print error --- lib/electrumx_rpc/electrumx.dart | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/electrumx_rpc/electrumx.dart b/lib/electrumx_rpc/electrumx.dart index 88c49cc45..eea9bed0b 100644 --- a/lib/electrumx_rpc/electrumx.dart +++ b/lib/electrumx_rpc/electrumx.dart @@ -387,7 +387,14 @@ class ElectrumX { throw jsonRpcResponse.exception!; } - final response = jsonRpcResponse.data as List; + final List<dynamic> response; + try { + response = jsonRpcResponse.data as List; + } catch (_) { + throw Exception( + "Expected json list but got a map: ${jsonRpcResponse.data}", + ); + } // check for errors, format and throw if there are any final List<String> errors = []; From 0f1c1d21ad13d75cadf9a251540fe8d9260dee8d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Oct 2023 13:37:16 -0600 Subject: [PATCH 322/379] fix onchain note copy button bug --- .../wallet_view/transaction_views/transaction_details_view.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart index 54b528245..d1af131a5 100644 --- a/lib/pages/wallet_view/transaction_views/transaction_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/transaction_details_view.dart @@ -831,7 +831,7 @@ class _TransactionDetailsViewState ), if (isDesktop) IconCopyButton( - data: _transaction.address.value!.value, + data: _transaction.otherData ?? "", ), ], ), From 80614598323d5f7456cfb2780406b5d2d933e42d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Oct 2023 14:19:40 -0600 Subject: [PATCH 323/379] WIP tx details for v2 txns --- .../sub_widgets/transaction_v2_list.dart | 614 ------- .../tx_v2/transaction_v2_card.dart | 287 +++ .../tx_v2/transaction_v2_details_item.dart | 98 + .../tx_v2/transaction_v2_details_view.dart | 1572 +++++++++++++++++ .../tx_v2/transaction_v2_list.dart | 189 ++ .../tx_v2/transaction_v2_list_item.dart | 160 ++ .../wallet_view/desktop_wallet_view.dart | 2 +- lib/route_generator.dart | 18 + 8 files changed, 2325 insertions(+), 615 deletions(-) delete mode 100644 lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart create mode 100644 lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart create mode 100644 lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_item.dart create mode 100644 lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart create mode 100644 lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart create mode 100644 lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart diff --git a/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart b/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart deleted file mode 100644 index 264da6204..000000000 --- a/lib/pages/wallet_view/sub_widgets/transaction_v2_list.dart +++ /dev/null @@ -1,614 +0,0 @@ -/* - * This file is part of Stack Wallet. - * - * Copyright (c) 2023 Cypher Stack - * All Rights Reserved. - * The code is distributed under GPLv3 license, see LICENSE file for details. - * Generated by Cypher Stack on 2023-10-19 - * - */ - -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:isar/isar.dart'; -import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; -import 'package:stackwallet/models/isar/models/isar_models.dart'; -import 'package:stackwallet/pages/exchange_view/trade_details_view.dart'; -import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart'; -import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; -import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart'; -import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; -import 'package:stackwallet/providers/db/main_db_provider.dart'; -import 'package:stackwallet/providers/global/locale_provider.dart'; -import 'package:stackwallet/providers/global/prefs_provider.dart'; -import 'package:stackwallet/providers/global/price_provider.dart'; -import 'package:stackwallet/providers/global/trades_service_provider.dart'; -import 'package:stackwallet/providers/global/wallets_provider.dart'; -import 'package:stackwallet/route_generator.dart'; -import 'package:stackwallet/themes/stack_colors.dart'; -import 'package:stackwallet/utilities/amount/amount.dart'; -import 'package:stackwallet/utilities/amount/amount_formatter.dart'; -import 'package:stackwallet/utilities/constants.dart'; -import 'package:stackwallet/utilities/enums/coin_enum.dart'; -import 'package:stackwallet/utilities/format.dart'; -import 'package:stackwallet/utilities/text_styles.dart'; -import 'package:stackwallet/utilities/util.dart'; -import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; -import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; -import 'package:stackwallet/widgets/loading_indicator.dart'; -import 'package:stackwallet/widgets/trade_card.dart'; -import 'package:tuple/tuple.dart'; - -class TransactionsV2List extends ConsumerStatefulWidget { - const TransactionsV2List({ - Key? key, - required this.walletId, - }) : super(key: key); - - final String walletId; - - @override - ConsumerState<TransactionsV2List> createState() => _TransactionsV2ListState(); -} - -class _TxListItem extends ConsumerWidget { - const _TxListItem({ - super.key, - required this.tx, - this.radius, - required this.coin, - }); - - final TransactionV2 tx; - final BorderRadius? radius; - final Coin coin; - - @override - Widget build(BuildContext context, WidgetRef ref) { - final matchingTrades = ref - .read(tradesServiceProvider) - .trades - .where((e) => e.payInTxid == tx.txid || e.payOutTxid == tx.txid); - - if (tx.type == TransactionType.outgoing && matchingTrades.isNotEmpty) { - final trade = matchingTrades.first; - return Container( - decoration: BoxDecoration( - color: Theme.of(context).extension<StackColors>()!.popupBG, - borderRadius: radius, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - TransactionCardV2( - key: UniqueKey(), - transaction: tx, - ), - TradeCard( - key: Key(tx.txid + - tx.type.name + - tx.hashCode.toString() + - trade.uuid), // - trade: trade, - onTap: () async { - if (Util.isDesktop) { - await showDialog<void>( - context: context, - builder: (context) => Navigator( - initialRoute: TradeDetailsView.routeName, - onGenerateRoute: RouteGenerator.generateRoute, - onGenerateInitialRoutes: (_, __) { - return [ - FadePageRoute( - DesktopDialog( - maxHeight: null, - maxWidth: 580, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.only( - left: 32, - bottom: 16, - ), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Text( - "Trade details", - style: STextStyles.desktopH3(context), - ), - DesktopDialogCloseButton( - onPressedOverride: Navigator.of( - context, - rootNavigator: true, - ).pop, - ), - ], - ), - ), - Flexible( - child: TradeDetailsView( - tradeId: trade.tradeId, - // TODO - // transactionIfSentFromStack: tx, - transactionIfSentFromStack: null, - walletName: ref.watch( - walletsChangeNotifierProvider.select( - (value) => value - .getManager(tx.walletId) - .walletName, - ), - ), - walletId: tx.walletId, - ), - ), - ], - ), - ), - const RouteSettings( - name: TradeDetailsView.routeName, - ), - ), - ]; - }, - ), - ); - } else { - unawaited( - Navigator.of(context).pushNamed( - TradeDetailsView.routeName, - arguments: Tuple4( - trade.tradeId, - tx, - tx.walletId, - ref - .read(walletsChangeNotifierProvider) - .getManager(tx.walletId) - .walletName, - ), - ), - ); - } - }, - ) - ], - ), - ); - } else { - return Container( - decoration: BoxDecoration( - color: Theme.of(context).extension<StackColors>()!.popupBG, - borderRadius: radius, - ), - child: TransactionCardV2( - // this may mess with combined firo transactions - key: UniqueKey(), - transaction: tx, - ), - ); - } - } -} - -class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> { - bool _hasLoaded = false; - List<TransactionV2> _transactions = []; - - BorderRadius get _borderRadiusFirst { - return BorderRadius.only( - topLeft: Radius.circular( - Constants.size.circularBorderRadius, - ), - topRight: Radius.circular( - Constants.size.circularBorderRadius, - ), - ); - } - - BorderRadius get _borderRadiusLast { - return BorderRadius.only( - bottomLeft: Radius.circular( - Constants.size.circularBorderRadius, - ), - bottomRight: Radius.circular( - Constants.size.circularBorderRadius, - ), - ); - } - - @override - Widget build(BuildContext context) { - final manager = ref.watch(walletsChangeNotifierProvider - .select((value) => value.getManager(widget.walletId))); - - return FutureBuilder( - future: ref - .watch(mainDBProvider) - .isar - .transactionV2s - .where() - .walletIdEqualTo(widget.walletId) - .sortByTimestampDesc() - .findAll(), - builder: (fbContext, AsyncSnapshot<List<TransactionV2>> snapshot) { - if (snapshot.connectionState == ConnectionState.done && - snapshot.hasData) { - _transactions = snapshot.data!; - _hasLoaded = true; - } - if (!_hasLoaded) { - return const Column( - children: [ - Spacer(), - Center( - child: LoadingIndicator( - height: 50, - width: 50, - ), - ), - Spacer( - flex: 4, - ), - ], - ); - } - if (_transactions.isEmpty) { - return const NoTransActionsFound(); - } else { - _transactions.sort((a, b) => b.timestamp - a.timestamp); - return RefreshIndicator( - onRefresh: () async { - final managerProvider = ref - .read(walletsChangeNotifierProvider) - .getManagerProvider(widget.walletId); - if (!ref.read(managerProvider).isRefreshing) { - unawaited(ref.read(managerProvider).refresh()); - } - }, - child: Util.isDesktop - ? ListView.separated( - shrinkWrap: true, - itemBuilder: (context, index) { - BorderRadius? radius; - if (_transactions.length == 1) { - radius = BorderRadius.circular( - Constants.size.circularBorderRadius, - ); - } else if (index == _transactions.length - 1) { - radius = _borderRadiusLast; - } else if (index == 0) { - radius = _borderRadiusFirst; - } - final tx = _transactions[index]; - return _TxListItem( - tx: tx, - coin: manager.coin, - radius: radius, - ); - }, - separatorBuilder: (context, index) { - return Container( - width: double.infinity, - height: 2, - color: Theme.of(context) - .extension<StackColors>()! - .background, - ); - }, - itemCount: _transactions.length, - ) - : ListView.builder( - itemCount: _transactions.length, - itemBuilder: (context, index) { - BorderRadius? radius; - bool shouldWrap = false; - if (_transactions.length == 1) { - radius = BorderRadius.circular( - Constants.size.circularBorderRadius, - ); - } else if (index == _transactions.length - 1) { - radius = _borderRadiusLast; - shouldWrap = true; - } else if (index == 0) { - radius = _borderRadiusFirst; - } - final tx = _transactions[index]; - if (shouldWrap) { - return Column( - children: [ - _TxListItem( - tx: tx, - coin: manager.coin, - radius: radius, - ), - const SizedBox( - height: WalletView.navBarHeight + 14, - ), - ], - ); - } else { - return _TxListItem( - tx: tx, - coin: manager.coin, - radius: radius, - ); - } - }, - ), - ); - } - }, - ); - } -} - -class TransactionCardV2 extends ConsumerStatefulWidget { - const TransactionCardV2({ - Key? key, - required this.transaction, - }) : super(key: key); - - final TransactionV2 transaction; - - @override - ConsumerState<TransactionCardV2> createState() => _TransactionCardStateV2(); -} - -class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> { - late final TransactionV2 _transaction; - late final String walletId; - late final String prefix; - late final String unit; - late final Coin coin; - late final TransactionType txType; - - String whatIsIt( - Coin coin, - int currentHeight, - ) { - final confirmedStatus = _transaction.isConfirmed( - currentHeight, - coin.requiredConfirmations, - ); - - if (_transaction.subType == TransactionSubType.cashFusion) { - if (confirmedStatus) { - return "Anonymized"; - } else { - return "Anonymizing"; - } - } - - if (_transaction.type == TransactionType.incoming) { - // if (_transaction.isMinting) { - // return "Minting"; - // } else - if (confirmedStatus) { - return "Received"; - } else { - return "Receiving"; - } - } else if (_transaction.type == TransactionType.outgoing) { - if (confirmedStatus) { - return "Sent"; - } else { - return "Sending"; - } - } else if (_transaction.type == TransactionType.sentToSelf) { - return "Sent to self"; - } else { - return _transaction.type.name; - } - } - - @override - void initState() { - _transaction = widget.transaction; - walletId = _transaction.walletId; - - if (Util.isDesktop) { - if (_transaction.type == TransactionType.outgoing && - _transaction.subType != TransactionSubType.cashFusion) { - prefix = "-"; - } else if (_transaction.type == TransactionType.incoming) { - prefix = "+"; - } else { - prefix = ""; - } - } else { - prefix = ""; - } - coin = ref.read(walletsChangeNotifierProvider).getManager(walletId).coin; - - unit = coin.ticker; - super.initState(); - } - - @override - Widget build(BuildContext context) { - final locale = ref.watch( - localeServiceChangeNotifierProvider.select((value) => value.locale)); - - final baseCurrency = ref - .watch(prefsChangeNotifierProvider.select((value) => value.currency)); - - final price = ref - .watch(priceAnd24hChangeNotifierProvider - .select((value) => value.getPrice(coin))) - .item1; - - final currentHeight = ref.watch(walletsChangeNotifierProvider - .select((value) => value.getManager(walletId).currentHeight)); - - final Amount amount; - - if (_transaction.subType == TransactionSubType.cashFusion) { - amount = _transaction.getAmountReceivedThisWallet(coin: coin); - } else { - switch (_transaction.type) { - case TransactionType.outgoing: - amount = _transaction.getAmountSentFromThisWallet(coin: coin); - break; - - case TransactionType.incoming: - case TransactionType.sentToSelf: - amount = _transaction.getAmountReceivedThisWallet(coin: coin); - break; - - case TransactionType.unknown: - amount = _transaction.getAmountSentFromThisWallet(coin: coin); - break; - } - } - - return Material( - color: Theme.of(context).extension<StackColors>()!.popupBG, - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(Constants.size.circularBorderRadius), - ), - child: Padding( - padding: const EdgeInsets.all(6), - child: RawMaterialButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - ), - onPressed: () async { - if (Util.isDesktop) { - // TODO - // await showDialog<void>( - // context: context, - // builder: (context) => DesktopDialog( - // maxHeight: MediaQuery.of(context).size.height - 64, - // maxWidth: 580, - // child: TransactionDetailsView( - // transaction: _transaction, - // coin: coin, - // walletId: walletId, - // ), - // ), - // ); - } else { - unawaited( - Navigator.of(context).pushNamed( - TransactionDetailsView.routeName, - arguments: Tuple3( - _transaction, - coin, - walletId, - ), - ), - ); - } - }, - child: Padding( - padding: const EdgeInsets.all(8), - child: Row( - children: [ - TxIcon( - transaction: _transaction, - coin: coin, - currentHeight: currentHeight, - ), - const SizedBox( - width: 14, - ), - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - // crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: FittedBox( - fit: BoxFit.scaleDown, - child: Text( - whatIsIt( - coin, - currentHeight, - ), - style: STextStyles.itemSubtitle12(context), - ), - ), - ), - const SizedBox( - width: 10, - ), - Flexible( - child: FittedBox( - fit: BoxFit.scaleDown, - child: Builder( - builder: (_) { - return Text( - "$prefix${ref.watch(pAmountFormatter(coin)).format(amount)}", - style: STextStyles.itemSubtitle12(context), - ); - }, - ), - ), - ), - ], - ), - const SizedBox( - height: 4, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - // crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Flexible( - child: FittedBox( - fit: BoxFit.scaleDown, - child: Text( - Format.extractDateFrom(_transaction.timestamp), - style: STextStyles.label(context), - ), - ), - ), - if (ref.watch(prefsChangeNotifierProvider - .select((value) => value.externalCalls))) - const SizedBox( - width: 10, - ), - if (ref.watch(prefsChangeNotifierProvider - .select((value) => value.externalCalls))) - Flexible( - child: FittedBox( - fit: BoxFit.scaleDown, - child: Builder( - builder: (_) { - return Text( - "$prefix${Amount.fromDecimal( - amount.decimal * price, - fractionDigits: 2, - ).fiatString( - locale: locale, - )} $baseCurrency", - style: STextStyles.label(context), - ); - }, - ), - ), - ), - ], - ), - ], - ), - ), - ], - ), - ), - ), - ), - ); - } -} diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart new file mode 100644 index 000000000..c8162fbb1 --- /dev/null +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart @@ -0,0 +1,287 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart'; +import 'package:stackwallet/providers/global/locale_provider.dart'; +import 'package:stackwallet/providers/global/prefs_provider.dart'; +import 'package:stackwallet/providers/global/price_provider.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; +import 'package:stackwallet/utilities/amount/amount_formatter.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/format.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; + +class TransactionCardV2 extends ConsumerStatefulWidget { + const TransactionCardV2({ + Key? key, + required this.transaction, + }) : super(key: key); + + final TransactionV2 transaction; + + @override + ConsumerState<TransactionCardV2> createState() => _TransactionCardStateV2(); +} + +class _TransactionCardStateV2 extends ConsumerState<TransactionCardV2> { + late final TransactionV2 _transaction; + late final String walletId; + late final String prefix; + late final String unit; + late final Coin coin; + late final TransactionType txType; + + String whatIsIt( + Coin coin, + int currentHeight, + ) { + final confirmedStatus = _transaction.isConfirmed( + currentHeight, + coin.requiredConfirmations, + ); + + if (_transaction.subType == TransactionSubType.cashFusion) { + if (confirmedStatus) { + return "Anonymized"; + } else { + return "Anonymizing"; + } + } + + if (_transaction.type == TransactionType.incoming) { + // if (_transaction.isMinting) { + // return "Minting"; + // } else + if (confirmedStatus) { + return "Received"; + } else { + return "Receiving"; + } + } else if (_transaction.type == TransactionType.outgoing) { + if (confirmedStatus) { + return "Sent"; + } else { + return "Sending"; + } + } else if (_transaction.type == TransactionType.sentToSelf) { + return "Sent to self"; + } else { + return _transaction.type.name; + } + } + + @override + void initState() { + _transaction = widget.transaction; + walletId = _transaction.walletId; + + if (Util.isDesktop) { + if (_transaction.type == TransactionType.outgoing && + _transaction.subType != TransactionSubType.cashFusion) { + prefix = "-"; + } else if (_transaction.type == TransactionType.incoming) { + prefix = "+"; + } else { + prefix = ""; + } + } else { + prefix = ""; + } + coin = ref.read(walletsChangeNotifierProvider).getManager(walletId).coin; + + unit = coin.ticker; + super.initState(); + } + + @override + Widget build(BuildContext context) { + final locale = ref.watch( + localeServiceChangeNotifierProvider.select((value) => value.locale)); + + final baseCurrency = ref + .watch(prefsChangeNotifierProvider.select((value) => value.currency)); + + final price = ref + .watch(priceAnd24hChangeNotifierProvider + .select((value) => value.getPrice(coin))) + .item1; + + final currentHeight = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).currentHeight)); + + final Amount amount; + + if (_transaction.subType == TransactionSubType.cashFusion) { + amount = _transaction.getAmountReceivedThisWallet(coin: coin); + } else { + switch (_transaction.type) { + case TransactionType.outgoing: + amount = _transaction.getAmountSentFromThisWallet(coin: coin); + break; + + case TransactionType.incoming: + case TransactionType.sentToSelf: + amount = _transaction.getAmountReceivedThisWallet(coin: coin); + break; + + case TransactionType.unknown: + amount = _transaction.getAmountSentFromThisWallet(coin: coin); + break; + } + } + + return Material( + color: Theme.of(context).extension<StackColors>()!.popupBG, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(Constants.size.circularBorderRadius), + ), + child: Padding( + padding: const EdgeInsets.all(6), + child: RawMaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + onPressed: () async { + if (Util.isDesktop) { + await showDialog<void>( + context: context, + builder: (context) => DesktopDialog( + maxHeight: MediaQuery.of(context).size.height - 64, + maxWidth: 580, + child: TransactionV2DetailsView( + transaction: _transaction, + coin: coin, + walletId: walletId, + ), + ), + ); + } else { + unawaited( + Navigator.of(context).pushNamed( + TransactionV2DetailsView.routeName, + arguments: ( + tx: _transaction, + coin: coin, + walletId: walletId, + ), + ), + ); + } + }, + child: Padding( + padding: const EdgeInsets.all(8), + child: Row( + children: [ + TxIcon( + transaction: _transaction, + coin: coin, + currentHeight: currentHeight, + ), + const SizedBox( + width: 14, + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + // crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + whatIsIt( + coin, + currentHeight, + ), + style: STextStyles.itemSubtitle12(context), + ), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Builder( + builder: (_) { + return Text( + "$prefix${ref.watch(pAmountFormatter(coin)).format(amount)}", + style: STextStyles.itemSubtitle12(context), + ); + }, + ), + ), + ), + ], + ), + const SizedBox( + height: 4, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + // crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + Format.extractDateFrom(_transaction.timestamp), + style: STextStyles.label(context), + ), + ), + ), + if (ref.watch(prefsChangeNotifierProvider + .select((value) => value.externalCalls))) + const SizedBox( + width: 10, + ), + if (ref.watch(prefsChangeNotifierProvider + .select((value) => value.externalCalls))) + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Builder( + builder: (_) { + return Text( + "$prefix${Amount.fromDecimal( + amount.decimal * price, + fractionDigits: 2, + ).fiatString( + locale: locale, + )} $baseCurrency", + style: STextStyles.label(context), + ); + }, + ), + ), + ), + ], + ), + ], + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_item.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_item.dart new file mode 100644 index 000000000..242b85408 --- /dev/null +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_item.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +// import 'package:stackwallet/themes/stack_colors.dart'; +// import 'package:stackwallet/utilities/text_styles.dart'; +// import 'package:stackwallet/utilities/util.dart'; +// import 'package:stackwallet/widgets/rounded_white_container.dart'; + +// class TransactionV2DetailsItem extends StatelessWidget { +// const TransactionV2DetailsItem({ +// super.key, +// required this.label, +// required this.data, +// required this.infoOrientation, +// this.topRight, +// this.bottomLeft, +// }); +// +// final String label; +// final String data; +// final Axis infoOrientation; +// final bool showLabelBelowData; +// +// final Widget? topRight; +// final Widget? bottomLeft; +// +// @override +// Widget build(BuildContext context) { +// final isDesktop = Util.isDesktop; +// +// return RoundedWhiteContainer( +// padding: isDesktop ? const EdgeInsets.all(16) : const EdgeInsets.all(12), +// child: CommonChildren( +// buildIndex: infoOrientation == Axis.vertical ? 0 : 1, +// builders: [ +// (children) => Column( +// children: children, +// ), +// (children) => Row( +// children: children, +// ), +// ], +// children: [ +// Text( +// label, +// style: isDesktop +// ? STextStyles.desktopTextExtraExtraSmall(context) +// : STextStyles.itemSubtitle(context), +// ), +// const SizedBox(height: 8,), +// SelectableText( +// data, +// style: isDesktop +// ? STextStyles.desktopTextExtraExtraSmall(context).copyWith( +// color: Theme.of(context).extension<StackColors>()!.textDark, +// ) +// : STextStyles.itemSubtitle12(context), +// ), +// +// ], +// ), +// ); +// } +// } + +class CommonChild extends StatelessWidget { + const CommonChild({ + super.key, + required this.builders, + required this.buildIndex, + required this.child, + }); + + final Widget child; + final int buildIndex; + final List<Widget Function(Widget)> builders; + + @override + Widget build(BuildContext context) { + return builders[buildIndex](child); + } +} + +class CommonChildren extends StatelessWidget { + const CommonChildren({ + super.key, + required this.builders, + required this.buildIndex, + required this.children, + }); + + final List<Widget> children; + final int buildIndex; + final List<Widget Function(List<Widget>)> builders; + + @override + Widget build(BuildContext context) { + return builders[buildIndex](children); + } +} diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart new file mode 100644 index 000000000..f87349875 --- /dev/null +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart @@ -0,0 +1,1572 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by Cypher Stack on 2023-05-26 + * + */ + +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; +import 'package:stackwallet/notifications/show_flush_bar.dart'; +import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.dart'; +import 'package:stackwallet/providers/global/address_book_service_provider.dart'; +import 'package:stackwallet/providers/providers.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; +import 'package:stackwallet/utilities/amount/amount_formatter.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/block_explorers.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/format.dart'; +import 'package:stackwallet/utilities/logger.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/background.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/icon_widgets/copy_icon.dart'; +import 'package:stackwallet/widgets/icon_widgets/pencil_icon.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:stackwallet/widgets/stack_dialog.dart'; +import 'package:tuple/tuple.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class TransactionV2DetailsView extends ConsumerStatefulWidget { + const TransactionV2DetailsView({ + Key? key, + required this.transaction, + required this.walletId, + required this.coin, + }) : super(key: key); + + static const String routeName = "/transactionV2Details"; + + final TransactionV2 transaction; + final String walletId; + final Coin coin; + + @override + ConsumerState<TransactionV2DetailsView> createState() => + _TransactionV2DetailsViewState(); +} + +class _TransactionV2DetailsViewState + extends ConsumerState<TransactionV2DetailsView> { + late final bool isDesktop; + late TransactionV2 _transaction; + late final String walletId; + + late final Coin coin; + late final Amount amount; + late final Amount fee; + late final String amountPrefix; + late final String unit; + + late final List<({List<String> addresses, Amount amount})> data; + + bool showFeePending = false; + + @override + void initState() { + isDesktop = Util.isDesktop; + _transaction = widget.transaction; + walletId = widget.walletId; + + coin = widget.coin; + + fee = _transaction.getFee(coin: coin); + + if (_transaction.subType == TransactionSubType.cashFusion || + _transaction.type == TransactionType.sentToSelf) { + amountPrefix = ""; + } else { + amountPrefix = _transaction.type == TransactionType.outgoing ? "-" : "+"; + } + + unit = coin.ticker; + + if (_transaction.subType == TransactionSubType.cashFusion) { + amount = _transaction.getAmountReceivedThisWallet(coin: coin); + data = _transaction.outputs + .where((e) => e.walletOwns) + .map((e) => ( + addresses: e.addresses, + amount: Amount(rawValue: e.value, fractionDigits: coin.decimals) + )) + .toList(); + } else { + switch (_transaction.type) { + case TransactionType.outgoing: + amount = _transaction.getAmountSentFromThisWallet(coin: coin); + data = _transaction.outputs + .where((e) => !e.walletOwns) + .map((e) => ( + addresses: e.addresses, + amount: + Amount(rawValue: e.value, fractionDigits: coin.decimals) + )) + .toList(); + break; + + case TransactionType.incoming: + case TransactionType.sentToSelf: + amount = _transaction.getAmountReceivedThisWallet(coin: coin); + data = _transaction.outputs + .where((e) => e.walletOwns) + .map((e) => ( + addresses: e.addresses, + amount: + Amount(rawValue: e.value, fractionDigits: coin.decimals) + )) + .toList(); + break; + + case TransactionType.unknown: + amount = _transaction.getAmountSentFromThisWallet(coin: coin); + data = _transaction.inputs + .where((e) => e.walletOwns) + .map((e) => ( + addresses: e.addresses, + amount: + Amount(rawValue: e.value, fractionDigits: coin.decimals) + )) + .toList(); + break; + } + } + + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + String whatIsIt(TransactionV2 tx, int height) { + final type = tx.type; + if (coin == Coin.firo || coin == Coin.firoTestNet) { + if (tx.subType == TransactionSubType.mint) { + if (tx.isConfirmed(height, coin.requiredConfirmations)) { + return "Minted"; + } else { + return "Minting"; + } + } + } + + // if (coin == Coin.epicCash) { + // if (_transaction.isCancelled) { + // return "Cancelled"; + // } else if (type == TransactionType.incoming) { + // if (tx.isConfirmed(height, coin.requiredConfirmations)) { + // return "Received"; + // } else { + // if (_transaction.numberOfMessages == 1) { + // return "Receiving (waiting for sender)"; + // } else if ((_transaction.numberOfMessages ?? 0) > 1) { + // return "Receiving (waiting for confirmations)"; // TODO test if the sender still has to open again after the receiver has 2 messages present, ie. sender->receiver->sender->node (yes) vs. sender->receiver->node (no) + // } else { + // return "Receiving"; + // } + // } + // } else if (type == TransactionType.outgoing) { + // if (tx.isConfirmed(height, coin.requiredConfirmations)) { + // return "Sent (confirmed)"; + // } else { + // if (_transaction.numberOfMessages == 1) { + // return "Sending (waiting for receiver)"; + // } else if ((_transaction.numberOfMessages ?? 0) > 1) { + // return "Sending (waiting for confirmations)"; + // } else { + // return "Sending"; + // } + // } + // } + // } + + if (tx.subType == TransactionSubType.cashFusion) { + if (tx.isConfirmed(height, coin.requiredConfirmations)) { + return "Anonymized"; + } else { + return "Anonymizing"; + } + } + + if (type == TransactionType.incoming) { + // if (_transaction.isMinting) { + // return "Minting"; + // } else + if (tx.isConfirmed(height, coin.requiredConfirmations)) { + return "Received"; + } else { + return "Receiving"; + } + } else if (type == TransactionType.outgoing) { + if (tx.isConfirmed(height, coin.requiredConfirmations)) { + return "Sent"; + } else { + return "Sending"; + } + } else if (type == TransactionType.sentToSelf) { + return "Sent to self"; + } else { + return type.name; + } + } + + Future<String> fetchContactNameFor(String address) async { + if (address.isEmpty) { + return address; + } + try { + final contacts = ref.read(addressBookServiceProvider).contacts.where( + (element) => element.addresses + .where((element) => element.address == address) + .isNotEmpty); + if (contacts.isNotEmpty) { + return contacts.first.name; + } else { + return address; + } + } catch (e, s) { + Logging.instance.log("$e\n$s", level: LogLevel.Warning); + return address; + } + } + + String _note = ""; + + Future<bool> showExplorerWarning(String explorer) async { + final bool? shouldContinue = await showDialog<bool>( + context: context, + barrierDismissible: false, + builder: (_) { + if (!isDesktop) { + return StackDialog( + title: "Attention", + message: + "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.", + icon: Row( + children: [ + Consumer(builder: (_, ref, __) { + return Checkbox( + value: ref.watch(prefsChangeNotifierProvider + .select((value) => value.hideBlockExplorerWarning)), + onChanged: (value) { + if (value is bool) { + ref + .read(prefsChangeNotifierProvider) + .hideBlockExplorerWarning = value; + setState(() {}); + } + }, + ); + }), + Text( + "Never show again", + style: STextStyles.smallMed14(context), + ) + ], + ), + leftButton: TextButton( + onPressed: () { + Navigator.of(context).pop(false); + }, + child: Text( + "Cancel", + style: STextStyles.button(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .accentColorDark), + ), + ), + rightButton: TextButton( + style: Theme.of(context) + .extension<StackColors>()! + .getPrimaryEnabledButtonStyle(context), + onPressed: () { + Navigator.of(context).pop(true); + }, + child: Text( + "Continue", + style: STextStyles.button(context), + ), + ), + ); + } else { + return DesktopDialog( + maxWidth: 550, + maxHeight: 300, + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 32, vertical: 20), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Attention", + style: STextStyles.desktopH2(context), + ), + Row( + children: [ + Consumer(builder: (_, ref, __) { + return Checkbox( + value: ref.watch(prefsChangeNotifierProvider + .select((value) => + value.hideBlockExplorerWarning)), + onChanged: (value) { + if (value is bool) { + ref + .read(prefsChangeNotifierProvider) + .hideBlockExplorerWarning = value; + setState(() {}); + } + }, + ); + }), + Text( + "Never show again", + style: STextStyles.smallMed14(context), + ) + ], + ), + ], + ), + const SizedBox(height: 16), + Text( + "You are about to view this transaction in a block explorer. The explorer may log your IP address and link it to the transaction. Only proceed if you trust $explorer.", + style: STextStyles.desktopTextSmall(context), + ), + const SizedBox(height: 35), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SecondaryButton( + width: 200, + buttonHeight: ButtonHeight.l, + label: "Cancel", + onPressed: () { + Navigator.of( + context, + rootNavigator: true, + ).pop(false); + }, + ), + const SizedBox(width: 20), + PrimaryButton( + width: 200, + buttonHeight: ButtonHeight.l, + label: "Continue", + onPressed: () { + Navigator.of( + context, + rootNavigator: true, + ).pop(true); + }, + ), + ], + ), + ], + ), + ), + ); + } + }); + return shouldContinue ?? false; + } + + @override + Widget build(BuildContext context) { + final currentHeight = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).currentHeight)); + + return ConditionalParent( + condition: !isDesktop, + builder: (child) => Background( + child: child, + ), + child: Scaffold( + backgroundColor: isDesktop + ? Colors.transparent + : Theme.of(context).extension<StackColors>()!.background, + appBar: isDesktop + ? null + : AppBar( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + leading: AppBarBackButton( + onPressed: () async { + // if (FocusScope.of(context).hasFocus) { + // FocusScope.of(context).unfocus(); + // await Future<void>.delayed(Duration(milliseconds: 50)); + // } + Navigator.of(context).pop(); + }, + ), + title: Text( + "Transaction details", + style: STextStyles.navBarTitle(context), + ), + ), + body: Padding( + padding: isDesktop + ? const EdgeInsets.only(left: 32) + : const EdgeInsets.all(12), + child: Column( + children: [ + if (isDesktop) + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Transaction details", + style: STextStyles.desktopH3(context), + ), + const DesktopDialogCloseButton(), + ], + ), + Expanded( + child: Padding( + padding: isDesktop + ? const EdgeInsets.only( + right: 32, + bottom: 32, + ) + : const EdgeInsets.all(0), + child: ConditionalParent( + condition: isDesktop, + builder: (child) { + return RoundedWhiteContainer( + borderColor: isDesktop + ? Theme.of(context) + .extension<StackColors>()! + .backgroundAppBar + : null, + padding: const EdgeInsets.all(0), + child: child, + ); + }, + child: SingleChildScrollView( + primary: isDesktop ? false : null, + child: Padding( + padding: isDesktop + ? const EdgeInsets.all(0) + : const EdgeInsets.all(4), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(0) + : const EdgeInsets.all(12), + child: Container( + decoration: isDesktop + ? BoxDecoration( + color: Theme.of(context) + .extension<StackColors>()! + .backgroundAppBar, + borderRadius: BorderRadius.vertical( + top: Radius.circular( + Constants.size.circularBorderRadius, + ), + ), + ) + : null, + child: Padding( + padding: isDesktop + ? const EdgeInsets.all(12) + : const EdgeInsets.all(0), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + if (isDesktop) + Row( + children: [ + TxIcon( + transaction: _transaction, + currentHeight: currentHeight, + coin: coin, + ), + const SizedBox( + width: 16, + ), + SelectableText( + whatIsIt( + _transaction, + currentHeight, + ), + style: + STextStyles.desktopTextMedium( + context), + ), + ], + ), + Column( + crossAxisAlignment: isDesktop + ? CrossAxisAlignment.end + : CrossAxisAlignment.start, + children: [ + SelectableText( + "$amountPrefix${ref.watch(pAmountFormatter(coin)).format(amount)}", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension< + StackColors>()! + .textDark, + ) + : STextStyles.titleBold12( + context), + ), + const SizedBox( + height: 2, + ), + if (ref.watch( + prefsChangeNotifierProvider + .select((value) => + value.externalCalls))) + SelectableText( + "$amountPrefix${(amount.decimal * ref.watch( + priceAnd24hChangeNotifierProvider + .select((value) => + value + .getPrice( + coin) + .item1), + )).toAmount(fractionDigits: 2).fiatString( + locale: ref.watch( + localeServiceChangeNotifierProvider + .select( + (value) => value.locale, + ), + ), + )} ${ref.watch( + prefsChangeNotifierProvider + .select( + (value) => value.currency, + ), + )}", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle( + context), + ), + ], + ), + if (!isDesktop) + TxIcon( + transaction: _transaction, + currentHeight: currentHeight, + coin: coin, + ), + ], + ), + ), + ), + ), + + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + "Status", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall(context) + : STextStyles.itemSubtitle(context), + ), + // Flexible( + // child: FittedBox( + // fit: BoxFit.scaleDown, + // child: + SelectableText( + whatIsIt( + _transaction, + currentHeight, + ), + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: _transaction.type == + TransactionType.outgoing + ? Theme.of(context) + .extension<StackColors>()! + .accentColorOrange + : Theme.of(context) + .extension<StackColors>()! + .accentColorGreen, + ) + : STextStyles.itemSubtitle12(context), + ), + // ), + // ), + ], + ), + ), + if (!((coin == Coin.monero || + coin == Coin.wownero) && + _transaction.type == + TransactionType.outgoing) && + !((coin == Coin.firo || + coin == Coin.firoTestNet) && + _transaction.subType == + TransactionSubType.mint)) + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + if (!((coin == Coin.monero || + coin == Coin.wownero) && + _transaction.type == + TransactionType.outgoing) && + !((coin == Coin.firo || + coin == Coin.firoTestNet) && + _transaction.subType == + TransactionSubType.mint)) + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + ConditionalParent( + condition: kDebugMode, + builder: (child) { + return Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + children: [ + child, + // CustomTextButton( + // text: "Info", + // onTap: () async { + // final adr = await ref + // .read(mainDBProvider) + // .getAddress(walletId, + // addresses.first); + // if (adr != null && + // mounted) { + // if (isDesktop) { + // await showDialog< + // void>( + // context: context, + // builder: (_) => + // DesktopDialog( + // maxHeight: double + // .infinity, + // child: + // AddressDetailsView( + // addressId: + // adr.id, + // walletId: widget + // .walletId, + // ), + // ), + // ); + // } else { + // await Navigator.of( + // context) + // .pushNamed( + // AddressDetailsView + // .routeName, + // arguments: Tuple2( + // adr.id, + // widget.walletId, + // ), + // ); + // } + // } + // }, + // ) + ], + ); + }, + child: Text( + _transaction.type == + TransactionType.outgoing + ? "Sent to" + : "Received at", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle( + context), + ), + ), + const SizedBox( + height: 8, + ), + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + ...data.map( + (e) { + return Padding( + padding: + const EdgeInsets.all( + 8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + ...e.addresses.map( + (e) { + return FutureBuilder( + future: + fetchContactNameFor( + e), + builder: (builderContext, + AsyncSnapshot< + String> + snapshot) { + final String + addressOrContactName; + if (snapshot.connectionState == + ConnectionState + .done && + snapshot + .hasData) { + addressOrContactName = + snapshot + .data!; + } else { + addressOrContactName = + e; + } + + return SelectableText( + addressOrContactName, + style: isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ); + }, + ); + }, + ), + SelectableText( + ref + .watch( + pAmountFormatter( + coin)) + .format(e.amount), + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of( + context) + .extension< + StackColors>()! + .textDark, + ) + : STextStyles + .titleBold12( + context), + ), + ], + ), + ); + }, + ), + ], + ), + ], + ), + ), + // if (isDesktop) + // IconCopyButton( + // data: addresses.first, + // ), + ], + ), + ), + + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + (coin == Coin.epicCash) + ? "Local Note" + : "Note ", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle(context), + ), + isDesktop + ? IconPencilButton( + onPressed: () { + showDialog<void>( + context: context, + builder: (context) { + return DesktopDialog( + maxWidth: 580, + maxHeight: 360, + child: EditNoteView( + txid: _transaction.txid, + walletId: walletId, + note: _note, + ), + ); + }, + ); + }, + ) + : GestureDetector( + onTap: () { + Navigator.of(context).pushNamed( + EditNoteView.routeName, + arguments: Tuple3( + _transaction.txid, + walletId, + _note, + ), + ); + }, + child: Row( + children: [ + SvgPicture.asset( + Assets.svg.pencil, + width: 10, + height: 10, + color: Theme.of(context) + .extension< + StackColors>()! + .infoItemIcons, + ), + const SizedBox( + width: 4, + ), + Text( + "Edit", + style: STextStyles.link2( + context), + ), + ], + ), + ), + ], + ), + const SizedBox( + height: 8, + ), + FutureBuilder( + future: ref.watch( + notesServiceChangeNotifierProvider( + walletId) + .select((value) => value.getNoteFor( + txid: _transaction.txid))), + builder: (builderContext, + AsyncSnapshot<String> snapshot) { + if (snapshot.connectionState == + ConnectionState.done && + snapshot.hasData) { + _note = snapshot.data ?? ""; + } + return SelectableText( + _note, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12( + context), + ); + }, + ), + ], + ), + ), + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + "Date", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle(context), + ), + if (isDesktop) + const SizedBox( + height: 2, + ), + if (isDesktop) + SelectableText( + Format.extractDateFrom( + _transaction.timestamp, + ), + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12( + context), + ), + ], + ), + if (!isDesktop) + SelectableText( + Format.extractDateFrom( + _transaction.timestamp, + ), + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ), + if (isDesktop) + IconCopyButton( + data: Format.extractDateFrom( + _transaction.timestamp, + ), + ), + ], + ), + ), + if (coin != Coin.banano && coin != Coin.nano) + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + if (coin != Coin.banano && coin != Coin.nano) + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Builder(builder: (context) { + String feeString = showFeePending + ? _transaction.isConfirmed( + currentHeight, + coin.requiredConfirmations, + ) + ? ref + .watch(pAmountFormatter(coin)) + .format( + fee, + ) + : "Pending" + : ref + .watch(pAmountFormatter(coin)) + .format( + fee, + ); + + return Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + "Transaction fee", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle( + context), + ), + if (isDesktop) + const SizedBox( + height: 2, + ), + if (isDesktop) + SelectableText( + feeString, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension< + StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12( + context), + ), + ], + ), + if (!isDesktop) + SelectableText( + feeString, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12( + context), + ), + if (isDesktop) + IconCopyButton(data: feeString) + ], + ); + }), + ), + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Builder(builder: (context) { + final String height; + + if (widget.coin == Coin.bitcoincash || + widget.coin == Coin.eCash || + widget.coin == Coin.bitcoincashTestnet) { + height = + "${_transaction.height != null && _transaction.height! > 0 ? _transaction.height! : "Pending"}"; + } else { + height = widget.coin != Coin.epicCash && + _transaction.isConfirmed( + currentHeight, + coin.requiredConfirmations, + ) + ? "${_transaction.height == 0 ? "Unknown" : _transaction.height}" + : _transaction.getConfirmations( + currentHeight) > + 0 + ? "${_transaction.height}" + : "Pending"; + } + + return Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + "Block height", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle( + context), + ), + if (isDesktop) + const SizedBox( + height: 2, + ), + if (isDesktop) + SelectableText( + height, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension< + StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12( + context), + ), + ], + ), + if (!isDesktop) + SelectableText( + height, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12( + context), + ), + if (isDesktop) IconCopyButton(data: height), + ], + ); + }), + ), + + if (kDebugMode) + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + if (kDebugMode) + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + "Tx sub type", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle(context), + ), + SelectableText( + _transaction.subType.toString(), + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12(context), + ), + ], + ), + ), + isDesktop + ? const _Divider() + : const SizedBox( + height: 12, + ), + RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.all(16) + : const EdgeInsets.all(12), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + "Transaction ID", + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + : STextStyles.itemSubtitle( + context), + ), + const SizedBox( + height: 8, + ), + // Flexible( + // child: FittedBox( + // fit: BoxFit.scaleDown, + // child: + SelectableText( + _transaction.txid, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textDark, + ) + : STextStyles.itemSubtitle12( + context), + ), + if (coin != Coin.epicCash) + const SizedBox( + height: 8, + ), + if (coin != Coin.epicCash) + CustomTextButton( + text: "Open in block explorer", + onTap: () async { + final uri = + getBlockExplorerTransactionUrlFor( + coin: coin, + txid: _transaction.txid, + ); + + if (ref + .read( + prefsChangeNotifierProvider) + .hideBlockExplorerWarning == + false) { + final shouldContinue = + await showExplorerWarning( + "${uri.scheme}://${uri.host}"); + + if (!shouldContinue) { + return; + } + } + + // ref + // .read( + // shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = false; + try { + await launchUrl( + uri, + mode: LaunchMode + .externalApplication, + ); + } catch (_) { + if (mounted) { + unawaited( + showDialog<void>( + context: context, + builder: (_) => + StackOkDialog( + title: + "Could not open in block explorer", + message: + "Failed to open \"${uri.toString()}\"", + ), + ), + ); + } + } finally { + // Future<void>.delayed( + // const Duration(seconds: 1), + // () => ref + // .read( + // shouldShowLockscreenOnResumeStateProvider + // .state) + // .state = true, + // ); + } + }, + ), + // ), + // ), + ], + ), + ), + if (isDesktop) + const SizedBox( + width: 12, + ), + if (isDesktop) + IconCopyButton( + data: _transaction.txid, + ), + ], + ), + ), + // if ((coin == Coin.firoTestNet || coin == Coin.firo) && + // _transaction.subType == "mint") + // const SizedBox( + // height: 12, + // ), + // if ((coin == Coin.firoTestNet || coin == Coin.firo) && + // _transaction.subType == "mint") + // RoundedWhiteContainer( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // Text( + // "Mint Transaction ID", + // style: STextStyles.itemSubtitle(context), + // ), + // ], + // ), + // const SizedBox( + // height: 8, + // ), + // // Flexible( + // // child: FittedBox( + // // fit: BoxFit.scaleDown, + // // child: + // SelectableText( + // _transaction.otherData ?? "Unknown", + // style: STextStyles.itemSubtitle12(context), + // ), + // // ), + // // ), + // const SizedBox( + // height: 8, + // ), + // BlueTextButton( + // text: "Open in block explorer", + // onTap: () async { + // final uri = getBlockExplorerTransactionUrlFor( + // coin: coin, + // txid: _transaction.otherData ?? "Unknown", + // ); + // // ref + // // .read( + // // shouldShowLockscreenOnResumeStateProvider + // // .state) + // // .state = false; + // try { + // await launchUrl( + // uri, + // mode: LaunchMode.externalApplication, + // ); + // } catch (_) { + // unawaited(showDialog<void>( + // context: context, + // builder: (_) => StackOkDialog( + // title: "Could not open in block explorer", + // message: + // "Failed to open \"${uri.toString()}\"", + // ), + // )); + // } finally { + // // Future<void>.delayed( + // // const Duration(seconds: 1), + // // () => ref + // // .read( + // // shouldShowLockscreenOnResumeStateProvider + // // .state) + // // .state = true, + // // ); + // } + // }, + // ), + // ], + // ), + // ), + + if (!isDesktop) + const SizedBox( + height: 12, + ), + ], + ), + ), + ), + ), + ), + ), + ], + ), + ), + ), + ); + } +} + +class _Divider extends StatelessWidget { + const _Divider({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + height: 1, + color: Theme.of(context).extension<StackColors>()!.backgroundAppBar, + ); + } +} + +class IconCopyButton extends StatelessWidget { + const IconCopyButton({ + Key? key, + required this.data, + }) : super(key: key); + + final String data; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 26, + width: 26, + child: RawMaterialButton( + fillColor: + Theme.of(context).extension<StackColors>()!.buttonBackSecondary, + elevation: 0, + hoverElevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + onPressed: () async { + await Clipboard.setData(ClipboardData(text: data)); + if (context.mounted) { + unawaited( + showFloatingFlushBar( + type: FlushBarType.info, + message: "Copied to clipboard", + context: context, + ), + ); + } + }, + child: Padding( + padding: const EdgeInsets.all(5), + child: CopyIcon( + width: 16, + height: 16, + color: Theme.of(context).extension<StackColors>()!.textDark, + ), + ), + ), + ); + } +} + +class IconPencilButton extends StatelessWidget { + const IconPencilButton({ + Key? key, + this.onPressed, + }) : super(key: key); + + final VoidCallback? onPressed; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 26, + width: 26, + child: RawMaterialButton( + fillColor: + Theme.of(context).extension<StackColors>()!.buttonBackSecondary, + elevation: 0, + hoverElevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(6), + ), + onPressed: () => onPressed?.call(), + child: Padding( + padding: const EdgeInsets.all(5), + child: PencilIcon( + width: 16, + height: 16, + color: Theme.of(context).extension<StackColors>()!.textDark, + ), + ), + ), + ); + } +} diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart new file mode 100644 index 000000000..5ba44acb2 --- /dev/null +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart @@ -0,0 +1,189 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by Cypher Stack on 2023-10-19 + * + */ + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:isar/isar.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; +import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart'; +import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; +import 'package:stackwallet/providers/db/main_db_provider.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/loading_indicator.dart'; + +class TransactionsV2List extends ConsumerStatefulWidget { + const TransactionsV2List({ + Key? key, + required this.walletId, + }) : super(key: key); + + final String walletId; + + @override + ConsumerState<TransactionsV2List> createState() => _TransactionsV2ListState(); +} + +class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> { + bool _hasLoaded = false; + List<TransactionV2> _transactions = []; + + BorderRadius get _borderRadiusFirst { + return BorderRadius.only( + topLeft: Radius.circular( + Constants.size.circularBorderRadius, + ), + topRight: Radius.circular( + Constants.size.circularBorderRadius, + ), + ); + } + + BorderRadius get _borderRadiusLast { + return BorderRadius.only( + bottomLeft: Radius.circular( + Constants.size.circularBorderRadius, + ), + bottomRight: Radius.circular( + Constants.size.circularBorderRadius, + ), + ); + } + + @override + Widget build(BuildContext context) { + final manager = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(widget.walletId))); + + return FutureBuilder( + future: ref + .watch(mainDBProvider) + .isar + .transactionV2s + .where() + .walletIdEqualTo(widget.walletId) + .sortByTimestampDesc() + .findAll(), + builder: (fbContext, AsyncSnapshot<List<TransactionV2>> snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + _transactions = snapshot.data!; + _hasLoaded = true; + } + if (!_hasLoaded) { + return const Column( + children: [ + Spacer(), + Center( + child: LoadingIndicator( + height: 50, + width: 50, + ), + ), + Spacer( + flex: 4, + ), + ], + ); + } + if (_transactions.isEmpty) { + return const NoTransActionsFound(); + } else { + _transactions.sort((a, b) => b.timestamp - a.timestamp); + return RefreshIndicator( + onRefresh: () async { + final managerProvider = ref + .read(walletsChangeNotifierProvider) + .getManagerProvider(widget.walletId); + if (!ref.read(managerProvider).isRefreshing) { + unawaited(ref.read(managerProvider).refresh()); + } + }, + child: Util.isDesktop + ? ListView.separated( + shrinkWrap: true, + itemBuilder: (context, index) { + BorderRadius? radius; + if (_transactions.length == 1) { + radius = BorderRadius.circular( + Constants.size.circularBorderRadius, + ); + } else if (index == _transactions.length - 1) { + radius = _borderRadiusLast; + } else if (index == 0) { + radius = _borderRadiusFirst; + } + final tx = _transactions[index]; + return TxListItem( + tx: tx, + coin: manager.coin, + radius: radius, + ); + }, + separatorBuilder: (context, index) { + return Container( + width: double.infinity, + height: 2, + color: Theme.of(context) + .extension<StackColors>()! + .background, + ); + }, + itemCount: _transactions.length, + ) + : ListView.builder( + itemCount: _transactions.length, + itemBuilder: (context, index) { + BorderRadius? radius; + bool shouldWrap = false; + if (_transactions.length == 1) { + radius = BorderRadius.circular( + Constants.size.circularBorderRadius, + ); + } else if (index == _transactions.length - 1) { + radius = _borderRadiusLast; + shouldWrap = true; + } else if (index == 0) { + radius = _borderRadiusFirst; + } + final tx = _transactions[index]; + if (shouldWrap) { + return Column( + children: [ + TxListItem( + tx: tx, + coin: manager.coin, + radius: radius, + ), + const SizedBox( + height: WalletView.navBarHeight + 14, + ), + ], + ); + } else { + return TxListItem( + tx: tx, + coin: manager.coin, + radius: radius, + ); + } + }, + ), + ); + } + }, + ); + } +} diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart new file mode 100644 index 000000000..82fdce6d6 --- /dev/null +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart @@ -0,0 +1,160 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart'; +import 'package:stackwallet/pages/exchange_view/trade_details_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart'; +import 'package:stackwallet/providers/global/trades_service_provider.dart'; +import 'package:stackwallet/providers/global/wallets_provider.dart'; +import 'package:stackwallet/route_generator.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/trade_card.dart'; +import 'package:tuple/tuple.dart'; + +class TxListItem extends ConsumerWidget { + const TxListItem({ + super.key, + required this.tx, + this.radius, + required this.coin, + }); + + final TransactionV2 tx; + final BorderRadius? radius; + final Coin coin; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final matchingTrades = ref + .read(tradesServiceProvider) + .trades + .where((e) => e.payInTxid == tx.txid || e.payOutTxid == tx.txid); + + if (tx.type == TransactionType.outgoing && matchingTrades.isNotEmpty) { + final trade = matchingTrades.first; + return Container( + decoration: BoxDecoration( + color: Theme.of(context).extension<StackColors>()!.popupBG, + borderRadius: radius, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TransactionCardV2( + key: UniqueKey(), + transaction: tx, + ), + TradeCard( + key: Key(tx.txid + + tx.type.name + + tx.hashCode.toString() + + trade.uuid), // + trade: trade, + onTap: () async { + if (Util.isDesktop) { + await showDialog<void>( + context: context, + builder: (context) => Navigator( + initialRoute: TradeDetailsView.routeName, + onGenerateRoute: RouteGenerator.generateRoute, + onGenerateInitialRoutes: (_, __) { + return [ + FadePageRoute( + DesktopDialog( + maxHeight: null, + maxWidth: 580, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 32, + bottom: 16, + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + "Trade details", + style: STextStyles.desktopH3(context), + ), + DesktopDialogCloseButton( + onPressedOverride: Navigator.of( + context, + rootNavigator: true, + ).pop, + ), + ], + ), + ), + Flexible( + child: TradeDetailsView( + tradeId: trade.tradeId, + // TODO + // transactionIfSentFromStack: tx, + transactionIfSentFromStack: null, + walletName: ref.watch( + walletsChangeNotifierProvider.select( + (value) => value + .getManager(tx.walletId) + .walletName, + ), + ), + walletId: tx.walletId, + ), + ), + ], + ), + ), + const RouteSettings( + name: TradeDetailsView.routeName, + ), + ), + ]; + }, + ), + ); + } else { + unawaited( + Navigator.of(context).pushNamed( + TradeDetailsView.routeName, + arguments: Tuple4( + trade.tradeId, + tx, + tx.walletId, + ref + .read(walletsChangeNotifierProvider) + .getManager(tx.walletId) + .walletName, + ), + ), + ); + } + }, + ) + ], + ), + ); + } else { + return Container( + decoration: BoxDecoration( + color: Theme.of(context).extension<StackColors>()!.popupBG, + borderRadius: radius, + ), + child: TransactionCardV2( + // this may mess with combined firo transactions + key: UniqueKey(), + transaction: tx, + ), + ); + } + } +} diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart index 3804475eb..b9398cc66 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart @@ -19,9 +19,9 @@ import 'package:flutter_svg/svg.dart'; import 'package:stackwallet/pages/add_wallet_views/add_token_view/edit_wallet_tokens_view.dart'; import 'package:stackwallet/pages/special/firo_rescan_recovery_error_dialog.dart'; import 'package:stackwallet/pages/token_view/my_tokens_view.dart'; -import 'package:stackwallet/pages/wallet_view/sub_widgets/transaction_v2_list.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/transactions_list.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/my_wallet.dart'; diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 468ee5f11..85dab0310 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -17,6 +17,7 @@ import 'package:stackwallet/models/add_wallet_list_entity/sub_classes/eth_token_ import 'package:stackwallet/models/buy/response_objects/quote.dart'; import 'package:stackwallet/models/exchange/incomplete_exchange.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/models/isar/models/contact_entry.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/models/isar/ordinal.dart'; @@ -131,6 +132,7 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_search_filter_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart'; import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; import 'package:stackwallet/pages/wallets_view/wallets_overview.dart'; import 'package:stackwallet/pages/wallets_view/wallets_view.dart'; @@ -1259,6 +1261,22 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case TransactionV2DetailsView.routeName: + if (args is ({TransactionV2 tx, Coin coin, String walletId})) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => TransactionV2DetailsView( + transaction: args.tx, + coin: args.coin, + walletId: args.walletId, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case AllTransactionsView.routeName: if (args is ({String walletId, bool isTokens})) { return getRoute( From 79d117d7f1c869fe1bb87ad7e635e45564885169 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Oct 2023 16:05:30 -0600 Subject: [PATCH 324/379] print spam cleanup --- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 6c246aae3..63ff5cd21 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -1696,9 +1696,7 @@ class BitcoinCashWallet extends CoinServiceAPI } final scripthash = _convertToScriptHash(allAddresses[i].value, _network); - if (kDebugMode) { - print("SCRIPT_HASH_FOR_ADDRESS ${allAddresses[i]} IS $scripthash"); - } + batches[batchNumber]!.addAll({ scripthash: [scripthash] }); From c6a370e4f5d3124485eeb7e3be79717466e40d84 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 20 Oct 2023 17:26:42 -0600 Subject: [PATCH 325/379] WIP group fusions on wallet home screen activity --- .../tx_v2/fusion_tx_group_card.dart | 176 ++++++++++++ .../tx_v2/transaction_v2_list.dart | 71 ++++- .../tx_v2/transaction_v2_list_item.dart | 258 ++++++++++-------- .../wallet_view/desktop_wallet_view.dart | 2 +- lib/utilities/format.dart | 15 +- 5 files changed, 392 insertions(+), 130 deletions(-) create mode 100644 lib/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart b/lib/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart new file mode 100644 index 000000000..0197ea15c --- /dev/null +++ b/lib/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart @@ -0,0 +1,176 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; +import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; +import 'package:stackwallet/providers/providers.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/format.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; + +class FusionTxGroup { + final List<TransactionV2> transactions; + FusionTxGroup(this.transactions); +} + +class FusionTxGroupCard extends ConsumerWidget { + const FusionTxGroupCard({super.key, required this.group}); + + final FusionTxGroup group; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final walletId = group.transactions.first.walletId; + + final coin = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).coin)); + + final currentHeight = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).currentHeight)); + + return Material( + color: Theme.of(context).extension<StackColors>()!.popupBG, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(Constants.size.circularBorderRadius), + ), + child: Padding( + padding: const EdgeInsets.all(6), + child: RawMaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + onPressed: () async { + if (Util.isDesktop) { + // await showDialog<void>( + // context: context, + // builder: (context) => DesktopDialog( + // maxHeight: MediaQuery.of(context).size.height - 64, + // maxWidth: 580, + // child: TransactionV2DetailsView( + // transaction: _transaction, + // coin: coin, + // walletId: walletId, + // ), + // ), + // ); + } else { + // unawaited( + // Navigator.of(context).pushNamed( + // TransactionV2DetailsView.routeName, + // arguments: ( + // tx: _transaction, + // coin: coin, + // walletId: walletId, + // ), + // ), + // ); + } + }, + child: Padding( + padding: const EdgeInsets.all(8), + child: Row( + children: [ + TxIcon( + transaction: group.transactions.first, + coin: coin, + currentHeight: currentHeight, + ), + const SizedBox( + width: 14, + ), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + // crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + "Fusions", + style: STextStyles.itemSubtitle12(context), + ), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Builder( + builder: (_) { + return Text( + "${group.transactions.length} fusion transactions", + style: STextStyles.itemSubtitle12(context), + ); + }, + ), + ), + ), + ], + ), + const SizedBox( + height: 4, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + // crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Flexible( + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + Format.extractDateFrom( + group.transactions.last.timestamp, + ), + style: STextStyles.label(context), + ), + ), + ), + // if (ref.watch(prefsChangeNotifierProvider + // .select((value) => value.externalCalls))) + // const SizedBox( + // width: 10, + // ), + // if (ref.watch(prefsChangeNotifierProvider + // .select((value) => value.externalCalls))) + // Flexible( + // child: FittedBox( + // fit: BoxFit.scaleDown, + // child: Builder( + // builder: (_) { + // return Text( + // "$prefix${Amount.fromDecimal( + // amount.decimal * price, + // fractionDigits: 2, + // ).fiatString( + // locale: locale, + // )} $baseCurrency", + // style: STextStyles.label(context), + // ); + // }, + // ), + // ), + // ), + ], + ), + ], + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart index 5ba44acb2..8cdff69cb 100644 --- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart @@ -13,8 +13,10 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:isar/isar.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart'; import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; import 'package:stackwallet/providers/db/main_db_provider.dart'; @@ -102,6 +104,59 @@ class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> { return const NoTransActionsFound(); } else { _transactions.sort((a, b) => b.timestamp - a.timestamp); + + final List<Object> _txns = []; + + List<TransactionV2> fusions = []; + + for (int i = 0; i < _transactions.length; i++) { + final tx = _transactions[i]; + + if (tx.subType == TransactionSubType.cashFusion) { + if (fusions.isNotEmpty) { + final prevTime = DateTime.fromMillisecondsSinceEpoch( + fusions.last.timestamp * 1000); + final thisTime = + DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000); + + print( + "DIFFERERNCE: ${prevTime.difference(thisTime).inMinutes}"); + + if (prevTime.difference(thisTime).inMinutes > 30) { + _txns.add(FusionTxGroup(fusions)); + fusions = [tx]; + continue; + } + } + + fusions.add(tx); + } + + if (i + 1 < _transactions.length) { + final nextTx = _transactions[i + 1]; + if (nextTx.subType != TransactionSubType.cashFusion && + fusions.isNotEmpty) { + _txns.add(FusionTxGroup(fusions)); + fusions = []; + } + } + + if (tx.subType != TransactionSubType.cashFusion) { + _txns.add(tx); + } + } + + // sanity check + int count = 0; + for (final e in _txns) { + if (e is TransactionV2) { + count++; + } else if (e is FusionTxGroup) { + count += e.transactions.length; + } + } + assert(count == _transactions.length); + return RefreshIndicator( onRefresh: () async { final managerProvider = ref @@ -116,16 +171,16 @@ class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> { shrinkWrap: true, itemBuilder: (context, index) { BorderRadius? radius; - if (_transactions.length == 1) { + if (_txns.length == 1) { radius = BorderRadius.circular( Constants.size.circularBorderRadius, ); - } else if (index == _transactions.length - 1) { + } else if (index == _txns.length - 1) { radius = _borderRadiusLast; } else if (index == 0) { radius = _borderRadiusFirst; } - final tx = _transactions[index]; + final tx = _txns[index]; return TxListItem( tx: tx, coin: manager.coin, @@ -141,24 +196,24 @@ class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> { .background, ); }, - itemCount: _transactions.length, + itemCount: _txns.length, ) : ListView.builder( - itemCount: _transactions.length, + itemCount: _txns.length, itemBuilder: (context, index) { BorderRadius? radius; bool shouldWrap = false; - if (_transactions.length == 1) { + if (_txns.length == 1) { radius = BorderRadius.circular( Constants.size.circularBorderRadius, ); - } else if (index == _transactions.length - 1) { + } else if (index == _txns.length - 1) { radius = _borderRadiusLast; shouldWrap = true; } else if (index == 0) { radius = _borderRadiusFirst; } - final tx = _transactions[index]; + final tx = _txns[index]; if (shouldWrap) { return Column( children: [ diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart index 82fdce6d6..6780f7e49 100644 --- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart @@ -5,6 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/pages/exchange_view/trade_details_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart'; import 'package:stackwallet/providers/global/trades_service_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; @@ -24,137 +25,156 @@ class TxListItem extends ConsumerWidget { required this.tx, this.radius, required this.coin, - }); + }) : assert(tx is TransactionV2 || tx is FusionTxGroup); - final TransactionV2 tx; + final Object tx; final BorderRadius? radius; final Coin coin; @override Widget build(BuildContext context, WidgetRef ref) { - final matchingTrades = ref - .read(tradesServiceProvider) - .trades - .where((e) => e.payInTxid == tx.txid || e.payOutTxid == tx.txid); + if (tx is TransactionV2) { + final _tx = tx as TransactionV2; - if (tx.type == TransactionType.outgoing && matchingTrades.isNotEmpty) { - final trade = matchingTrades.first; - return Container( - decoration: BoxDecoration( - color: Theme.of(context).extension<StackColors>()!.popupBG, - borderRadius: radius, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - TransactionCardV2( - key: UniqueKey(), - transaction: tx, - ), - TradeCard( - key: Key(tx.txid + - tx.type.name + - tx.hashCode.toString() + - trade.uuid), // - trade: trade, - onTap: () async { - if (Util.isDesktop) { - await showDialog<void>( - context: context, - builder: (context) => Navigator( - initialRoute: TradeDetailsView.routeName, - onGenerateRoute: RouteGenerator.generateRoute, - onGenerateInitialRoutes: (_, __) { - return [ - FadePageRoute( - DesktopDialog( - maxHeight: null, - maxWidth: 580, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.only( - left: 32, - bottom: 16, - ), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Text( - "Trade details", - style: STextStyles.desktopH3(context), - ), - DesktopDialogCloseButton( - onPressedOverride: Navigator.of( - context, - rootNavigator: true, - ).pop, - ), - ], - ), - ), - Flexible( - child: TradeDetailsView( - tradeId: trade.tradeId, - // TODO - // transactionIfSentFromStack: tx, - transactionIfSentFromStack: null, - walletName: ref.watch( - walletsChangeNotifierProvider.select( - (value) => value - .getManager(tx.walletId) - .walletName, - ), + final matchingTrades = ref + .read(tradesServiceProvider) + .trades + .where((e) => e.payInTxid == _tx.txid || e.payOutTxid == _tx.txid); + + if (_tx.type == TransactionType.outgoing && matchingTrades.isNotEmpty) { + final trade = matchingTrades.first; + return Container( + decoration: BoxDecoration( + color: Theme.of(context).extension<StackColors>()!.popupBG, + borderRadius: radius, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TransactionCardV2( + key: UniqueKey(), + transaction: _tx, + ), + TradeCard( + key: Key(_tx.txid + + _tx.type.name + + _tx.hashCode.toString() + + trade.uuid), // + trade: trade, + onTap: () async { + if (Util.isDesktop) { + await showDialog<void>( + context: context, + builder: (context) => Navigator( + initialRoute: TradeDetailsView.routeName, + onGenerateRoute: RouteGenerator.generateRoute, + onGenerateInitialRoutes: (_, __) { + return [ + FadePageRoute( + DesktopDialog( + maxHeight: null, + maxWidth: 580, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 32, + bottom: 16, + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + "Trade details", + style: + STextStyles.desktopH3(context), + ), + DesktopDialogCloseButton( + onPressedOverride: Navigator.of( + context, + rootNavigator: true, + ).pop, + ), + ], ), - walletId: tx.walletId, ), - ), - ], + Flexible( + child: TradeDetailsView( + tradeId: trade.tradeId, + // TODO + // transactionIfSentFromStack: tx, + transactionIfSentFromStack: null, + walletName: ref.watch( + walletsChangeNotifierProvider.select( + (value) => value + .getManager(_tx.walletId) + .walletName, + ), + ), + walletId: _tx.walletId, + ), + ), + ], + ), + ), + const RouteSettings( + name: TradeDetailsView.routeName, ), ), - const RouteSettings( - name: TradeDetailsView.routeName, - ), - ), - ]; - }, - ), - ); - } else { - unawaited( - Navigator.of(context).pushNamed( - TradeDetailsView.routeName, - arguments: Tuple4( - trade.tradeId, - tx, - tx.walletId, - ref - .read(walletsChangeNotifierProvider) - .getManager(tx.walletId) - .walletName, + ]; + }, ), - ), - ); - } - }, - ) - ], - ), - ); - } else { - return Container( - decoration: BoxDecoration( - color: Theme.of(context).extension<StackColors>()!.popupBG, - borderRadius: radius, - ), - child: TransactionCardV2( - // this may mess with combined firo transactions - key: UniqueKey(), - transaction: tx, - ), - ); + ); + } else { + unawaited( + Navigator.of(context).pushNamed( + TradeDetailsView.routeName, + arguments: Tuple4( + trade.tradeId, + _tx, + _tx.walletId, + ref + .read(walletsChangeNotifierProvider) + .getManager(_tx.walletId) + .walletName, + ), + ), + ); + } + }, + ) + ], + ), + ); + } else { + return Container( + decoration: BoxDecoration( + color: Theme.of(context).extension<StackColors>()!.popupBG, + borderRadius: radius, + ), + child: TransactionCardV2( + // this may mess with combined firo transactions + key: UniqueKey(), + transaction: _tx, + ), + ); + } } + + final group = tx as FusionTxGroup; + + return Container( + decoration: BoxDecoration( + color: Theme.of(context).extension<StackColors>()!.popupBG, + borderRadius: radius, + ), + child: FusionTxGroupCard( + // this may mess with combined firo transactions + key: UniqueKey(), + group: group, + ), + ); } } diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart index b9398cc66..26e066ad9 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart @@ -446,7 +446,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> { .getManager(widget.walletId) .hasTokenSupport)) ? "Tokens" - : "Recent transactions", + : "Recent activity", style: STextStyles.desktopTextExtraSmall(context) .copyWith( color: Theme.of(context) diff --git a/lib/utilities/format.dart b/lib/utilities/format.dart index 2139a750e..216be7099 100644 --- a/lib/utilities/format.dart +++ b/lib/utilities/format.dart @@ -50,16 +50,27 @@ abstract class Format { // } // format date string from unix timestamp - static String extractDateFrom(int timestamp, {bool localized = true}) { + static String extractDateFrom( + int timestamp, { + bool localized = true, + bool noTime = false, + }) { var date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000); if (!localized) { date = date.toUtc(); } + final dayAndYear = + "${date.day} ${Constants.monthMapShort[date.month]} ${date.year}"; + + if (noTime) { + return dayAndYear; + } + final minutes = date.minute < 10 ? "0${date.minute}" : date.minute.toString(); - return "${date.day} ${Constants.monthMapShort[date.month]} ${date.year}, ${date.hour}:$minutes"; + return "$dayAndYear, ${date.hour}:$minutes"; } // static String localizedStringAsFixed({ From 4627af92086a9546029a805ee9640045d0424c34 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sat, 21 Oct 2023 16:45:35 -0500 Subject: [PATCH 326/379] raise maxNumberOfIndexesToCheck for bch --- .../sub_widgets/restoring_wallet_card.dart | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart index 3e762e177..1e99a1a4b 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart @@ -117,7 +117,12 @@ class _RestoringWalletCardState extends ConsumerState<RestoringWalletCard> { if (coin == Coin.firo) { maxUnusedAddressGap = 50; } - const maxNumberOfIndexesToCheck = 1000; + + int maxNumberOfIndexesToCheck = 1000; + // If Bitcoin Cash, multiply by 100. + if (coin == Coin.bitcoincash) { + maxNumberOfIndexesToCheck *= 100; + } if (mnemonicList.isEmpty) { await manager.recoverFromMnemonic( @@ -262,7 +267,12 @@ class _RestoringWalletCardState extends ConsumerState<RestoringWalletCard> { if (coin == Coin.firo) { maxUnusedAddressGap = 50; } - const maxNumberOfIndexesToCheck = 1000; + + int maxNumberOfIndexesToCheck = 1000; + // If Bitcoin Cash, multiply by 100. + if (coin == Coin.bitcoincash) { + maxNumberOfIndexesToCheck *= 100; + } if (mnemonicList.isEmpty) { await manager.recoverFromMnemonic( From 5720f08aadb3a2329fab3a5c62b4111302af9c23 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sat, 21 Oct 2023 16:45:35 -0500 Subject: [PATCH 327/379] Revert "raise maxNumberOfIndexesToCheck for bch" This reverts commit 4627af92086a9546029a805ee9640045d0424c34. --- .../sub_widgets/restoring_wallet_card.dart | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart index 1e99a1a4b..3e762e177 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_widgets/restoring_wallet_card.dart @@ -117,12 +117,7 @@ class _RestoringWalletCardState extends ConsumerState<RestoringWalletCard> { if (coin == Coin.firo) { maxUnusedAddressGap = 50; } - - int maxNumberOfIndexesToCheck = 1000; - // If Bitcoin Cash, multiply by 100. - if (coin == Coin.bitcoincash) { - maxNumberOfIndexesToCheck *= 100; - } + const maxNumberOfIndexesToCheck = 1000; if (mnemonicList.isEmpty) { await manager.recoverFromMnemonic( @@ -267,12 +262,7 @@ class _RestoringWalletCardState extends ConsumerState<RestoringWalletCard> { if (coin == Coin.firo) { maxUnusedAddressGap = 50; } - - int maxNumberOfIndexesToCheck = 1000; - // If Bitcoin Cash, multiply by 100. - if (coin == Coin.bitcoincash) { - maxNumberOfIndexesToCheck *= 100; - } + const maxNumberOfIndexesToCheck = 1000; if (mnemonicList.isEmpty) { await manager.recoverFromMnemonic( From 93a0f1f6abe57e89f1d00c10c690fac10b61d7ae Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sat, 21 Oct 2023 16:51:45 -0500 Subject: [PATCH 328/379] reconfigure rescan logic to raise maxNumberOfIndexesToCheck as needed so if we have activity beyond index 1000, maxNumberOfIndexesToCheck effectively increases --- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 63ff5cd21..5d3501f82 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -472,8 +472,14 @@ class BitcoinCashWallet extends CoinServiceAPI int gapCounter = 0; int highestIndexWithHistory = 0; + // Loop until either the index limit or the highest index with history, + // whichever is greater, plus the gap limit, so that we if there is activity + // above the max index, the limit is raised to that index plus the gap limit. for (int index = 0; - index < maxNumberOfIndexesToCheck && gapCounter < maxUnusedAddressGap; + index < + max(maxNumberOfIndexesToCheck, + highestIndexWithHistory + maxUnusedAddressGap) && + gapCounter < maxUnusedAddressGap; index += txCountBatchSize) { List<String> iterationsAddressArray = []; Logging.instance.log( From c761b9ae655ca39ec79c5979e4ee779d31f33b4a Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Sat, 21 Oct 2023 16:53:45 -0500 Subject: [PATCH 329/379] rename variable to be more accurate according to last commit's logic --- .../coins/bitcoincash/bitcoincash_wallet.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 5d3501f82..cb71d4f4e 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -461,7 +461,7 @@ class BitcoinCashWallet extends CoinServiceAPI } Future<Tuple3<List<isar_models.Address>, DerivePathType, int>> _checkGaps( - int maxNumberOfIndexesToCheck, + int minNumberOfIndexesToCheck, int maxUnusedAddressGap, int txCountBatchSize, bip32.BIP32 root, @@ -472,12 +472,13 @@ class BitcoinCashWallet extends CoinServiceAPI int gapCounter = 0; int highestIndexWithHistory = 0; - // Loop until either the index limit or the highest index with history, - // whichever is greater, plus the gap limit, so that we if there is activity - // above the max index, the limit is raised to that index plus the gap limit. + // Scan addresses until the minimum required addresses have been scanned or + // until the highest index with activity, plus the gap limit, whichever is + // higher, so that we if there is activity above the minimum index, we don't + // miss it. for (int index = 0; index < - max(maxNumberOfIndexesToCheck, + max(minNumberOfIndexesToCheck, highestIndexWithHistory + maxUnusedAddressGap) && gapCounter < maxUnusedAddressGap; index += txCountBatchSize) { From 355c247275ac0d0663e3caa98d48449fece813c8 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Oct 2023 09:51:54 -0600 Subject: [PATCH 330/379] remove unused vars --- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index cb71d4f4e..d39fbffad 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2071,8 +2071,6 @@ class BitcoinCashWallet extends CoinServiceAPI for (final txData in allTransactions) { // set to true if any inputs were detected as owned by this wallet bool wasSentFromThisWallet = false; - BigInt amountSentFromThisWallet = - BigInt.zero; // unsure if needed. Not used rn // set to true if any outputs were detected as owned by this wallet bool wasReceivedInThisWallet = false; @@ -2130,7 +2128,6 @@ class BitcoinCashWallet extends CoinServiceAPI if (allAddressesSet.intersection(input.addresses.toSet()).isNotEmpty) { wasSentFromThisWallet = true; - amountSentFromThisWallet += input.value; input = input.copyWith(walletOwns: true); } @@ -2165,15 +2162,10 @@ class BitcoinCashWallet extends CoinServiceAPI outputs.add(output); } - final totalIn = inputs - .map((e) => e.value) - .reduce((value, element) => value += element); final totalOut = outputs .map((e) => e.value) .reduce((value, element) => value += element); - final fee = totalIn - totalOut; - isar_models.TransactionType type; isar_models.TransactionSubType subType = isar_models.TransactionSubType.none; From 0c3735ef41a0677a7c83c3f7f4239dc9006885d5 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Oct 2023 10:47:44 -0600 Subject: [PATCH 331/379] ignore bad tx for now and log it --- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index d39fbffad..0c9496a3e 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2200,7 +2200,11 @@ class BitcoinCashWallet extends CoinServiceAPI // only found outputs owned by this wallet type = isar_models.TransactionType.incoming; } else { - throw Exception("Unexpected tx found: $txData"); + Logging.instance.log( + "Unexpected tx found: $txData", + level: LogLevel.Error, + ); + continue; } final tx = TransactionV2( From 3b2260aab212cdd61545ed7d06aee2013cabfbb8 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Oct 2023 10:55:11 -0600 Subject: [PATCH 332/379] possible bad state: no element error fix --- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 0c9496a3e..783146c11 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2164,7 +2164,7 @@ class BitcoinCashWallet extends CoinServiceAPI final totalOut = outputs .map((e) => e.value) - .reduce((value, element) => value += element); + .fold(BigInt.zero, (value, element) => value + element); isar_models.TransactionType type; isar_models.TransactionSubType subType = From f290743d31533bd02d989f765469b43a33d42d28 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Oct 2023 11:16:05 -0600 Subject: [PATCH 333/379] clean up --- .../tx_v2/transaction_v2_list.dart | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart index 8cdff69cb..3179fedcc 100644 --- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart @@ -119,9 +119,6 @@ class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> { final thisTime = DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000); - print( - "DIFFERERNCE: ${prevTime.difference(thisTime).inMinutes}"); - if (prevTime.difference(thisTime).inMinutes > 30) { _txns.add(FusionTxGroup(fusions)); fusions = [tx]; @@ -146,17 +143,6 @@ class _TransactionsV2ListState extends ConsumerState<TransactionsV2List> { } } - // sanity check - int count = 0; - for (final e in _txns) { - if (e is TransactionV2) { - count++; - } else if (e is FusionTxGroup) { - count += e.transactions.length; - } - } - assert(count == _transactions.length); - return RefreshIndicator( onRefresh: () async { final managerProvider = ref From 4c6404cfb22aa9432deac2134d52cd6f5b0de6e7 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Oct 2023 11:42:45 -0600 Subject: [PATCH 334/379] fusion group details --- .../tx_v2/fusion_group_details_view.dart | 234 ++++++++++++++++++ .../tx_v2/fusion_tx_group_card.dart | 47 ++-- .../tx_v2/transaction_v2_list_item.dart | 1 - lib/route_generator.dart | 21 ++ 4 files changed, 280 insertions(+), 23 deletions(-) create mode 100644 lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart b/lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart new file mode 100644 index 000000000..5b9ded00e --- /dev/null +++ b/lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart @@ -0,0 +1,234 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by Cypher Stack on 2023-05-26 + * + */ + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart'; +import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/background.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; + +class FusionGroupDetailsView extends ConsumerStatefulWidget { + const FusionGroupDetailsView({ + Key? key, + required this.transactions, + required this.walletId, + required this.coin, + }) : super(key: key); + + static const String routeName = "/fusionGroupDetailsView"; + + final List<TransactionV2> transactions; + final String walletId; + final Coin coin; + + @override + ConsumerState<FusionGroupDetailsView> createState() => + _FusionGroupDetailsViewState(); +} + +class _FusionGroupDetailsViewState + extends ConsumerState<FusionGroupDetailsView> { + late final bool isDesktop; + late final String walletId; + + BorderRadius get _borderRadiusFirst { + return BorderRadius.only( + topLeft: Radius.circular( + Constants.size.circularBorderRadius, + ), + topRight: Radius.circular( + Constants.size.circularBorderRadius, + ), + ); + } + + BorderRadius get _borderRadiusLast { + return BorderRadius.only( + bottomLeft: Radius.circular( + Constants.size.circularBorderRadius, + ), + bottomRight: Radius.circular( + Constants.size.circularBorderRadius, + ), + ); + } + + @override + void initState() { + isDesktop = Util.isDesktop; + walletId = widget.walletId; + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ConditionalParent( + condition: !isDesktop, + builder: (child) => Background( + child: child, + ), + child: Scaffold( + backgroundColor: isDesktop + ? Colors.transparent + : Theme.of(context).extension<StackColors>()!.background, + appBar: isDesktop + ? null + : AppBar( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + leading: AppBarBackButton( + onPressed: () async { + Navigator.of(context).pop(); + }, + ), + title: Text( + "Fusion transactions", + style: STextStyles.navBarTitle(context), + ), + ), + body: Padding( + padding: isDesktop + ? const EdgeInsets.only(left: 32) + : const EdgeInsets.all(12), + child: Column( + children: [ + if (isDesktop) + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Fusion transactions", + style: STextStyles.desktopH3(context), + ), + const DesktopDialogCloseButton(), + ], + ), + Flexible( + child: Padding( + padding: isDesktop + ? const EdgeInsets.only( + right: 32, + bottom: 32, + ) + : const EdgeInsets.all(0), + child: ConditionalParent( + condition: isDesktop, + builder: (child) { + return RoundedWhiteContainer( + borderColor: isDesktop + ? Theme.of(context) + .extension<StackColors>()! + .backgroundAppBar + : null, + padding: const EdgeInsets.all(0), + child: child, + ); + }, + child: SingleChildScrollView( + primary: isDesktop ? false : null, + child: Padding( + padding: isDesktop + ? const EdgeInsets.all(0) + : const EdgeInsets.all(4), + child: Util.isDesktop + ? ListView.separated( + shrinkWrap: true, + itemBuilder: (context, index) { + BorderRadius? radius; + if (widget.transactions.length == 1) { + radius = BorderRadius.circular( + Constants.size.circularBorderRadius, + ); + } else if (index == + widget.transactions.length - 1) { + radius = _borderRadiusLast; + } else if (index == 0) { + radius = _borderRadiusFirst; + } + final tx = widget.transactions[index]; + return TxListItem( + tx: tx, + coin: widget.coin, + radius: radius, + ); + }, + separatorBuilder: (context, index) { + return Container( + width: double.infinity, + height: 1.2, + color: Theme.of(context) + .extension<StackColors>()! + .background, + ); + }, + itemCount: widget.transactions.length, + ) + : ListView.builder( + itemCount: widget.transactions.length, + itemBuilder: (context, index) { + BorderRadius? radius; + bool shouldWrap = false; + if (widget.transactions.length == 1) { + radius = BorderRadius.circular( + Constants.size.circularBorderRadius, + ); + } else if (index == + widget.transactions.length - 1) { + radius = _borderRadiusLast; + shouldWrap = true; + } else if (index == 0) { + radius = _borderRadiusFirst; + } + final tx = widget.transactions[index]; + if (shouldWrap) { + return Column( + children: [ + TxListItem( + tx: tx, + coin: widget.coin, + radius: radius, + ), + const SizedBox( + height: WalletView.navBarHeight + 14, + ), + ], + ); + } else { + return TxListItem( + tx: tx, + coin: widget.coin, + radius: radius, + ); + } + }, + ), + ), + ), + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart b/lib/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart index 0197ea15c..aad00fa1e 100644 --- a/lib/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart +++ b/lib/pages/wallet_view/transaction_views/tx_v2/fusion_tx_group_card.dart @@ -1,13 +1,17 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; class FusionTxGroup { final List<TransactionV2> transactions; @@ -46,29 +50,28 @@ class FusionTxGroupCard extends ConsumerWidget { ), onPressed: () async { if (Util.isDesktop) { - // await showDialog<void>( - // context: context, - // builder: (context) => DesktopDialog( - // maxHeight: MediaQuery.of(context).size.height - 64, - // maxWidth: 580, - // child: TransactionV2DetailsView( - // transaction: _transaction, - // coin: coin, - // walletId: walletId, - // ), - // ), - // ); + await showDialog<void>( + context: context, + builder: (context) => DesktopDialog( + maxWidth: 580, + child: FusionGroupDetailsView( + transactions: group.transactions, + coin: coin, + walletId: walletId, + ), + ), + ); } else { - // unawaited( - // Navigator.of(context).pushNamed( - // TransactionV2DetailsView.routeName, - // arguments: ( - // tx: _transaction, - // coin: coin, - // walletId: walletId, - // ), - // ), - // ); + unawaited( + Navigator.of(context).pushNamed( + FusionGroupDetailsView.routeName, + arguments: ( + transactions: group.transactions, + coin: coin, + walletId: walletId, + ), + ), + ); } }, child: Padding( diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart index 6780f7e49..b0171c950 100644 --- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart @@ -171,7 +171,6 @@ class TxListItem extends ConsumerWidget { borderRadius: radius, ), child: FusionTxGroupCard( - // this may mess with combined firo transactions key: UniqueKey(), group: group, ), diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 85dab0310..7978d6d8d 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -132,6 +132,7 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_search_filter_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart'; import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; import 'package:stackwallet/pages/wallets_view/wallets_overview.dart'; @@ -1277,6 +1278,26 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case FusionGroupDetailsView.routeName: + if (args is ({ + List<TransactionV2> transactions, + Coin coin, + String walletId + })) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => FusionGroupDetailsView( + transactions: args.transactions, + coin: args.coin, + walletId: args.walletId, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case AllTransactionsView.routeName: if (args is ({String walletId, bool isTokens})) { return getRoute( From f81b71ba9e6d1b4d35b81bb2dac8d31d427b27e0 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 23 Oct 2023 13:19:36 -0500 Subject: [PATCH 335/379] icons same color as text --- .../cashfusion/sub_widgets/fusion_progress.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart index f5112e4fc..a976c225d 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_progress.dart @@ -124,6 +124,7 @@ class _ProgressItem extends StatelessWidget { iconAsset, width: 18, height: 18, + color: Theme.of(context).extension<StackColors>()!.textDark, ), ), ), From bd634e556446a639ffd3b438bd7fb28a245b1c20 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Oct 2023 12:38:42 -0600 Subject: [PATCH 336/379] remove unused file and color fix --- .../tx_v2/transaction_v2_details_item.dart | 98 ------------------- .../tx_v2/transaction_v2_details_view.dart | 3 +- 2 files changed, 2 insertions(+), 99 deletions(-) delete mode 100644 lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_item.dart diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_item.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_item.dart deleted file mode 100644 index 242b85408..000000000 --- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_item.dart +++ /dev/null @@ -1,98 +0,0 @@ -import 'package:flutter/material.dart'; -// import 'package:stackwallet/themes/stack_colors.dart'; -// import 'package:stackwallet/utilities/text_styles.dart'; -// import 'package:stackwallet/utilities/util.dart'; -// import 'package:stackwallet/widgets/rounded_white_container.dart'; - -// class TransactionV2DetailsItem extends StatelessWidget { -// const TransactionV2DetailsItem({ -// super.key, -// required this.label, -// required this.data, -// required this.infoOrientation, -// this.topRight, -// this.bottomLeft, -// }); -// -// final String label; -// final String data; -// final Axis infoOrientation; -// final bool showLabelBelowData; -// -// final Widget? topRight; -// final Widget? bottomLeft; -// -// @override -// Widget build(BuildContext context) { -// final isDesktop = Util.isDesktop; -// -// return RoundedWhiteContainer( -// padding: isDesktop ? const EdgeInsets.all(16) : const EdgeInsets.all(12), -// child: CommonChildren( -// buildIndex: infoOrientation == Axis.vertical ? 0 : 1, -// builders: [ -// (children) => Column( -// children: children, -// ), -// (children) => Row( -// children: children, -// ), -// ], -// children: [ -// Text( -// label, -// style: isDesktop -// ? STextStyles.desktopTextExtraExtraSmall(context) -// : STextStyles.itemSubtitle(context), -// ), -// const SizedBox(height: 8,), -// SelectableText( -// data, -// style: isDesktop -// ? STextStyles.desktopTextExtraExtraSmall(context).copyWith( -// color: Theme.of(context).extension<StackColors>()!.textDark, -// ) -// : STextStyles.itemSubtitle12(context), -// ), -// -// ], -// ), -// ); -// } -// } - -class CommonChild extends StatelessWidget { - const CommonChild({ - super.key, - required this.builders, - required this.buildIndex, - required this.child, - }); - - final Widget child; - final int buildIndex; - final List<Widget Function(Widget)> builders; - - @override - Widget build(BuildContext context) { - return builders[buildIndex](child); - } -} - -class CommonChildren extends StatelessWidget { - const CommonChildren({ - super.key, - required this.builders, - required this.buildIndex, - required this.children, - }); - - final List<Widget> children; - final int buildIndex; - final List<Widget Function(List<Widget>)> builders; - - @override - Widget build(BuildContext context) { - return builders[buildIndex](children); - } -} diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart index f87349875..ffe732a24 100644 --- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart @@ -626,7 +626,8 @@ class _TransactionV2DetailsViewState context) .copyWith( color: _transaction.type == - TransactionType.outgoing + TransactionType.outgoing && _transaction.subType != + TransactionSubType.cashFusion ? Theme.of(context) .extension<StackColors>()! .accentColorOrange From 0396b7865f245be9fdfe134b5851d3a1e5500224 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Oct 2023 13:29:30 -0600 Subject: [PATCH 337/379] all transactions sort groups properly --- .../all_transactions_view.dart | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart index 002376ca3..eae121a44 100644 --- a/lib/pages/wallet_view/transaction_views/all_transactions_view.dart +++ b/lib/pages/wallet_view/transaction_views/all_transactions_view.dart @@ -47,6 +47,12 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart'; import 'package:stackwallet/widgets/transaction_card.dart'; import 'package:tuple/tuple.dart'; +typedef _GroupedTransactions = ({ + String label, + DateTime startDate, + List<Transaction> transactions +}); + class AllTransactionsView extends ConsumerStatefulWidget { const AllTransactionsView({ Key? key, @@ -192,25 +198,24 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> { .toList(); } - List<Tuple2<String, List<Transaction>>> groupTransactionsByMonth( - List<Transaction> transactions) { - Map<String, List<Transaction>> map = {}; + List<_GroupedTransactions> groupTransactionsByMonth( + List<Transaction> transactions, + ) { + Map<String, _GroupedTransactions> map = {}; for (var tx in transactions) { final date = DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000); final monthYear = "${Constants.monthMap[date.month]} ${date.year}"; if (map[monthYear] == null) { - map[monthYear] = []; + map[monthYear] = + (label: monthYear, startDate: date, transactions: [tx]); + } else { + map[monthYear]!.transactions.add(tx); } - map[monthYear]!.add(tx); } - List<Tuple2<String, List<Transaction>>> result = []; - map.forEach((key, value) { - result.add(Tuple2(key, value)); - }); - - return result; + return map.values.toList() + ..sort((a, b) => b.startDate.compareTo(a.startDate)); } @override @@ -504,7 +509,7 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> { height: 12, ), Text( - month.item1, + month.label, style: STextStyles.smallMed12(context), ), const SizedBox( @@ -523,14 +528,15 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> { .extension<StackColors>()! .background, ), - itemCount: month.item2.length, + itemCount: month.transactions.length, itemBuilder: (context, index) => Padding( padding: const EdgeInsets.all(4), child: DesktopTransactionCardRow( key: Key( - "transactionCard_key_${month.item2[index].txid}"), - transaction: month.item2[index], + "transactionCard_key_${month.transactions[index].txid}"), + transaction: + month.transactions[index], walletId: walletId, ), ), @@ -541,7 +547,7 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> { padding: const EdgeInsets.all(0), child: Column( children: [ - ...month.item2.map( + ...month.transactions.map( (tx) => TransactionCard( key: Key( "transactionCard_key_${tx.txid}"), From a299ca1315aeb1e30b3f269708669dc3d1884606 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Oct 2023 13:29:46 -0600 Subject: [PATCH 338/379] all transactions v2 for bch --- .../blockchain_data/v2/transaction_v2.dart | 5 + .../tx_v2/all_transactions_v2_view.dart | 1022 +++++++++++++++++ .../wallet_view/desktop_wallet_view.dart | 50 +- lib/route_generator.dart | 15 + 4 files changed, 1069 insertions(+), 23 deletions(-) create mode 100644 lib/pages/wallet_view/transaction_views/tx_v2/all_transactions_v2_view.dart diff --git a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart index e03b777ae..c39c0cf11 100644 --- a/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart +++ b/lib/models/isar/models/blockchain_data/v2/transaction_v2.dart @@ -87,6 +87,11 @@ class TransactionV2 { return Amount(rawValue: inSum, fractionDigits: coin.decimals); } + Set<String> associatedAddresses() => { + ...inputs.map((e) => e.addresses).expand((e) => e), + ...outputs.map((e) => e.addresses).expand((e) => e), + }; + @override String toString() { return 'TransactionV2(\n' diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/all_transactions_v2_view.dart b/lib/pages/wallet_view/transaction_views/tx_v2/all_transactions_v2_view.dart new file mode 100644 index 000000000..1c5f2b361 --- /dev/null +++ b/lib/pages/wallet_view/transaction_views/tx_v2/all_transactions_v2_view.dart @@ -0,0 +1,1022 @@ +/* + * This file is part of Stack Wallet. + * + * Copyright (c) 2023 Cypher Stack + * All Rights Reserved. + * The code is distributed under GPLv3 license, see LICENSE file for details. + * Generated by Cypher Stack on 2023-05-26 + * + */ + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:isar/isar.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; +import 'package:stackwallet/models/isar/models/contact_entry.dart'; +import 'package:stackwallet/models/transaction_filter.dart'; +import 'package:stackwallet/pages/wallet_view/sub_widgets/tx_icon.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_search_filter_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart'; +import 'package:stackwallet/providers/db/main_db_provider.dart'; +import 'package:stackwallet/providers/global/address_book_service_provider.dart'; +import 'package:stackwallet/providers/providers.dart'; +import 'package:stackwallet/providers/ui/transaction_filter_provider.dart'; +import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/utilities/amount/amount.dart'; +import 'package:stackwallet/utilities/amount/amount_formatter.dart'; +import 'package:stackwallet/utilities/assets.dart'; +import 'package:stackwallet/utilities/constants.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; +import 'package:stackwallet/utilities/format.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; +import 'package:stackwallet/widgets/desktop/desktop_dialog.dart'; +import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; +import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; +import 'package:stackwallet/widgets/loading_indicator.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:stackwallet/widgets/stack_text_field.dart'; +import 'package:stackwallet/widgets/textfield_icon_button.dart'; + +typedef _GroupedTransactions = ({ + String label, + DateTime startDate, + List<TransactionV2> transactions +}); + +class AllTransactionsV2View extends ConsumerStatefulWidget { + const AllTransactionsV2View({ + Key? key, + required this.walletId, + }) : super(key: key); + + static const String routeName = "/allTransactionsV2"; + + final String walletId; + + @override + ConsumerState<AllTransactionsV2View> createState() => + _AllTransactionsV2ViewState(); +} + +class _AllTransactionsV2ViewState extends ConsumerState<AllTransactionsV2View> { + late final String walletId; + + late final TextEditingController _searchController; + final searchFieldFocusNode = FocusNode(); + + @override + void initState() { + walletId = widget.walletId; + _searchController = TextEditingController(); + + super.initState(); + } + + @override + void dispose() { + _searchController.dispose(); + searchFieldFocusNode.dispose(); + super.dispose(); + } + + // TODO: optimise search+filter + List<TransactionV2> filter( + {required List<TransactionV2> transactions, TransactionFilter? filter}) { + if (filter == null) { + return transactions; + } + + //todo: check if print needed + // debugPrint("FILTER: $filter"); + + final contacts = ref.read(addressBookServiceProvider).contacts; + final notes = + ref.read(notesServiceChangeNotifierProvider(walletId)).notesSync; + + return transactions.where((tx) { + if (!filter.sent && !filter.received) { + return false; + } + + if (filter.received && + !filter.sent && + tx.type == TransactionType.outgoing) { + return false; + } + + if (filter.sent && + !filter.received && + tx.type == TransactionType.incoming) { + return false; + } + + final date = DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000); + if ((filter.to != null && + date.millisecondsSinceEpoch > + filter.to!.millisecondsSinceEpoch) || + (filter.from != null && + date.millisecondsSinceEpoch < + filter.from!.millisecondsSinceEpoch)) { + return false; + } + + return _isKeywordMatch(tx, filter.keyword.toLowerCase(), contacts, notes); + }).toList(); + } + + bool _isKeywordMatch( + TransactionV2 tx, + String keyword, + List<ContactEntry> contacts, + Map<String, String> notes, + ) { + if (keyword.isEmpty) { + return true; + } + + bool contains = false; + + // check if address book name contains + contains |= contacts + .where((e) => + e.addresses + .map((e) => e.address) + .toSet() + .intersection(tx.associatedAddresses()) + .isNotEmpty && + e.name.toLowerCase().contains(keyword)) + .isNotEmpty; + + // check if address contains + contains |= tx + .associatedAddresses() + .where((e) => e.toLowerCase().contains(keyword)) + .isNotEmpty; + + // check if note contains + contains |= notes[tx.txid] != null && + notes[tx.txid]!.toLowerCase().contains(keyword); + + // check if txid contains + contains |= tx.txid.toLowerCase().contains(keyword); + + // check if subType contains + contains |= tx.subType.name.toLowerCase().contains(keyword); + + // check if txType contains + contains |= tx.type.name.toLowerCase().contains(keyword); + + // check if date contains + contains |= + Format.extractDateFrom(tx.timestamp).toLowerCase().contains(keyword); + + return contains; + } + + String _searchString = ""; + + // TODO search more tx fields + List<TransactionV2> search(String text, List<TransactionV2> transactions) { + if (text.isEmpty) { + return transactions; + } + text = text.toLowerCase(); + final contacts = ref.read(addressBookServiceProvider).contacts; + final notes = + ref.read(notesServiceChangeNotifierProvider(walletId)).notesSync; + + return transactions + .where((tx) => _isKeywordMatch(tx, text, contacts, notes)) + .toList(); + } + + List<_GroupedTransactions> groupTransactionsByMonth( + List<TransactionV2> transactions, + ) { + Map<String, _GroupedTransactions> map = {}; + + for (var tx in transactions) { + final date = DateTime.fromMillisecondsSinceEpoch(tx.timestamp * 1000); + final monthYear = "${Constants.monthMap[date.month]} ${date.year}"; + if (map[monthYear] == null) { + map[monthYear] = + (label: monthYear, startDate: date, transactions: [tx]); + } else { + map[monthYear]!.transactions.add(tx); + } + } + + return map.values.toList() + ..sort((a, b) => b.startDate.compareTo(a.startDate)); + } + + @override + Widget build(BuildContext context) { + final isDesktop = Util.isDesktop; + + return MasterScaffold( + background: Theme.of(context).extension<StackColors>()!.background, + isDesktop: isDesktop, + appBar: isDesktop + ? DesktopAppBar( + isCompactHeight: true, + background: Theme.of(context).extension<StackColors>()!.popupBG, + leading: Row( + children: [ + const SizedBox( + width: 32, + ), + AppBarIconButton( + size: 32, + color: Theme.of(context) + .extension<StackColors>()! + .textFieldDefaultBG, + shadows: const [], + icon: SvgPicture.asset( + Assets.svg.arrowLeft, + width: 18, + height: 18, + color: Theme.of(context) + .extension<StackColors>()! + .topNavIconPrimary, + ), + onPressed: Navigator.of(context).pop, + ), + const SizedBox( + width: 12, + ), + Text( + "Transactions", + style: STextStyles.desktopH3(context), + ), + ], + ), + ) + : AppBar( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + leading: AppBarBackButton( + onPressed: () async { + if (FocusScope.of(context).hasFocus) { + FocusScope.of(context).unfocus(); + await Future<void>.delayed( + const Duration(milliseconds: 75)); + } + if (mounted) { + Navigator.of(context).pop(); + } + }, + ), + title: Text( + "Transactions", + style: STextStyles.navBarTitle(context), + ), + actions: [ + Padding( + padding: const EdgeInsets.only( + top: 10, + bottom: 10, + right: 20, + ), + child: AspectRatio( + aspectRatio: 1, + child: AppBarIconButton( + key: const Key("transactionSearchFilterViewButton"), + size: 36, + shadows: const [], + color: Theme.of(context) + .extension<StackColors>()! + .background, + icon: SvgPicture.asset( + Assets.svg.filter, + color: Theme.of(context) + .extension<StackColors>()! + .accentColorDark, + width: 20, + height: 20, + ), + onPressed: () { + Navigator.of(context).pushNamed( + TransactionSearchFilterView.routeName, + arguments: ref + .read(walletsChangeNotifierProvider) + .getManager(walletId) + .coin, + ); + }, + ), + ), + ), + ], + ), + body: Padding( + padding: EdgeInsets.only( + left: isDesktop ? 20 : 12, + top: isDesktop ? 20 : 12, + right: isDesktop ? 20 : 12, + ), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(4), + child: Row( + children: [ + ConditionalParent( + condition: isDesktop, + builder: (child) => SizedBox( + width: 570, + child: child, + ), + child: ConditionalParent( + condition: !isDesktop, + builder: (child) => Expanded( + child: child, + ), + child: ClipRRect( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + child: TextField( + autocorrect: !isDesktop, + enableSuggestions: !isDesktop, + controller: _searchController, + focusNode: searchFieldFocusNode, + onChanged: (value) { + setState(() { + _searchString = value; + }); + }, + style: isDesktop + ? STextStyles.desktopTextExtraSmall(context) + .copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .textFieldActiveText, + height: 1.8, + ) + : STextStyles.field(context), + decoration: standardInputDecoration( + "Search...", + searchFieldFocusNode, + context, + desktopMed: isDesktop, + ).copyWith( + prefixIcon: Padding( + padding: EdgeInsets.symmetric( + horizontal: isDesktop ? 12 : 10, + vertical: isDesktop ? 18 : 16, + ), + child: SvgPicture.asset( + Assets.svg.search, + width: isDesktop ? 20 : 16, + height: isDesktop ? 20 : 16, + ), + ), + suffixIcon: _searchController.text.isNotEmpty + ? Padding( + padding: const EdgeInsets.only(right: 0), + child: UnconstrainedBox( + child: Row( + children: [ + TextFieldIconButton( + child: const XIcon(), + onTap: () async { + setState(() { + _searchController.text = ""; + _searchString = ""; + }); + }, + ), + ], + ), + ), + ) + : null, + ), + ), + ), + ), + ), + if (isDesktop) + const SizedBox( + width: 20, + ), + if (isDesktop) + SecondaryButton( + buttonHeight: ButtonHeight.l, + width: 200, + label: "Filter", + icon: SvgPicture.asset( + Assets.svg.filter, + color: Theme.of(context) + .extension<StackColors>()! + .accentColorDark, + width: 20, + height: 20, + ), + onPressed: () { + final coin = ref + .read(walletsChangeNotifierProvider) + .getManager(walletId) + .coin; + if (isDesktop) { + showDialog<void>( + context: context, + builder: (context) { + return TransactionSearchFilterView( + coin: coin, + ); + }, + ); + } else { + Navigator.of(context).pushNamed( + TransactionSearchFilterView.routeName, + arguments: coin, + ); + } + }, + ), + ], + ), + ), + if (isDesktop) + const SizedBox( + height: 8, + ), + if (isDesktop && + ref.watch(transactionFilterProvider.state).state != null) + const Padding( + padding: EdgeInsets.symmetric( + vertical: 8, + ), + child: Row( + children: [ + TransactionFilterOptionBar(), + ], + ), + ), + const SizedBox( + height: 8, + ), + Expanded( + child: Consumer( + builder: (_, ref, __) { + final managerProvider = ref.watch( + walletsChangeNotifierProvider.select( + (value) => value.getManagerProvider(walletId))); + + final criteria = + ref.watch(transactionFilterProvider.state).state; + + //todo: check if print needed + // debugPrint("Consumer build called"); + + return FutureBuilder( + future: ref + .watch(mainDBProvider) + .isar + .transactionV2s + .where() + .walletIdEqualTo(walletId) + .sortByTimestampDesc() + .findAll(), + builder: (_, AsyncSnapshot<List<TransactionV2>> snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + final filtered = filter( + transactions: snapshot.data!, filter: criteria); + + final searched = search(_searchString, filtered); + + final monthlyList = groupTransactionsByMonth(searched); + return ListView.builder( + primary: isDesktop ? false : null, + itemCount: monthlyList.length, + itemBuilder: (_, index) { + final month = monthlyList[index]; + return Padding( + padding: const EdgeInsets.all(4), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (index != 0) + const SizedBox( + height: 12, + ), + Text( + month.label, + style: STextStyles.smallMed12(context), + ), + const SizedBox( + height: 12, + ), + if (isDesktop) + RoundedWhiteContainer( + padding: const EdgeInsets.all(0), + child: ListView.separated( + shrinkWrap: true, + primary: false, + separatorBuilder: (context, _) => + Container( + height: 1, + color: Theme.of(context) + .extension<StackColors>()! + .background, + ), + itemCount: month.transactions.length, + itemBuilder: (context, index) => + Padding( + padding: const EdgeInsets.all(4), + child: DesktopTransactionCardRow( + key: Key( + "transactionCard_key_${month.transactions[index].txid}"), + transaction: + month.transactions[index], + walletId: walletId, + ), + ), + ), + ), + if (!isDesktop) + RoundedWhiteContainer( + padding: const EdgeInsets.all(0), + child: Column( + children: [ + ...month.transactions.map( + (tx) => TransactionCardV2( + key: Key( + "transactionCard_key_${tx.txid}"), + transaction: tx, + ), + ), + ], + ), + ), + ], + ), + ); + }, + ); + } else { + // TODO: proper loading indicator + return const LoadingIndicator(); + } + }, + ); + }, + ), + ), + ], + ), + ), + ); + } +} + +class TransactionFilterOptionBar extends ConsumerStatefulWidget { + const TransactionFilterOptionBar({Key? key}) : super(key: key); + + @override + ConsumerState<TransactionFilterOptionBar> createState() => + _TransactionFilterOptionBarState(); +} + +class _TransactionFilterOptionBarState + extends ConsumerState<TransactionFilterOptionBar> { + final List<TransactionFilterOptionBarItem> items = []; + TransactionFilter? _filter; + + @override + void initState() { + _filter = ref.read(transactionFilterProvider.state).state; + + if (_filter != null) { + if (_filter!.sent) { + const label = "Sent"; + final item = TransactionFilterOptionBarItem( + label: label, + onPressed: (s) { + items.removeWhere((e) => e.label == label); + if (items.isEmpty) { + ref.read(transactionFilterProvider.state).state = null; + } else { + ref.read(transactionFilterProvider.state).state = + ref.read(transactionFilterProvider.state).state?.copyWith( + sent: false, + ); + setState(() {}); + } + }, + ); + items.add(item); + } + if (_filter!.received) { + const label = ("Received"); + final item = TransactionFilterOptionBarItem( + label: label, + onPressed: (s) { + items.removeWhere((e) => e.label == label); + if (items.isEmpty) { + ref.read(transactionFilterProvider.state).state = null; + } else { + ref.read(transactionFilterProvider.state).state = + ref.read(transactionFilterProvider.state).state?.copyWith( + received: false, + ); + setState(() {}); + } + }, + ); + items.add(item); + } + + if (_filter!.to != null) { + final label = _filter!.from.toString(); + final item = TransactionFilterOptionBarItem( + label: label, + onPressed: (s) { + items.removeWhere((e) => e.label == label); + if (items.isEmpty) { + ref.read(transactionFilterProvider.state).state = null; + } else { + ref.read(transactionFilterProvider.state).state = + ref.read(transactionFilterProvider.state).state?.copyWith( + to: null, + ); + setState(() {}); + } + }, + ); + items.add(item); + } + if (_filter!.from != null) { + final label2 = _filter!.to.toString(); + final item2 = TransactionFilterOptionBarItem( + label: label2, + onPressed: (s) { + items.removeWhere((e) => e.label == label2); + if (items.isEmpty) { + ref.read(transactionFilterProvider.state).state = null; + } else { + ref.read(transactionFilterProvider.state).state = + ref.read(transactionFilterProvider.state).state?.copyWith( + from: null, + ); + setState(() {}); + } + }, + ); + items.add(item2); + } + + if (_filter!.amount != null) { + final label = _filter!.amount!.toString(); + final item = TransactionFilterOptionBarItem( + label: label, + onPressed: (s) { + items.removeWhere((e) => e.label == label); + if (items.isEmpty) { + ref.read(transactionFilterProvider.state).state = null; + } else { + ref.read(transactionFilterProvider.state).state = + ref.read(transactionFilterProvider.state).state?.copyWith( + amount: null, + ); + setState(() {}); + } + }, + ); + items.add(item); + } + if (_filter!.keyword.isNotEmpty) { + final label = _filter!.keyword; + final item = TransactionFilterOptionBarItem( + label: label, + onPressed: (s) { + items.removeWhere((e) => e.label == label); + if (items.isEmpty) { + ref.read(transactionFilterProvider.state).state = null; + } else { + ref.read(transactionFilterProvider.state).state = + ref.read(transactionFilterProvider.state).state?.copyWith( + keyword: "", + ); + setState(() {}); + } + }, + ); + items.add(item); + } + } + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 32, + child: ListView.separated( + primary: false, + scrollDirection: Axis.horizontal, + shrinkWrap: true, + itemCount: items.length, + separatorBuilder: (_, __) => const SizedBox( + width: 16, + ), + itemBuilder: (context, index) => items[index], + ), + ); + } +} + +class TransactionFilterOptionBarItem extends StatelessWidget { + const TransactionFilterOptionBarItem({ + Key? key, + required this.label, + this.onPressed, + }) : super(key: key); + + final String label; + final void Function(String)? onPressed; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () => onPressed?.call(label), + child: Container( + height: 32, + decoration: BoxDecoration( + color: + Theme.of(context).extension<StackColors>()!.buttonBackSecondary, + borderRadius: BorderRadius.circular(1000)), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 14, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Center( + child: Padding( + padding: const EdgeInsets.only(top: 2), + child: Text( + label, + textAlign: TextAlign.center, + style: STextStyles.labelExtraExtraSmall(context).copyWith( + color: + Theme.of(context).extension<StackColors>()!.textDark, + ), + ), + ), + ), + const SizedBox( + width: 10, + ), + XIcon( + width: 16, + height: 16, + color: Theme.of(context).extension<StackColors>()!.textDark, + ), + ], + ), + ), + ), + ); + } +} + +class DesktopTransactionCardRow extends ConsumerStatefulWidget { + const DesktopTransactionCardRow({ + Key? key, + required this.transaction, + required this.walletId, + }) : super(key: key); + + final TransactionV2 transaction; + final String walletId; + + @override + ConsumerState<DesktopTransactionCardRow> createState() => + _DesktopTransactionCardRowState(); +} + +class _DesktopTransactionCardRowState + extends ConsumerState<DesktopTransactionCardRow> { + late final TransactionV2 _transaction; + late final String walletId; + + String whatIsIt(TransactionType type, Coin coin, int height) { + if (_transaction.subType == TransactionSubType.mint || + _transaction.subType == TransactionSubType.cashFusion) { + if (_transaction.isConfirmed(height, coin.requiredConfirmations)) { + return "Anonymized"; + } else { + return "Anonymizing"; + } + } + + if (type == TransactionType.incoming) { + if (_transaction.isConfirmed(height, coin.requiredConfirmations)) { + return "Received"; + } else { + return "Receiving"; + } + } else if (type == TransactionType.outgoing) { + if (_transaction.isConfirmed(height, coin.requiredConfirmations)) { + return "Sent"; + } else { + return "Sending"; + } + } else if (type == TransactionType.sentToSelf) { + return "Sent to self"; + } else { + return type.name; + } + } + + @override + void initState() { + walletId = widget.walletId; + _transaction = widget.transaction; + super.initState(); + } + + @override + Widget build(BuildContext context) { + final locale = ref.watch( + localeServiceChangeNotifierProvider.select((value) => value.locale)); + final manager = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId))); + + final baseCurrency = ref + .watch(prefsChangeNotifierProvider.select((value) => value.currency)); + + final coin = manager.coin; + + final price = ref + .watch(priceAnd24hChangeNotifierProvider + .select((value) => value.getPrice(coin))) + .item1; + + late final String prefix; + if (Util.isDesktop) { + if (_transaction.type == TransactionType.outgoing) { + prefix = "-"; + } else if (_transaction.type == TransactionType.incoming) { + prefix = "+"; + } else { + prefix = ""; + } + } else { + prefix = ""; + } + + final currentHeight = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(walletId).currentHeight)); + + final Amount amount; + + if (_transaction.subType == TransactionSubType.cashFusion) { + amount = _transaction.getAmountReceivedThisWallet(coin: coin); + } else { + switch (_transaction.type) { + case TransactionType.outgoing: + amount = _transaction.getAmountSentFromThisWallet(coin: coin); + break; + + case TransactionType.incoming: + case TransactionType.sentToSelf: + amount = _transaction.getAmountReceivedThisWallet(coin: coin); + break; + + case TransactionType.unknown: + amount = _transaction.getAmountSentFromThisWallet(coin: coin); + break; + } + } + + return Material( + color: Theme.of(context).extension<StackColors>()!.popupBG, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(Constants.size.circularBorderRadius), + ), + child: RawMaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, + ), + ), + onPressed: () async { + if (Util.isDesktop) { + await showDialog<void>( + context: context, + builder: (context) => DesktopDialog( + maxHeight: MediaQuery.of(context).size.height - 64, + maxWidth: 580, + child: TransactionV2DetailsView( + transaction: _transaction, + coin: coin, + walletId: walletId, + ), + ), + ); + } else { + unawaited( + Navigator.of(context).pushNamed( + TransactionV2DetailsView.routeName, + arguments: ( + tx: _transaction, + coin: coin, + walletId: walletId, + ), + ), + ); + } + }, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 10, + horizontal: 16, + ), + child: Row( + children: [ + TxIcon( + transaction: _transaction, + currentHeight: currentHeight, + coin: coin, + ), + const SizedBox( + width: 12, + ), + Expanded( + flex: 3, + child: Text( + whatIsIt( + _transaction.type, + coin, + currentHeight, + ), + style: + STextStyles.desktopTextExtraExtraSmall(context).copyWith( + color: Theme.of(context).extension<StackColors>()!.textDark, + ), + ), + ), + Expanded( + flex: 4, + child: Text( + Format.extractDateFrom(_transaction.timestamp), + style: STextStyles.label(context), + ), + ), + Expanded( + flex: 6, + child: Text( + "$prefix${ref.watch(pAmountFormatter(coin)).format(amount)}", + style: + STextStyles.desktopTextExtraExtraSmall(context).copyWith( + color: Theme.of(context).extension<StackColors>()!.textDark, + ), + ), + ), + if (ref.watch(prefsChangeNotifierProvider + .select((value) => value.externalCalls))) + Expanded( + flex: 4, + child: Text( + "$prefix${(amount.decimal * price).toAmount( + fractionDigits: 2, + ).fiatString( + locale: locale, + )} $baseCurrency", + style: STextStyles.desktopTextExtraExtraSmall(context), + ), + ), + SvgPicture.asset( + Assets.svg.circleInfo, + width: 20, + height: 20, + color: + Theme.of(context).extension<StackColors>()!.textSubtitle2, + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart index 26e066ad9..466a900ef 100644 --- a/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart +++ b/lib/pages_desktop_specific/my_stack_view/wallet_view/desktop_wallet_view.dart @@ -21,6 +21,7 @@ import 'package:stackwallet/pages/special/firo_rescan_recovery_error_dialog.dart import 'package:stackwallet/pages/token_view/my_tokens_view.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/transactions_list.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/all_transactions_v2_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_features.dart'; import 'package:stackwallet/pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_wallet_summary.dart'; @@ -461,30 +462,33 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> { .hasTokenSupport)) ? "Edit" : "See all", - onTap: ref.watch(walletsChangeNotifierProvider.select( - (value) => value - .getManager(widget.walletId) - .hasTokenSupport)) - ? () async { - final result = await showDialog<int?>( - context: context, - builder: (context) => EditWalletTokensView( - walletId: widget.walletId, - isDesktopPopup: true, - ), - ); + onTap: () async { + if (ref + .read(walletsChangeNotifierProvider) + .getManager(widget.walletId) + .hasTokenSupport) { + final result = await showDialog<int?>( + context: context, + builder: (context) => EditWalletTokensView( + walletId: widget.walletId, + isDesktopPopup: true, + ), + ); - if (result == 42) { - // wallet tokens were edited so update ui - setState(() {}); - } - } - : () { - Navigator.of(context).pushNamed( - AllTransactionsView.routeName, - arguments: widget.walletId, - ); - }, + if (result == 42) { + // wallet tokens were edited so update ui + setState(() {}); + } + } else { + await Navigator.of(context).pushNamed( + coin == Coin.bitcoincash || + coin == Coin.bitcoincashTestnet + ? AllTransactionsV2View.routeName + : AllTransactionsView.routeName, + arguments: widget.walletId, + ); + } + }, ), ], ), diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 7978d6d8d..3c02b7cbf 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -132,6 +132,7 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions import 'package:stackwallet/pages/wallet_view/transaction_views/edit_note_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_search_filter_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/all_transactions_v2_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart'; import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; @@ -1324,6 +1325,20 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case AllTransactionsV2View.routeName: + if (args is String) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => AllTransactionsV2View( + walletId: args, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case TransactionSearchFilterView.routeName: if (args is Coin) { return getRoute( From 968f02819927f5f59f35e6254f2e26fac84087c3 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Oct 2023 15:05:50 -0600 Subject: [PATCH 339/379] fusion tx ui fixes for mobile --- .../tx_v2/fusion_group_details_view.dart | 244 ++++++++---------- lib/pages/wallet_view/wallet_view.dart | 23 +- 2 files changed, 120 insertions(+), 147 deletions(-) diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart b/lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart index 5b9ded00e..874d1fdba 100644 --- a/lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/tx_v2/fusion_group_details_view.dart @@ -12,14 +12,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list_item.dart'; -import 'package:stackwallet/pages/wallet_view/wallet_view.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/background.dart'; -import 'package:stackwallet/widgets/conditional_parent.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart'; @@ -80,147 +78,66 @@ class _FusionGroupDetailsViewState @override Widget build(BuildContext context) { - return ConditionalParent( - condition: !isDesktop, - builder: (child) => Background( - child: child, - ), - child: Scaffold( - backgroundColor: isDesktop - ? Colors.transparent - : Theme.of(context).extension<StackColors>()!.background, - appBar: isDesktop - ? null - : AppBar( - backgroundColor: - Theme.of(context).extension<StackColors>()!.background, - leading: AppBarBackButton( - onPressed: () async { - Navigator.of(context).pop(); - }, - ), - title: Text( - "Fusion transactions", - style: STextStyles.navBarTitle(context), - ), - ), - body: Padding( - padding: isDesktop - ? const EdgeInsets.only(left: 32) - : const EdgeInsets.all(12), + if (isDesktop) { + return Material( + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.only(left: 32), child: Column( children: [ - if (isDesktop) - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Fusion transactions", - style: STextStyles.desktopH3(context), - ), - const DesktopDialogCloseButton(), - ], - ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Fusion transactions", + style: STextStyles.desktopH3(context), + ), + const DesktopDialogCloseButton(), + ], + ), Flexible( child: Padding( - padding: isDesktop - ? const EdgeInsets.only( - right: 32, - bottom: 32, - ) - : const EdgeInsets.all(0), - child: ConditionalParent( - condition: isDesktop, - builder: (child) { - return RoundedWhiteContainer( - borderColor: isDesktop - ? Theme.of(context) - .extension<StackColors>()! - .backgroundAppBar - : null, - padding: const EdgeInsets.all(0), - child: child, - ); - }, - child: SingleChildScrollView( - primary: isDesktop ? false : null, - child: Padding( - padding: isDesktop - ? const EdgeInsets.all(0) - : const EdgeInsets.all(4), - child: Util.isDesktop - ? ListView.separated( - shrinkWrap: true, - itemBuilder: (context, index) { - BorderRadius? radius; - if (widget.transactions.length == 1) { - radius = BorderRadius.circular( - Constants.size.circularBorderRadius, - ); - } else if (index == - widget.transactions.length - 1) { - radius = _borderRadiusLast; - } else if (index == 0) { - radius = _borderRadiusFirst; - } - final tx = widget.transactions[index]; - return TxListItem( - tx: tx, - coin: widget.coin, - radius: radius, - ); - }, - separatorBuilder: (context, index) { - return Container( - width: double.infinity, - height: 1.2, - color: Theme.of(context) - .extension<StackColors>()! - .background, - ); - }, - itemCount: widget.transactions.length, - ) - : ListView.builder( - itemCount: widget.transactions.length, - itemBuilder: (context, index) { - BorderRadius? radius; - bool shouldWrap = false; - if (widget.transactions.length == 1) { - radius = BorderRadius.circular( - Constants.size.circularBorderRadius, - ); - } else if (index == - widget.transactions.length - 1) { - radius = _borderRadiusLast; - shouldWrap = true; - } else if (index == 0) { - radius = _borderRadiusFirst; - } - final tx = widget.transactions[index]; - if (shouldWrap) { - return Column( - children: [ - TxListItem( - tx: tx, - coin: widget.coin, - radius: radius, - ), - const SizedBox( - height: WalletView.navBarHeight + 14, - ), - ], - ); - } else { - return TxListItem( - tx: tx, - coin: widget.coin, - radius: radius, - ); - } - }, - ), - ), + padding: const EdgeInsets.only( + right: 32, + bottom: 32, + ), + child: RoundedWhiteContainer( + borderColor: isDesktop + ? Theme.of(context) + .extension<StackColors>()! + .backgroundAppBar + : null, + padding: const EdgeInsets.all(0), + child: ListView.separated( + shrinkWrap: true, + itemBuilder: (context, index) { + BorderRadius? radius; + if (widget.transactions.length == 1) { + radius = BorderRadius.circular( + Constants.size.circularBorderRadius, + ); + } else if (index == widget.transactions.length - 1) { + radius = _borderRadiusLast; + } else if (index == 0) { + radius = _borderRadiusFirst; + } + final tx = widget.transactions[index]; + return TxListItem( + tx: tx, + coin: widget.coin, + radius: radius, + ); + }, + separatorBuilder: (context, index) { + return Container( + width: double.infinity, + height: 1.2, + color: Theme.of(context) + .extension<StackColors>()! + .background, + ); + }, + itemCount: widget.transactions.length, ), ), ), @@ -228,7 +145,52 @@ class _FusionGroupDetailsViewState ], ), ), - ), - ); + ); + } else { + return Background( + child: Scaffold( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + appBar: AppBar( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + leading: AppBarBackButton( + onPressed: () async { + Navigator.of(context).pop(); + }, + ), + title: Text( + "Fusion transactions", + style: STextStyles.navBarTitle(context), + ), + ), + body: Padding( + padding: const EdgeInsets.all(16), + child: ListView.builder( + itemCount: widget.transactions.length, + itemBuilder: (context, index) { + BorderRadius? radius; + if (widget.transactions.length == 1) { + radius = BorderRadius.circular( + Constants.size.circularBorderRadius, + ); + } else if (index == widget.transactions.length - 1) { + radius = _borderRadiusLast; + } else if (index == 0) { + radius = _borderRadiusFirst; + } + final tx = widget.transactions[index]; + + return TxListItem( + tx: tx, + coin: widget.coin, + radius: radius, + ); + }, + ), + ), + ), + ); + } } } diff --git a/lib/pages/wallet_view/wallet_view.dart b/lib/pages/wallet_view/wallet_view.dart index e38a38cdd..34456cebd 100644 --- a/lib/pages/wallet_view/wallet_view.dart +++ b/lib/pages/wallet_view/wallet_view.dart @@ -37,6 +37,8 @@ import 'package:stackwallet/pages/token_view/my_tokens_view.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/transactions_list.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/wallet_summary.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/all_transactions_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/all_transactions_v2_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_list.dart'; import 'package:stackwallet/providers/global/auto_swb_service_provider.dart'; import 'package:stackwallet/providers/global/paynym_api_provider.dart'; import 'package:stackwallet/providers/providers.dart'; @@ -842,7 +844,10 @@ class _WalletViewState extends ConsumerState<WalletView> { text: "See all", onTap: () { Navigator.of(context).pushNamed( - AllTransactionsView.routeName, + coin == Coin.bitcoincash || + coin == Coin.bitcoincashTestnet + ? AllTransactionsV2View.routeName + : AllTransactionsView.routeName, arguments: walletId, ); }, @@ -881,7 +886,7 @@ class _WalletViewState extends ConsumerState<WalletView> { 0.0, 0.8, 1.0, - ], // 10% purple, 80% transparent, 10% purple + ], ).createShader(bounds); }, child: Container( @@ -896,10 +901,16 @@ class _WalletViewState extends ConsumerState<WalletView> { CrossAxisAlignment.stretch, children: [ Expanded( - child: TransactionsList( - managerProvider: managerProvider, - walletId: walletId, - ), + child: coin == Coin.bitcoincash || + coin == Coin.bitcoincashTestnet + ? TransactionsV2List( + walletId: widget.walletId, + ) + : TransactionsList( + managerProvider: + managerProvider, + walletId: walletId, + ), ), ], ), From 61dbc3a0e4f765a93037550c538d44e00715ba94 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 23 Oct 2023 16:11:42 -0500 Subject: [PATCH 340/379] mobile expanded fix and fusiondart pub ref update fusiondart pub ref update is just to remove some outdated comments. --- fusiondart | 2 +- .../cashfusion/fusion_progress_view.dart | 54 +++++++++---------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/fusiondart b/fusiondart index 3cc986173..411c3f9b5 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 3cc9861738e94f4c24fc17f272c0bf2be49a5ee7 +Subproject commit 411c3f9b58189690fca3475a7558e11ddc7821be diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 562ab5c22..815e47ad5 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -137,42 +137,38 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { child: Padding( padding: const EdgeInsets.all(16), child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ if (_fusionRoundsCompleted == 0) - Expanded( - child: RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackError, - child: Text( - "Do not close this window. If you exit, " - "the process will be canceled.", - style: STextStyles.smallMed14(context) - .copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextError, - ), - textAlign: TextAlign.center, + RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackError, + child: Text( + "Do not close this window. If you exit, " + "the process will be canceled.", + style: + STextStyles.smallMed14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextError, ), + textAlign: TextAlign.center, ), ), if (_fusionRoundsCompleted > 0) - Expanded( - child: RoundedContainer( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarBackInfo, - child: Text( - "Fusion rounds completed: $_fusionRoundsCompleted", - style: - STextStyles.w500_14(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .snackBarTextInfo, - ), - textAlign: TextAlign.center, + RoundedContainer( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarBackInfo, + child: Text( + "Fusion rounds completed: $_fusionRoundsCompleted", + style: STextStyles.w500_14(context).copyWith( + color: Theme.of(context) + .extension<StackColors>()! + .snackBarTextInfo, ), + textAlign: TextAlign.center, ), ), const SizedBox( From 762757f694db63c697491c39dec87a27767465d7 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 23 Oct 2023 16:46:15 -0500 Subject: [PATCH 341/379] remove checkCoins --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 411c3f9b5..191907225 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 411c3f9b58189690fca3475a7558e11ddc7821be +Subproject commit 191907225c411e0aa68fa0636a7b91976318753e From bfbcaea4c58fab2a88d3116f8816e7f651ef1128 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 23 Oct 2023 16:47:08 -0500 Subject: [PATCH 342/379] fix mobile button height --- lib/pages/cashfusion/fusion_progress_view.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 815e47ad5..cf02963a6 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -51,14 +51,14 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { title: "Cancel fusion?", leftButton: SecondaryButton( label: "No", - buttonHeight: ButtonHeight.l, + buttonHeight: null, onPressed: () { Navigator.of(context).pop(false); }, ), rightButton: PrimaryButton( label: "Yes", - buttonHeight: ButtonHeight.l, + buttonHeight: null, onPressed: () { Navigator.of(context).pop(true); }, From 98ce0950236ab5a4d0e436603661173154292e21 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 23 Oct 2023 16:49:56 -0500 Subject: [PATCH 343/379] fix to catch openConnection issues --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 191907225..3e189ea76 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 191907225c411e0aa68fa0636a7b91976318753e +Subproject commit 3e189ea764087e61ee7a5d025362c63195e27761 From 9ac429c6cdc0106cb32e345e8d9411ec2f120cae Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Mon, 23 Oct 2023 16:59:59 -0500 Subject: [PATCH 344/379] rethrow in greet try-catch --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 3e189ea76..7e4099289 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 3e189ea764087e61ee7a5d025362c63195e27761 +Subproject commit 7e4099289fc8c86594bbe7c737ce8804e7638d8d From bb0511d468f4e52f7c0bc14c5e03f3cdab6e4b62 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 23 Oct 2023 16:20:42 -0600 Subject: [PATCH 345/379] look up v2 txns by address --- .../addresses/address_details_view.dart | 95 +++++++++++++++++-- 1 file changed, 87 insertions(+), 8 deletions(-) diff --git a/lib/pages/receive_view/addresses/address_details_view.dart b/lib/pages/receive_view/addresses/address_details_view.dart index 75d41b073..fa8b02617 100644 --- a/lib/pages/receive_view/addresses/address_details_view.dart +++ b/lib/pages/receive_view/addresses/address_details_view.dart @@ -13,13 +13,19 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:isar/isar.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:stackwallet/db/isar/main_db.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/input_v2.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/output_v2.dart'; +import 'package:stackwallet/models/isar/models/blockchain_data/v2/transaction_v2.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/pages/receive_view/addresses/address_tag.dart'; import 'package:stackwallet/pages/wallet_view/sub_widgets/no_transactions_found.dart'; import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_card.dart'; +import 'package:stackwallet/providers/db/main_db_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/address_utils.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/background.dart'; @@ -145,6 +151,8 @@ class _AddressDetailsViewState extends ConsumerState<AddressDetailsView> { @override Widget build(BuildContext context) { + final coin = ref.watch(walletsChangeNotifierProvider + .select((value) => value.getManager(widget.walletId).coin)); return ConditionalParent( condition: !isDesktop, builder: (child) => Background( @@ -258,10 +266,16 @@ class _AddressDetailsViewState extends ConsumerState<AddressDetailsView> { borderColor: Theme.of(context) .extension<StackColors>()! .backgroundAppBar, - child: _AddressDetailsTxList( - walletId: widget.walletId, - address: address, - ), + child: coin == Coin.bitcoincash || + coin == Coin.bitcoincashTestnet + ? _AddressDetailsTxV2List( + walletId: widget.walletId, + address: address, + ) + : _AddressDetailsTxList( + walletId: widget.walletId, + address: address, + ), ), ], ), @@ -377,10 +391,15 @@ class _AddressDetailsViewState extends ConsumerState<AddressDetailsView> { height: 12, ), if (!isDesktop) - _AddressDetailsTxList( - walletId: widget.walletId, - address: address, - ), + coin == Coin.bitcoincash || coin == Coin.bitcoincashTestnet + ? _AddressDetailsTxV2List( + walletId: widget.walletId, + address: address, + ) + : _AddressDetailsTxList( + walletId: widget.walletId, + address: address, + ), ], ), ); @@ -445,6 +464,66 @@ class _AddressDetailsTxList extends StatelessWidget { } } +class _AddressDetailsTxV2List extends ConsumerWidget { + const _AddressDetailsTxV2List({ + Key? key, + required this.walletId, + required this.address, + }) : super(key: key); + + final String walletId; + final Address address; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final query = ref + .watch(mainDBProvider) + .isar + .transactionV2s + .where() + .walletIdEqualTo(walletId) + .filter() + .inputsElement((q) => q.addressesElementContains(address.value)) + .or() + .outputsElement((q) => q.addressesElementContains(address.value)) + .sortByTimestampDesc(); + + final count = query.countSync(); + + if (count > 0) { + if (Util.isDesktop) { + final txns = query.findAllSync(); + return ListView.separated( + shrinkWrap: true, + primary: false, + itemBuilder: (_, index) => TransactionCardV2( + transaction: txns[index], + ), + separatorBuilder: (_, __) => const _Div(height: 1), + itemCount: count, + ); + } else { + return RoundedWhiteContainer( + padding: EdgeInsets.zero, + child: Column( + mainAxisSize: MainAxisSize.min, + children: query + .findAllSync() + .map( + (e) => TransactionCardV2( + transaction: e, + ), + ) + .toList(), + ), + ); + } + } else { + return const NoTransActionsFound(); + } + } +} + class _Div extends StatelessWidget { const _Div({ Key? key, From 3e767f77781820d6dcb0baade4ebe93014d1fdd6 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 24 Oct 2023 08:34:07 -0600 Subject: [PATCH 346/379] clean up tx details w/ more than one output address displayed --- .../tx_v2/transaction_v2_details_view.dart | 253 ++++++++++++------ 1 file changed, 173 insertions(+), 80 deletions(-) diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart index ffe732a24..5c313ea81 100644 --- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart @@ -400,6 +400,20 @@ class _TransactionV2DetailsViewState final currentHeight = ref.watch(walletsChangeNotifierProvider .select((value) => value.getManager(walletId).currentHeight)); + final String outputLabel; + + if (_transaction.subType == TransactionSubType.cashFusion) { + outputLabel = "Outputs"; + } else if (_transaction.type == TransactionType.incoming) { + if (data.length == 1 && data.first.addresses.length == 1) { + outputLabel = "Receiving address"; + } else { + outputLabel = "Receiving addresses"; + } + } else { + outputLabel = "Sent to"; + } + return ConditionalParent( condition: !isDesktop, builder: (child) => Background( @@ -626,8 +640,11 @@ class _TransactionV2DetailsViewState context) .copyWith( color: _transaction.type == - TransactionType.outgoing && _transaction.subType != - TransactionSubType.cashFusion + TransactionType + .outgoing && + _transaction.subType != + TransactionSubType + .cashFusion ? Theme.of(context) .extension<StackColors>()! .accentColorOrange @@ -731,10 +748,7 @@ class _TransactionV2DetailsViewState ); }, child: Text( - _transaction.type == - TransactionType.outgoing - ? "Sent to" - : "Received at", + outputLabel, style: isDesktop ? STextStyles .desktopTextExtraExtraSmall( @@ -750,82 +764,102 @@ class _TransactionV2DetailsViewState crossAxisAlignment: CrossAxisAlignment.start, children: [ - ...data.map( - (e) { - return Padding( - padding: - const EdgeInsets.all( - 8.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - ...e.addresses.map( - (e) { - return FutureBuilder( - future: - fetchContactNameFor( - e), - builder: (builderContext, - AsyncSnapshot< - String> - snapshot) { - final String - addressOrContactName; - if (snapshot.connectionState == - ConnectionState - .done && - snapshot - .hasData) { - addressOrContactName = + if (data.length == 1 && + data.first.addresses.length == + 1) + FutureBuilder( + future: fetchContactNameFor( + data.first.addresses + .first), + builder: (builderContext, + AsyncSnapshot<String> + snapshot) { + String + addressOrContactName = + data.first.addresses + .first; + if (snapshot.connectionState == + ConnectionState + .done && + snapshot.hasData) { + addressOrContactName = + snapshot.data!; + } + return SelectableText( + addressOrContactName, + style: isDesktop + ? STextStyles + .desktopTextExtraExtraSmall( + context) + .copyWith( + color: Theme.of( + context) + .extension< + StackColors>()! + .textDark, + ) + : STextStyles + .itemSubtitle12( + context), + ); + }, + ), + if (!(data.length == 1 && + data.first.addresses.length == + 1)) + ...data.map( + (group) { + return Padding( + padding: + const EdgeInsets.all( + 8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + ...group.addresses + .map( + (e) { + return FutureBuilder( + future: + fetchContactNameFor( + e), + builder: (builderContext, + AsyncSnapshot< + String> + snapshot) { + final String + addressOrContactName; + if (snapshot.connectionState == + ConnectionState + .done && snapshot - .data!; - } else { - addressOrContactName = - e; - } + .hasData) { + addressOrContactName = + snapshot + .data!; + } else { + addressOrContactName = + e; + } - return SelectableText( - addressOrContactName, - style: isDesktop - ? STextStyles.desktopTextExtraExtraSmall(context).copyWith( - color: Theme.of(context) - .extension<StackColors>()! - .textDark, - ) - : STextStyles.itemSubtitle12(context), - ); - }, - ); - }, - ), - SelectableText( - ref - .watch( - pAmountFormatter( - coin)) - .format(e.amount), - style: isDesktop - ? STextStyles - .desktopTextExtraExtraSmall( - context) - .copyWith( - color: Theme.of( - context) - .extension< - StackColors>()! - .textDark, - ) - : STextStyles - .titleBold12( - context), - ), - ], - ), - ); - }, - ), + return OutputCard( + address: + addressOrContactName, + amount: group + .amount, + coin: coin, + ); + }, + ); + }, + ), + ], + ), + ); + }, + ), ], ), ], @@ -1479,6 +1513,65 @@ class _TransactionV2DetailsViewState } } +class OutputCard extends ConsumerWidget { + const OutputCard({ + super.key, + required this.address, + required this.amount, + required this.coin, + }); + + final String address; + final Amount amount; + final Coin coin; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Address", + style: Util.isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context) + : STextStyles.itemSubtitle(context), + ), + SelectableText( + address, + style: Util.isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context).copyWith( + color: Theme.of(context).extension<StackColors>()!.textDark, + ) + : STextStyles.itemSubtitle12(context), + ), + const SizedBox( + height: 10, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Amount", + style: Util.isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context) + : STextStyles.itemSubtitle(context), + ), + SelectableText( + ref.watch(pAmountFormatter(coin)).format(amount), + style: Util.isDesktop + ? STextStyles.desktopTextExtraExtraSmall(context).copyWith( + color: + Theme.of(context).extension<StackColors>()!.textDark, + ) + : STextStyles.itemSubtitle12(context), + ), + ], + ) + ], + ); + } +} + class _Divider extends StatelessWidget { const _Divider({Key? key}) : super(key: key); From d041d9a9ec9dc9f154acbc1a3ce9626788816bab Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 24 Oct 2023 12:28:09 -0600 Subject: [PATCH 347/379] performance fix --- .../sub_widgets/desktop_address_list.dart | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/lib/pages_desktop_specific/addresses/sub_widgets/desktop_address_list.dart b/lib/pages_desktop_specific/addresses/sub_widgets/desktop_address_list.dart index f0b4836f8..62645f858 100644 --- a/lib/pages_desktop_specific/addresses/sub_widgets/desktop_address_list.dart +++ b/lib/pages_desktop_specific/addresses/sub_widgets/desktop_address_list.dart @@ -210,30 +210,27 @@ class _DesktopAddressListState extends ConsumerState<DesktopAddressList> { height: 20, ), Expanded( - child: SingleChildScrollView( - child: RoundedWhiteContainer( - padding: EdgeInsets.zero, - child: ListView.separated( - shrinkWrap: true, - itemCount: ids.length, - separatorBuilder: (_, __) => Container( - height: 1, - color: Theme.of(context) - .extension<StackColors>()! - .backgroundAppBar, - ), - itemBuilder: (_, index) => Padding( - padding: const EdgeInsets.all(4), - child: AddressCard( - key: Key("addressCardDesktop_key_${ids[index]}"), - walletId: widget.walletId, - addressId: ids[index], - coin: coin, - onPressed: () { - ref.read(desktopSelectedAddressId.state).state = - ids[index]; - }, - ), + child: RoundedWhiteContainer( + padding: EdgeInsets.zero, + child: ListView.separated( + shrinkWrap: true, + itemCount: ids.length, + separatorBuilder: (_, __) => Container( + height: 1, + color: Theme.of(context) + .extension<StackColors>()! + .backgroundAppBar, + ), + itemBuilder: (_, index) => Padding( + padding: const EdgeInsets.all(4), + child: AddressCard( + key: Key("addressCardDesktop_key_${ids[index]}"), + walletId: widget.walletId, + addressId: ids[index], + coin: coin, + onPressed: () { + ref.read(desktopSelectedAddressId.state).state = ids[index]; + }, ), ), ), From ae68a85937aab02d78d69511a3d02a44a404d213 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 24 Oct 2023 13:59:09 -0500 Subject: [PATCH 348/379] don't expand all the things --- .../cashfusion/fusion_progress_view.dart | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index cf02963a6..a021753c0 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -178,20 +178,16 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { walletId: widget.walletId, ), if (_succeeded) - Expanded( - child: PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Fuse again", - onPressed: () => _fuseAgain, - ), + PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Fuse again", + onPressed: () => _fuseAgain, ), if (_failed) - Expanded( - child: PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Try again", - onPressed: () => _fuseAgain, - ), + PrimaryButton( + buttonHeight: ButtonHeight.m, + label: "Try again", + onPressed: () => _fuseAgain, ), if (!_succeeded && !_failed) const Spacer(), const SizedBox( From c9b4029826d536536a60a10e597fef94573cc3f6 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 24 Oct 2023 13:11:57 -0600 Subject: [PATCH 349/379] small ui tweaks in tx details screen --- .../tx_v2/transaction_v2_details_view.dart | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart index 5c313ea81..d52a504c6 100644 --- a/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart +++ b/lib/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart @@ -447,6 +447,7 @@ class _TransactionV2DetailsViewState ? const EdgeInsets.only(left: 32) : const EdgeInsets.all(12), child: Column( + mainAxisSize: MainAxisSize.min, children: [ if (isDesktop) Row( @@ -459,7 +460,7 @@ class _TransactionV2DetailsViewState const DesktopDialogCloseButton(), ], ), - Expanded( + Flexible( child: Padding( padding: isDesktop ? const EdgeInsets.only( @@ -487,6 +488,7 @@ class _TransactionV2DetailsViewState ? const EdgeInsets.all(0) : const EdgeInsets.all(4), child: Column( + mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ RoundedWhiteContainer( @@ -803,13 +805,23 @@ class _TransactionV2DetailsViewState context), ); }, - ), - if (!(data.length == 1 && - data.first.addresses.length == - 1)) - ...data.map( - (group) { - return Padding( + ) + else + for (int i = 0; + i < data.length; + i++) + ConditionalParent( + condition: i > 0, + builder: (child) => Column( + crossAxisAlignment: + CrossAxisAlignment + .stretch, + children: [ + const _Divider(), + child, + ], + ), + child: Padding( padding: const EdgeInsets.all( 8.0), @@ -818,7 +830,8 @@ class _TransactionV2DetailsViewState CrossAxisAlignment .start, children: [ - ...group.addresses + ...data[i] + .addresses .map( (e) { return FutureBuilder( @@ -847,7 +860,8 @@ class _TransactionV2DetailsViewState return OutputCard( address: addressOrContactName, - amount: group + amount: data[ + i] .amount, coin: coin, ); @@ -857,9 +871,8 @@ class _TransactionV2DetailsViewState ), ], ), - ); - }, - ), + ), + ), ], ), ], From 52f0d3903025033f014edb018b4239603306c2d4 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 24 Oct 2023 14:28:01 -0500 Subject: [PATCH 350/379] fusiondart cleanup --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 7e4099289..053f2de8c 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 7e4099289fc8c86594bbe7c737ce8804e7638d8d +Subproject commit 053f2de8c9ebd72a6546306be0ad7207c125337e From 87802b2a590b9ccfe5badc465818286c2e10708f Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Tue, 24 Oct 2023 14:36:44 -0500 Subject: [PATCH 351/379] fusiondart update minor --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 053f2de8c..08132417c 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 053f2de8c9ebd72a6546306be0ad7207c125337e +Subproject commit 08132417c879e9c87ca2a8efef5e92095f3ff6d6 From 5edfafae4f5ee6522b4a238ec9c7e3fb26800b1c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 24 Oct 2023 16:11:53 -0600 Subject: [PATCH 352/379] mobile button layout fixes --- .../cashfusion/fusion_progress_view.dart | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index a021753c0..4363a0461 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -177,22 +177,28 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { FusionProgress( walletId: widget.walletId, ), - if (_succeeded) - PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Fuse again", - onPressed: () => _fuseAgain, - ), - if (_failed) - PrimaryButton( - buttonHeight: ButtonHeight.m, - label: "Try again", - onPressed: () => _fuseAgain, - ), - if (!_succeeded && !_failed) const Spacer(), + const Spacer(), const SizedBox( height: 16, ), + if (_succeeded) + PrimaryButton( + label: "Fuse again", + onPressed: () => _fuseAgain, + ), + if (_succeeded) + const SizedBox( + height: 16, + ), + if (_failed) + PrimaryButton( + label: "Try again", + onPressed: () => _fuseAgain, + ), + if (_failed) + const SizedBox( + height: 16, + ), SecondaryButton( label: "Cancel", onPressed: () async { From a5c4fe180ee795458df13ef3f02ebd02636a0766 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 24 Oct 2023 16:12:05 -0600 Subject: [PATCH 353/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 08132417c..4386b83ea 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 08132417c879e9c87ca2a8efef5e92095f3ff6d6 +Subproject commit 4386b83eaf03e57250bd248d43a2bfa6f902a952 From 453316feb470ce5957a8276a281d85d1ecda6165 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 24 Oct 2023 16:32:46 -0600 Subject: [PATCH 354/379] update ref --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 4386b83ea..9866975af 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 4386b83eaf03e57250bd248d43a2bfa6f902a952 +Subproject commit 9866975af64dbb95e4ddbd6fb63656da4364409b From 3c4fc5e0cc21e0fd4374e19d84f147f0c78d9291 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 24 Oct 2023 16:43:41 -0600 Subject: [PATCH 355/379] couple tweaks --- lib/pages/cashfusion/cashfusion_view.dart | 21 +------------------ .../cashfusion/fusion_progress_view.dart | 4 ++-- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/lib/pages/cashfusion/cashfusion_view.dart b/lib/pages/cashfusion/cashfusion_view.dart index 5b34381d4..50407a172 100644 --- a/lib/pages/cashfusion/cashfusion_view.dart +++ b/lib/pages/cashfusion/cashfusion_view.dart @@ -148,9 +148,7 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { Theme.of(context).extension<StackColors>()!.background, appBar: AppBar( automaticallyImplyLeading: false, - leading: AppBarBackButton(onPressed: () { - _stop(); - }), + leading: const AppBarBackButton(), title: Text( "CashFusion", style: STextStyles.navBarTitle(context), @@ -445,21 +443,4 @@ class _CashFusionViewState extends ConsumerState<CashFusionView> { ), ); } - - /// Stops the fusion process. - /// - /// This is called when the user presses the back button. - void _stop() async { - final fusionWallet = ref - .read(walletsChangeNotifierProvider) - .getManager(widget.walletId) - .wallet as FusionWalletInterface; - - await fusionWallet.stop(); - // TODO await successful cancellation and showLoading while it stops. - - if (mounted) { - Navigator.of(context).pop(); - } - } } diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 4363a0461..9399f047d 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -184,7 +184,7 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { if (_succeeded) PrimaryButton( label: "Fuse again", - onPressed: () => _fuseAgain, + onPressed: _fuseAgain, ), if (_succeeded) const SizedBox( @@ -193,7 +193,7 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { if (_failed) PrimaryButton( label: "Try again", - onPressed: () => _fuseAgain, + onPressed: _fuseAgain, ), if (_failed) const SizedBox( From a2b20316ced51735d3bc9e7f73286db6fbfe7f83 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 24 Oct 2023 16:49:39 -0600 Subject: [PATCH 356/379] notifier not required on read when not updating value --- .../cashfusion/sub_widgets/fusion_dialog.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index fb84da245..b269b19ac 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -40,9 +40,7 @@ class FusionDialogView extends ConsumerStatefulWidget { class _FusionDialogViewState extends ConsumerState<FusionDialogView> { Future<bool> _requestAndProcessCancel() async { - if (!ref - .read(fusionProgressUIStateProvider(widget.walletId).notifier) - .running) { + if (!ref.read(fusionProgressUIStateProvider(widget.walletId)).running) { return true; } else { bool? shouldCancel = await showDialog<bool?>( From 4d71d3dec63e303afeaeaf596b4580c711811c0d Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Tue, 24 Oct 2023 17:04:09 -0600 Subject: [PATCH 357/379] ensure failed state is reset so that the retry button is not shown when fusing again or after tapping retry --- lib/pages/cashfusion/fusion_progress_view.dart | 11 +++++++++++ lib/services/mixins/fusion_wallet_interface.dart | 1 + 2 files changed, 12 insertions(+) diff --git a/lib/pages/cashfusion/fusion_progress_view.dart b/lib/pages/cashfusion/fusion_progress_view.dart index 9399f047d..96ef5eda9 100644 --- a/lib/pages/cashfusion/fusion_progress_view.dart +++ b/lib/pages/cashfusion/fusion_progress_view.dart @@ -232,6 +232,17 @@ class _FusionProgressViewState extends ConsumerState<FusionProgressView> { final fusionInfo = ref.read(prefsChangeNotifierProvider).fusionServerInfo; + try { + fusionWallet.uiState = ref.read( + fusionProgressUIStateProvider(widget.walletId), + ); + } catch (e) { + if (!e.toString().contains( + "FusionProgressUIState was already set for ${widget.walletId}")) { + rethrow; + } + } + unawaited(fusionWallet.fuse(fusionInfo: fusionInfo)); } } diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index ebd9d59f5..38db66a8d 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -228,6 +228,7 @@ mixin FusionWalletInterface { CashFusionState(status: CashFusionStatus.waiting, info: info); _uiState?.fusionState = CashFusionState(status: CashFusionStatus.waiting, info: info); + _uiState?.failed = false; break; } } From eb95cc3abf8e844e59f4649afe68d4824c8b4093 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Oct 2023 08:46:00 -0600 Subject: [PATCH 358/379] update ref and pass in more data --- fusiondart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 9866975af..1c1437050 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 9866975af64dbb95e4ddbd6fb63656da4364409b +Subproject commit 1c1437050a3e6ae6d5452161630cfbf1bc027b1f diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 38db66a8d..0208a34ac 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -12,6 +12,7 @@ import 'package:stackwallet/electrumx_rpc/cached_electrumx.dart'; import 'package:stackwallet/models/fusion_progress_ui_state.dart'; import 'package:stackwallet/models/isar/models/isar_models.dart'; import 'package:stackwallet/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart'; +import 'package:stackwallet/services/coins/bitcoincash/bitcoincash_wallet.dart'; import 'package:stackwallet/services/fusion_tor_service.dart'; import 'package:stackwallet/utilities/bip32_utils.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; @@ -430,6 +431,9 @@ mixin FusionWalletInterface { serverHost: fusionInfo.host, serverPort: fusionInfo.port, serverSsl: fusionInfo.ssl, + genesisHashHex: + _coin.isTestNet ? GENESIS_HASH_TESTNET : GENESIS_HASH_MAINNET, + enableDebugPrint: true, // TODO set to false on release ); // Instantiate a Fusion object with custom parameters. From 6197cc6b6a17670cf896029c884aa426da21b4ef Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Wed, 25 Oct 2023 10:29:10 -0500 Subject: [PATCH 359/379] cleanup --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 1c1437050..a7e034e4c 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 1c1437050a3e6ae6d5452161630cfbf1bc027b1f +Subproject commit a7e034e4c3aca9df1b186ed1814793c5fe0012f4 From 381a6b7b4bb9c833da1cce348407e5e069e99177 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Oct 2023 09:57:25 -0600 Subject: [PATCH 360/379] desktop fixes --- .../cashfusion/sub_widgets/fusion_dialog.dart | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart index b269b19ac..ca9067129 100644 --- a/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart +++ b/lib/pages_desktop_specific/cashfusion/sub_widgets/fusion_dialog.dart @@ -232,7 +232,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { child: PrimaryButton( buttonHeight: ButtonHeight.m, label: "Fuse again", - onPressed: () => _fuseAgain, + onPressed: _fuseAgain, ), ), if (_succeeded) @@ -244,7 +244,7 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { child: PrimaryButton( buttonHeight: ButtonHeight.m, label: "Try again", - onPressed: () => _fuseAgain, + onPressed: _fuseAgain, ), ), if (_failed) @@ -290,6 +290,17 @@ class _FusionDialogViewState extends ConsumerState<FusionDialogView> { final fusionInfo = ref.read(prefsChangeNotifierProvider).fusionServerInfo; + try { + fusionWallet.uiState = ref.read( + fusionProgressUIStateProvider(widget.walletId), + ); + } catch (e) { + if (!e.toString().contains( + "FusionProgressUIState was already set for ${widget.walletId}")) { + rethrow; + } + } + unawaited(fusionWallet.fuse(fusionInfo: fusionInfo)); } } From ea04ea9796af177dd19ac8bce73f5ad59a062c0e Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Oct 2023 10:45:30 -0600 Subject: [PATCH 361/379] fixes --- fusiondart | 2 +- .../coins/bitcoincash/bitcoincash_wallet.dart | 1 + .../mixins/fusion_wallet_interface.dart | 27 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index a7e034e4c..65643acb5 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit a7e034e4c3aca9df1b186ed1814793c5fe0012f4 +Subproject commit 65643acb54f829d29bb07939e16e3002e85eede7 diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 783146c11..f8507a3e9 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -151,6 +151,7 @@ class BitcoinCashWallet extends CoinServiceAPI mnemonic: mnemonicString, mnemonicPassphrase: mnemonicPassphrase, network: _network, + convertToScriptHash: _convertToScriptHash, ); initCoinControlInterface( walletId: walletId, diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 0208a34ac..43bae9909 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -125,6 +125,8 @@ mixin FusionWalletInterface { late final CachedElectrumX Function() _getWalletCachedElectrumX; late final Future<int> Function() _getChainHeight; late final Future<void> Function() _updateWalletUTXOS; + late final String Function(String bchAddress, btcdart.NetworkType network) + _convertToScriptHash; // Fusion object. fusion.Fusion? _mainFusionObject; @@ -154,6 +156,9 @@ mixin FusionWalletInterface { required Future<String?> mnemonic, required Future<String?> mnemonicPassphrase, required btcdart.NetworkType network, + required final String Function( + String bchAddress, btcdart.NetworkType network) + convertToScriptHash, }) async { // Set passed in wallet data. _walletId = walletId; @@ -167,6 +172,7 @@ mixin FusionWalletInterface { _mnemonic = mnemonic; _mnemonicPassphrase = mnemonicPassphrase; _network = network; + _convertToScriptHash = convertToScriptHash; } // callback to update the ui state object @@ -409,6 +415,26 @@ mixin FusionWalletInterface { } } + Future<bool> _checkUtxoExists( + String address, + String prevTxid, + int prevIndex, + ) async { + final scriptHash = _convertToScriptHash(address, _network); + + final utxos = await _getWalletCachedElectrumX() + .electrumXClient + .getUTXOs(scripthash: scriptHash); + + for (final utxo in utxos) { + if (utxo["tx_hash"] == prevTxid && utxo["tx_pos"] == prevIndex) { + return true; + } + } + + return false; + } + // Initial attempt for CashFusion integration goes here. /// Fuse the wallet's UTXOs. @@ -446,6 +472,7 @@ mixin FusionWalletInterface { getSocksProxyAddress: _getSocksProxyAddress, getChainHeight: _getChainHeight, updateStatusCallback: _updateStatus, + checkUtxoExists: _checkUtxoExists, getTransactionJson: (String txid) async => await _getWalletCachedElectrumX().getTransaction( coin: _coin, From 10f3e53dcbaa0509dcd3215791d4b36eaadfca16 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Oct 2023 11:14:43 -0600 Subject: [PATCH 362/379] type fixes --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 65643acb5..ec9a480f7 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 65643acb54f829d29bb07939e16e3002e85eede7 +Subproject commit ec9a480f78c6ff3de1d187ef103358a591c248b9 From 7d385bdb1ad7818a753b6a2c0848fca939af0e4c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Wed, 25 Oct 2023 12:26:46 -0600 Subject: [PATCH 363/379] completer check --- fusiondart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index ec9a480f7..66a708120 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit ec9a480f78c6ff3de1d187ef103358a591c248b9 +Subproject commit 66a7081205f3c0ff401d0fa6ba293a63f1929104 From b0124ca6919f905ebcd13de9d561d2bf67a39c7f Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 26 Oct 2023 10:30:12 -0500 Subject: [PATCH 364/379] add FusionMode enum and require its usage --- fusiondart | 2 +- lib/services/mixins/fusion_wallet_interface.dart | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fusiondart b/fusiondart index 66a708120..afe3e345e 160000 --- a/fusiondart +++ b/fusiondart @@ -1 +1 @@ -Subproject commit 66a7081205f3c0ff401d0fa6ba293a63f1929104 +Subproject commit afe3e345ecd762704e9acdbbc4bf20a69c028e76 diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 43bae9909..30b8af64d 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -460,6 +460,7 @@ mixin FusionWalletInterface { genesisHashHex: _coin.isTestNet ? GENESIS_HASH_TESTNET : GENESIS_HASH_MAINNET, enableDebugPrint: true, // TODO set to false on release + mode: fusion.FusionMode.normal, ); // Instantiate a Fusion object with custom parameters. From b5ce7c6635be0ac870f87e6ab943e4cefbcf9675 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 26 Oct 2023 10:48:54 -0500 Subject: [PATCH 365/379] replace fusiondart submodule with package --- .gitmodules | 3 --- fusiondart | 1 - pubspec.yaml | 7 +++++-- 3 files changed, 5 insertions(+), 6 deletions(-) delete mode 160000 fusiondart diff --git a/.gitmodules b/.gitmodules index cf4975167..7474c8a54 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,6 +7,3 @@ [submodule "crypto_plugins/flutter_liblelantus"] path = crypto_plugins/flutter_liblelantus url = https://github.com/cypherstack/flutter_liblelantus.git -[submodule "fusiondart"] - path = fusiondart - url = https://github.com/cypherstack/fusiondart.git diff --git a/fusiondart b/fusiondart deleted file mode 160000 index afe3e345e..000000000 --- a/fusiondart +++ /dev/null @@ -1 +0,0 @@ -Subproject commit afe3e345ecd762704e9acdbbc4bf20a69c028e76 diff --git a/pubspec.yaml b/pubspec.yaml index 372c8588f..3360cd662 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,6 +62,11 @@ dependencies: url: https://github.com/cypherstack/tor.git ref: 0a6888282f4e98401051a396e9d2293bd55ac2c2 + fusiondart: + git: + url: https://github.com/cypherstack/fusiondart.git + ref: 30b9495eaeb3bfcd80b57a1879113a7d85ed054c + # Utility plugins http: ^0.13.0 local_auth: ^1.1.10 @@ -144,8 +149,6 @@ dependencies: nanodart: ^2.0.0 basic_utils: ^5.5.4 stellar_flutter_sdk: ^1.5.3 - fusiondart: - path: ./fusiondart socks_socket: git: url: https://github.com/cypherstack/socks_socket.git From 3e559a27f3ac0f288f6fc251e23caaad72ddd3d1 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Oct 2023 09:54:20 -0600 Subject: [PATCH 366/379] final clean up --- lib/services/mixins/fusion_wallet_interface.dart | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 30b8af64d..2db0e82ff 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -1,10 +1,10 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'dart:typed_data'; import 'package:bitbox/bitbox.dart' as bitbox; import 'package:bitcoindart/bitcoindart.dart' as btcdart; +import 'package:flutter/foundation.dart'; import 'package:fusiondart/fusiondart.dart' as fusion; import 'package:isar/isar.dart'; import 'package:stackwallet/db/isar/main_db.dart'; @@ -36,11 +36,13 @@ class FusionInfo { required this.rounds, }) : assert(rounds >= 0); - // TODO update defaults static const DEFAULTS = FusionInfo( - host: "cashfusion.stackwallet.com", - port: 8787, - ssl: false, + host: "fusion.servo.cash", + port: 8789, + ssl: true, + // host: "cashfusion.stackwallet.com", + // port: 8787, + // ssl: false, rounds: 0, // 0 is continuous ); @@ -459,7 +461,7 @@ mixin FusionWalletInterface { serverSsl: fusionInfo.ssl, genesisHashHex: _coin.isTestNet ? GENESIS_HASH_TESTNET : GENESIS_HASH_MAINNET, - enableDebugPrint: true, // TODO set to false on release + enableDebugPrint: kDebugMode, mode: fusion.FusionMode.normal, ); From 390bc8026fadfb903c171e7840ee5d756e70b43a Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 26 Oct 2023 12:29:06 -0500 Subject: [PATCH 367/379] add torForOvert flag --- lib/services/mixins/fusion_wallet_interface.dart | 4 ++++ pubspec.lock | 8 +++++--- pubspec.yaml | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 2db0e82ff..7b790aeff 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -17,6 +17,7 @@ import 'package:stackwallet/services/fusion_tor_service.dart'; import 'package:stackwallet/utilities/bip32_utils.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/logger.dart'; +import 'package:stackwallet/utilities/prefs.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; const String kReservedFusionAddress = "reserved_fusion_address"; @@ -105,6 +106,8 @@ mixin FusionWalletInterface { late final Future<String?> _mnemonicPassphrase; late final btcdart.NetworkType _network; + final _prefs = Prefs.instance; + // setting values on this should notify any listeners (the GUI) FusionProgressUIState? _uiState; FusionProgressUIState get uiState { @@ -462,6 +465,7 @@ mixin FusionWalletInterface { genesisHashHex: _coin.isTestNet ? GENESIS_HASH_TESTNET : GENESIS_HASH_MAINNET, enableDebugPrint: kDebugMode, + torForOvert: _prefs.useTor, mode: fusion.FusionMode.normal, ); diff --git a/pubspec.lock b/pubspec.lock index 49125d53d..8ee2e3aa0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -805,9 +805,11 @@ packages: fusiondart: dependency: "direct main" description: - path: fusiondart - relative: true - source: path + path: "." + ref: "0e7ebee90d90ba0967f773c96e08410d2c87b417" + resolved-ref: "0e7ebee90d90ba0967f773c96e08410d2c87b417" + url: "https://github.com/cypherstack/fusiondart.git" + source: git version: "1.0.0" glob: dependency: transitive diff --git a/pubspec.yaml b/pubspec.yaml index 3360cd662..7be175336 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,7 +65,7 @@ dependencies: fusiondart: git: url: https://github.com/cypherstack/fusiondart.git - ref: 30b9495eaeb3bfcd80b57a1879113a7d85ed054c + ref: 0e7ebee90d90ba0967f773c96e08410d2c87b417 # Utility plugins http: ^0.13.0 From f915a705dc73ea10f372aa2d2a1a04a074998043 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Oct 2023 16:06:47 -0600 Subject: [PATCH 368/379] checking electrumx takes too long --- lib/services/coins/bitcoincash/bitcoincash_wallet.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index f8507a3e9..4b42c16dc 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -278,10 +278,10 @@ class BitcoinCashWallet extends CoinServiceAPI if (txCountInDB == 0) { // double check via electrumx // _getTxCountForAddress can throw! - final count = await getTxCount(address: address); - if (count == 0) { - return true; - } + // final count = await getTxCount(address: address); + // if (count == 0) { + return true; + // } } return false; From b82cd05fd9fcd683443f9e2e4f845e9c95bf4975 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Oct 2023 16:22:30 -0600 Subject: [PATCH 369/379] reserve in batch --- .../mixins/fusion_wallet_interface.dart | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index 7b790aeff..bf4def848 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -326,18 +326,22 @@ mixin FusionWalletInterface { } /// Reserve an address for fusion. - Future<Address> _reserveAddress(Address address) async { - address = address.copyWith(otherData: kReservedFusionAddress); - - // Make sure the address is updated in the database as reserved for Fusion. - final _address = await _db.getAddress(_walletId, address.value); - if (_address != null) { - await _db.updateAddress(_address, address); - } else { - await _db.putAddress(address); + Future<List<Address>> _reserveAddresses(Iterable<Address> addresses) async { + if (addresses.isEmpty) { + return []; } - return address; + final updatedAddresses = addresses + .map((e) => e.copyWith(otherData: kReservedFusionAddress)) + .toList(); + + await _db.isar.writeTxn(() async { + await _db.isar.addresses + .deleteAll(updatedAddresses.map((e) => e.id).toList()); + await _db.isar.addresses.putAll(updatedAddresses); + }); + + return updatedAddresses; } /// un reserve a fusion reserved address. @@ -366,10 +370,12 @@ mixin FusionWalletInterface { ); // Initialize a list of unused reserved change addresses. - final List<Address> unusedReservedAddresses = []; - for (final address in unusedChangeAddresses) { - unusedReservedAddresses.add(await _reserveAddress(address)); - } + final List<Address> unusedReservedAddresses = unusedChangeAddresses + .where((e) => e.otherData == kReservedFusionAddress) + .toList(); + + unusedReservedAddresses.addAll(await _reserveAddresses( + unusedChangeAddresses.where((e) => e.otherData == null))); // Return the list of unused reserved change addresses. return unusedReservedAddresses From c2dd868421f2d5b311a01aad5972b96bc15a6f32 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Oct 2023 16:22:46 -0600 Subject: [PATCH 370/379] update fusiondart dep --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 7be175336..8d747503f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,7 +65,7 @@ dependencies: fusiondart: git: url: https://github.com/cypherstack/fusiondart.git - ref: 0e7ebee90d90ba0967f773c96e08410d2c87b417 + ref: 35fd1ab11c8988fa4ee671c481d40fb9a2b8a451 # Utility plugins http: ^0.13.0 From a5930647a8f9d7c9689e1e07f8550b06a10f2df3 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Thu, 26 Oct 2023 16:44:50 -0600 Subject: [PATCH 371/379] possible index violation error fix --- lib/services/mixins/fusion_wallet_interface.dart | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index bf4def848..b215851ee 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -336,9 +336,19 @@ mixin FusionWalletInterface { .toList(); await _db.isar.writeTxn(() async { - await _db.isar.addresses - .deleteAll(updatedAddresses.map((e) => e.id).toList()); - await _db.isar.addresses.putAll(updatedAddresses); + for (final newAddress in updatedAddresses) { + final oldAddress = await _db.getAddress( + newAddress.walletId, + newAddress.value, + ); + + if (oldAddress != null) { + newAddress.id = oldAddress.id; + await _db.isar.addresses.delete(oldAddress.id); + } + + await _db.isar.addresses.put(newAddress); + } }); return updatedAddresses; From bdcc958d9db5d25e69de38f995fced465ad6f38a Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Thu, 26 Oct 2023 22:51:23 -0500 Subject: [PATCH 372/379] update fusiondart ref --- pubspec.lock | 4 ++-- pubspec.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 8ee2e3aa0..f9eee32ec 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -806,8 +806,8 @@ packages: dependency: "direct main" description: path: "." - ref: "0e7ebee90d90ba0967f773c96e08410d2c87b417" - resolved-ref: "0e7ebee90d90ba0967f773c96e08410d2c87b417" + ref: "4eecd817a5e79b8c5f0e106692351e39152d9baf" + resolved-ref: "4eecd817a5e79b8c5f0e106692351e39152d9baf" url: "https://github.com/cypherstack/fusiondart.git" source: git version: "1.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 8d747503f..8f15c9f52 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,7 +65,7 @@ dependencies: fusiondart: git: url: https://github.com/cypherstack/fusiondart.git - ref: 35fd1ab11c8988fa4ee671c481d40fb9a2b8a451 + ref: 4eecd817a5e79b8c5f0e106692351e39152d9baf # Utility plugins http: ^0.13.0 From 43eee96c4c218b3ff1d4a3d7883f1f50b673641e Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 27 Oct 2023 10:16:21 -0500 Subject: [PATCH 373/379] update fusiondart ref to julian's equality check fix --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 8f15c9f52..561d4ce5e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,7 +65,7 @@ dependencies: fusiondart: git: url: https://github.com/cypherstack/fusiondart.git - ref: 4eecd817a5e79b8c5f0e106692351e39152d9baf + ref: df8f7c627cfc77eaa3e364c0d166f3d04169ae05 # Utility plugins http: ^0.13.0 From a9094a4ad9454293903b05356ed622d364699ec1 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Oct 2023 09:56:26 -0600 Subject: [PATCH 374/379] update tests --- .../bitcoincash/bitcoincash_wallet_test.dart | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart index f3598dfa1..f5619ac9a 100644 --- a/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart +++ b/test/services/coins/bitcoincash/bitcoincash_wallet_test.dart @@ -91,7 +91,7 @@ void main() async { mainnetWallet?.addressType( address: "1DP3PUePwMa5CoZwzjznVKhzdLsZftjcAT"), DerivePathType.bip44); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -102,7 +102,7 @@ void main() async { () => mainnetWallet?.addressType( address: "mhqpGtwhcR6gFuuRjLTpHo41919QfuGy8Y"), throwsArgumentError); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -113,7 +113,7 @@ void main() async { () => mainnetWallet?.addressType( address: "tb1qzzlm6mnc8k54mx6akehl8p9ray8r439va5ndyq"), throwsArgumentError); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -124,7 +124,7 @@ void main() async { () => mainnetWallet?.addressType( address: "mpMk94ETazqonHutyC1v6ajshgtP8oiFKU"), throwsArgumentError); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -136,7 +136,7 @@ void main() async { address: "bitcoincash:qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"), DerivePathType.bip44); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -147,7 +147,7 @@ void main() async { mainnetWallet?.addressType( address: "qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"), DerivePathType.bip44); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -159,7 +159,7 @@ void main() async { address: "bitcoincash:pzpp3nchmzzf0gr69lj82ymurg5u3ds6kcwr5m07np"), throwsArgumentError); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -170,7 +170,7 @@ void main() async { () => mainnetWallet?.addressType( address: "pzpp3nchmzzf0gr69lj82ymurg5u3ds6kcwr5m07np"), throwsArgumentError); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -208,7 +208,7 @@ void main() async { expect( mainnetWallet?.validateAddress("1DP3PUePwMa5CoZwzjznVKhzdLsZftjcAT"), true); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -219,7 +219,7 @@ void main() async { mainnetWallet?.validateAddress( "bitcoincash:qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"), true); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -230,7 +230,7 @@ void main() async { mainnetWallet ?.validateAddress("qrwjyc4pewj9utzrtnh0whkzkuvy5q8wg52n254x6k"), true); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -240,7 +240,7 @@ void main() async { expect( mainnetWallet?.validateAddress("mhqpGtwhcR6gFuuRjLTpHo41919QfuGy8Y"), false); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -253,7 +253,7 @@ void main() async { mainnetWallet ?.validateAddress("pzpp3nchmzzf0gr69lj82ymurg5u3ds6kcwr5m07np"), false); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -263,7 +263,7 @@ void main() async { expect( mainnetWallet?.validateAddress("3DYuVEmuKWQFxJcF7jDPhwPiXLTiNnyMFb"), false); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -273,7 +273,7 @@ void main() async { expect( mainnetWallet?.validateAddress("mhqpGtwhcR6gFuuRjLTpHo41919QfuGy8Y"), false); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -311,7 +311,7 @@ void main() async { when(client?.ping()).thenAnswer((_) async => false); final bool? result = await bch?.testNetworkConnection(); expect(result, false); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verify(client?.ping()).called(1); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); @@ -322,7 +322,7 @@ void main() async { when(client?.ping()).thenThrow(Exception); final bool? result = await bch?.testNetworkConnection(); expect(result, false); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verify(client?.ping()).called(1); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); @@ -333,7 +333,7 @@ void main() async { when(client?.ping()).thenAnswer((_) async => true); final bool? result = await bch?.testNetworkConnection(); expect(result, true); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verify(client?.ping()).called(1); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); @@ -374,7 +374,7 @@ void main() async { test("get networkType main", () async { expect(bch?.coin, bchcoin); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -391,7 +391,7 @@ void main() async { secureStore: secureStore, ); expect(bch?.coin, bchcoin); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 4); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -399,7 +399,7 @@ void main() async { test("get cryptoCurrency", () async { expect(Coin.bitcoincash, Coin.bitcoincash); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -407,7 +407,7 @@ void main() async { test("get coinName", () async { expect(Coin.bitcoincash, Coin.bitcoincash); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -415,7 +415,7 @@ void main() async { test("get coinTicker", () async { expect(Coin.bitcoincash, Coin.bitcoincash); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -425,7 +425,7 @@ void main() async { expect(Coin.bitcoincash, Coin.bitcoincash); bch?.walletName = "new name"; expect(bch?.walletName, "new name"); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -440,7 +440,7 @@ void main() async { expect(bch?.estimateTxFee(vSize: 356, feeRatePerKB: 1699), 712); expect(bch?.estimateTxFee(vSize: 356, feeRatePerKB: 2000), 712); expect(bch?.estimateTxFee(vSize: 356, feeRatePerKB: 12345), 4628); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -474,7 +474,7 @@ void main() async { verify(client?.estimateFee(blocks: 1)).called(1); verify(client?.estimateFee(blocks: 5)).called(1); verify(client?.estimateFee(blocks: 20)).called(1); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -511,7 +511,7 @@ void main() async { verify(client?.estimateFee(blocks: 1)).called(1); verify(client?.estimateFee(blocks: 5)).called(1); verify(client?.estimateFee(blocks: 20)).called(1); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -629,7 +629,7 @@ void main() async { await expectLater( () => bch?.initializeNew(null), throwsA(isA<Exception>())) .then((_) { - expect(secureStore.interactions, 2); + expect(secureStore.interactions, 4); verifyNever(client?.ping()).called(0); verify(client?.getServerFeatures()).called(1); verifyNoMoreInteractions(client); @@ -1209,7 +1209,7 @@ void main() async { "1df1cab6d109d506aa424b00b6a013c5e1947dc13b78d62b4d0e9f518b3035d1")) .called(1); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -1234,7 +1234,7 @@ void main() async { "64953f7db441a21172de206bf70b920c8c718ed4f03df9a85073c0400be0053c")) .called(0); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -1894,7 +1894,7 @@ void main() async { verify(client?.getServerFeatures()).called(1); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); }); @@ -1936,7 +1936,7 @@ void main() async { verify(client?.getServerFeatures()).called(1); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 4); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); }); @@ -1972,7 +1972,7 @@ void main() async { verify(client?.getServerFeatures()).called(1); - expect(secureStore.interactions, 2); + expect(secureStore.interactions, 4); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); }); @@ -2731,7 +2731,7 @@ void main() async { expect(didThrow, true); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -2747,7 +2747,7 @@ void main() async { expect(didThrow, true); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -2763,7 +2763,7 @@ void main() async { expect(didThrow, true); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -2779,7 +2779,7 @@ void main() async { expect(didThrow, true); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -2800,7 +2800,7 @@ void main() async { rawTx: "a string", requestID: anyNamed("requestID"))) .called(1); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); @@ -2825,7 +2825,7 @@ void main() async { rawTx: "a string", requestID: anyNamed("requestID"))) .called(1); - expect(secureStore.interactions, 0); + expect(secureStore.interactions, 2); verifyNoMoreInteractions(client); verifyNoMoreInteractions(cachedClient); verifyNoMoreInteractions(tracker); From bfc24edeabaa712889cbfd274c6f05ba04ffb078 Mon Sep 17 00:00:00 2001 From: julian-CStack <97684800+julian-CStack@users.noreply.github.com> Date: Fri, 27 Oct 2023 10:41:55 -0600 Subject: [PATCH 375/379] Update test.yaml Flutter version --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e14b9d303..1f357846a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -8,12 +8,12 @@ jobs: - name: Prepare repository uses: actions/checkout@v3 with: - flutter-version: '3.10.3' + flutter-version: '3.10.6' channel: 'stable' - name: Install Flutter uses: subosito/flutter-action@v2 with: - flutter-version: '3.10.3' + flutter-version: '3.10.6' channel: 'stable' - name: Setup | Rust uses: ATiltedTree/setup-rust@v1 From a3ad7b5926a7be78a378b9eece67dda6bcda9caf Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 27 Oct 2023 11:43:17 -0500 Subject: [PATCH 376/379] pubspec lock update --- pubspec.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index f9eee32ec..d7d431c54 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -806,8 +806,8 @@ packages: dependency: "direct main" description: path: "." - ref: "4eecd817a5e79b8c5f0e106692351e39152d9baf" - resolved-ref: "4eecd817a5e79b8c5f0e106692351e39152d9baf" + ref: df8f7c627cfc77eaa3e364c0d166f3d04169ae05 + resolved-ref: df8f7c627cfc77eaa3e364c0d166f3d04169ae05 url: "https://github.com/cypherstack/fusiondart.git" source: git version: "1.0.0" From c0389d2da7cd86e5986ef5865eba01fe8b9caca6 Mon Sep 17 00:00:00 2001 From: sneurlax <sneurlax@gmail.com> Date: Fri, 27 Oct 2023 11:43:42 -0500 Subject: [PATCH 377/379] update all uiStates whenever we update any of them except on failure --- lib/models/fusion_progress_ui_state.dart | 52 ++++-- .../mixins/fusion_wallet_interface.dart | 166 ++++++++++++------ 2 files changed, 147 insertions(+), 71 deletions(-) diff --git a/lib/models/fusion_progress_ui_state.dart b/lib/models/fusion_progress_ui_state.dart index 3ce98d488..62168e359 100644 --- a/lib/models/fusion_progress_ui_state.dart +++ b/lib/models/fusion_progress_ui_state.dart @@ -52,55 +52,67 @@ class FusionProgressUIState extends ChangeNotifier { CashFusionState _connecting = CashFusionState(status: CashFusionStatus.waiting, info: null); CashFusionState get connecting => _connecting; - set connecting(CashFusionState state) { + void setConnecting(CashFusionState state, {bool shouldNotify = true}) { _connecting = state; _running = true; - notifyListeners(); + if (shouldNotify) { + notifyListeners(); + } } CashFusionState _outputs = CashFusionState(status: CashFusionStatus.waiting, info: null); CashFusionState get outputs => _outputs; - set outputs(CashFusionState state) { + void setOutputs(CashFusionState state, {bool shouldNotify = true}) { _outputs = state; _running = true; - notifyListeners(); + if (shouldNotify) { + notifyListeners(); + } } CashFusionState _peers = CashFusionState(status: CashFusionStatus.waiting, info: null); CashFusionState get peers => _peers; - set peers(CashFusionState state) { + void setPeers(CashFusionState state, {bool shouldNotify = true}) { _peers = state; _running = true; - notifyListeners(); + if (shouldNotify) { + notifyListeners(); + } } CashFusionState _fusing = CashFusionState(status: CashFusionStatus.waiting, info: null); CashFusionState get fusing => _fusing; - set fusing(CashFusionState state) { + void setFusing(CashFusionState state, {bool shouldNotify = true}) { _fusing = state; - _updateRunningState(state.status); - notifyListeners(); + _running = true; + if (shouldNotify) { + notifyListeners(); + } } CashFusionState _complete = CashFusionState(status: CashFusionStatus.waiting, info: null); CashFusionState get complete => _complete; - set complete(CashFusionState state) { + void setComplete(CashFusionState state, {bool shouldNotify = true}) { _complete = state; - _updateRunningState(state.status); - notifyListeners(); + _running = true; + if (shouldNotify) { + notifyListeners(); + } } CashFusionState _fusionStatus = CashFusionState(status: CashFusionStatus.waiting, info: null); CashFusionState get fusionState => _fusionStatus; - set fusionState(CashFusionState state) { + void setFusionState(CashFusionState state, {bool shouldNotify = true}) { _fusionStatus = state; _updateRunningState(state.status); - notifyListeners(); + if (shouldNotify) { + notifyListeners(); + } } /// An int storing the number of successfully completed fusion rounds. @@ -141,17 +153,21 @@ class FusionProgressUIState extends ChangeNotifier { /// Used to be named maxConsecutiveFusionRoundsFailed. bool _failed = false; bool get failed => _failed; - set failed(bool failed) { + void setFailed(bool failed, {bool shouldNotify = true}) { _failed = failed; - notifyListeners(); + if (shouldNotify) { + notifyListeners(); + } } /// A flag indicating that fusion is running. bool _running = false; bool get running => _running; - set running(bool running) { + void setRunning(bool running, {bool shouldNotify = true}) { _running = running; - notifyListeners(); + if (shouldNotify) { + notifyListeners(); + } } /// A helper method for setting the running flag. diff --git a/lib/services/mixins/fusion_wallet_interface.dart b/lib/services/mixins/fusion_wallet_interface.dart index b215851ee..dc26b4618 100644 --- a/lib/services/mixins/fusion_wallet_interface.dart +++ b/lib/services/mixins/fusion_wallet_interface.dart @@ -184,63 +184,118 @@ mixin FusionWalletInterface { void _updateStatus({required fusion.FusionStatus status, String? info}) { switch (status) { case fusion.FusionStatus.connecting: - _uiState?.connecting = CashFusionState( - status: CashFusionStatus.running, - info: - null); // We only want to show error messages for failed states. + _uiState?.setConnecting( + CashFusionState(status: CashFusionStatus.running, info: null), + shouldNotify: false); + _uiState?.setOutputs( + CashFusionState(status: CashFusionStatus.waiting, info: null), + shouldNotify: false); + _uiState?.setPeers( + CashFusionState(status: CashFusionStatus.waiting, info: null), + shouldNotify: false); + _uiState?.setFusing( + CashFusionState(status: CashFusionStatus.waiting, info: null), + shouldNotify: false); + _uiState?.setComplete( + CashFusionState(status: CashFusionStatus.waiting, info: null), + shouldNotify: true); break; case fusion.FusionStatus.setup: - _uiState?.connecting = - CashFusionState(status: CashFusionStatus.success, info: null); - _uiState?.outputs = - CashFusionState(status: CashFusionStatus.running, info: null); + _uiState?.setConnecting( + CashFusionState(status: CashFusionStatus.success, info: null), + shouldNotify: false); + _uiState?.setOutputs( + CashFusionState(status: CashFusionStatus.running, info: null), + shouldNotify: false); + _uiState?.setPeers( + CashFusionState(status: CashFusionStatus.waiting, info: null), + shouldNotify: false); + _uiState?.setFusing( + CashFusionState(status: CashFusionStatus.waiting, info: null), + shouldNotify: false); + _uiState?.setComplete( + CashFusionState(status: CashFusionStatus.waiting, info: null), + shouldNotify: true); break; case fusion.FusionStatus.waiting: - _uiState?.outputs = - CashFusionState(status: CashFusionStatus.success, info: null); - _uiState?.peers = - CashFusionState(status: CashFusionStatus.running, info: null); + _uiState?.setConnecting( + CashFusionState(status: CashFusionStatus.success, info: null), + shouldNotify: false); + _uiState?.setOutputs( + CashFusionState(status: CashFusionStatus.success, info: null), + shouldNotify: false); + _uiState?.setPeers( + CashFusionState(status: CashFusionStatus.running, info: null), + shouldNotify: false); + _uiState?.setFusing( + CashFusionState(status: CashFusionStatus.waiting, info: null), + shouldNotify: false); + _uiState?.setComplete( + CashFusionState(status: CashFusionStatus.waiting, info: null), + shouldNotify: true); break; case fusion.FusionStatus.running: - _uiState?.peers = - CashFusionState(status: CashFusionStatus.success, info: null); - _uiState?.fusing = - CashFusionState(status: CashFusionStatus.running, info: null); + _uiState?.setConnecting( + CashFusionState(status: CashFusionStatus.success, info: null), + shouldNotify: false); + _uiState?.setOutputs( + CashFusionState(status: CashFusionStatus.success, info: null), + shouldNotify: false); + _uiState?.setPeers( + CashFusionState(status: CashFusionStatus.success, info: null), + shouldNotify: false); + _uiState?.setFusing( + CashFusionState(status: CashFusionStatus.running, info: null), + shouldNotify: false); + _uiState?.setComplete( + CashFusionState(status: CashFusionStatus.waiting, info: null), + shouldNotify: true); break; case fusion.FusionStatus.complete: - _uiState?.fusing = - CashFusionState(status: CashFusionStatus.success, info: null); - _uiState?.complete = - CashFusionState(status: CashFusionStatus.success, info: null); + _uiState?.setConnecting( + CashFusionState(status: CashFusionStatus.success, info: null), + shouldNotify: false); + _uiState?.setOutputs( + CashFusionState(status: CashFusionStatus.success, info: null), + shouldNotify: false); + _uiState?.setPeers( + CashFusionState(status: CashFusionStatus.success, info: null), + shouldNotify: false); + _uiState?.setFusing( + CashFusionState(status: CashFusionStatus.success, info: null), + shouldNotify: false); + _uiState?.setComplete( + CashFusionState(status: CashFusionStatus.success, info: null), + shouldNotify: true); break; case fusion.FusionStatus.failed: - // _uiState?.fusing = CashFusionStatus.failed; - // _uiState?.complete = - // CashFusionState(status: CashFusionStatus.failed, info: info); - failCurrentUiState(info); - break; case fusion.FusionStatus.exception: - // _uiState?.complete = - // CashFusionState(status: CashFusionStatus.failed, info: info); - failCurrentUiState(info); break; case fusion.FusionStatus.reset: - _uiState?.outputs = - CashFusionState(status: CashFusionStatus.waiting, info: info); - _uiState?.peers = - CashFusionState(status: CashFusionStatus.waiting, info: info); - _uiState?.connecting = - CashFusionState(status: CashFusionStatus.waiting, info: info); - _uiState?.fusing = - CashFusionState(status: CashFusionStatus.waiting, info: info); - _uiState?.complete = - CashFusionState(status: CashFusionStatus.waiting, info: info); - _uiState?.fusionState = - CashFusionState(status: CashFusionStatus.waiting, info: info); - _uiState?.failed = false; + _uiState?.setConnecting( + CashFusionState(status: CashFusionStatus.waiting, info: info), + shouldNotify: false); + _uiState?.setOutputs( + CashFusionState(status: CashFusionStatus.waiting, info: info), + shouldNotify: false); + _uiState?.setPeers( + CashFusionState(status: CashFusionStatus.waiting, info: info), + shouldNotify: false); + _uiState?.setFusing( + CashFusionState(status: CashFusionStatus.waiting, info: info), + shouldNotify: false); + _uiState?.setComplete( + CashFusionState(status: CashFusionStatus.waiting, info: info), + shouldNotify: false); + + _uiState?.setFusionState( + CashFusionState(status: CashFusionStatus.waiting, info: info), + shouldNotify: false); + + _uiState?.setFailed(false, shouldNotify: true); break; } } @@ -248,28 +303,33 @@ mixin FusionWalletInterface { void failCurrentUiState(String? info) { // Check each _uiState value to see if it is running. If so, set it to failed. if (_uiState?.connecting.status == CashFusionStatus.running) { - _uiState?.connecting = - CashFusionState(status: CashFusionStatus.failed, info: info); + _uiState?.setConnecting( + CashFusionState(status: CashFusionStatus.failed, info: info), + shouldNotify: true); return; } if (_uiState?.outputs.status == CashFusionStatus.running) { - _uiState?.outputs = - CashFusionState(status: CashFusionStatus.failed, info: info); + _uiState?.setOutputs( + CashFusionState(status: CashFusionStatus.failed, info: info), + shouldNotify: true); return; } if (_uiState?.peers.status == CashFusionStatus.running) { - _uiState?.peers = - CashFusionState(status: CashFusionStatus.failed, info: info); + _uiState?.setPeers( + CashFusionState(status: CashFusionStatus.failed, info: info), + shouldNotify: true); return; } if (_uiState?.fusing.status == CashFusionStatus.running) { - _uiState?.fusing = - CashFusionState(status: CashFusionStatus.failed, info: info); + _uiState?.setFusing( + CashFusionState(status: CashFusionStatus.failed, info: info), + shouldNotify: true); return; } if (_uiState?.complete.status == CashFusionStatus.running) { - _uiState?.complete = - CashFusionState(status: CashFusionStatus.failed, info: info); + _uiState?.setComplete( + CashFusionState(status: CashFusionStatus.failed, info: info), + shouldNotify: true); return; } } @@ -656,7 +716,7 @@ mixin FusionWalletInterface { status: fusion.FusionStatus.failed, info: "Failed $maxFailedFuseCount times in a row, stopping."); _stopRequested = true; - _uiState?.failed = true; + _uiState?.setFailed(true, shouldNotify: true); } } } @@ -669,7 +729,7 @@ mixin FusionWalletInterface { // Stop the fusion process and update the UI state. await _mainFusionObject?.stop(); _mainFusionObject = null; - _uiState?.running = false; + _uiState?.setRunning(false, shouldNotify: true); } } From 86c33d4cb561c47a79f99b45f14c03833f62fca6 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Oct 2023 11:16:25 -0600 Subject: [PATCH 378/379] no need to fetch address if it already exists --- .../coins/bitcoincash/bitcoincash_wallet.dart | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart index 4b42c16dc..875aed471 100644 --- a/lib/services/coins/bitcoincash/bitcoincash_wallet.dart +++ b/lib/services/coins/bitcoincash/bitcoincash_wallet.dart @@ -2668,28 +2668,30 @@ class BitcoinCashWallet extends CoinServiceAPI try { // Populating the addresses to check for (var i = 0; i < utxosToUse.length; i++) { - final txid = utxosToUse[i].txid; - final tx = await _cachedElectrumXClient.getTransaction( - txHash: txid, - coin: coin, - ); + if (utxosToUse[i].address == null) { + final txid = utxosToUse[i].txid; + final tx = await _cachedElectrumXClient.getTransaction( + txHash: txid, + coin: coin, + ); - for (final output in tx["vout"] as List) { - final n = output["n"]; - if (n != null && n == utxosToUse[i].vout) { - String address = - output["scriptPubKey"]?["addresses"]?[0] as String? ?? - output["scriptPubKey"]["address"] as String; - if (bitbox.Address.detectFormat(address) != - bitbox.Address.formatCashAddr) { - try { - address = bitbox.Address.toCashAddress(address); - } catch (_) { - rethrow; + for (final output in tx["vout"] as List) { + final n = output["n"]; + if (n != null && n == utxosToUse[i].vout) { + String address = + output["scriptPubKey"]?["addresses"]?[0] as String? ?? + output["scriptPubKey"]["address"] as String; + if (bitbox.Address.detectFormat(address) != + bitbox.Address.formatCashAddr) { + try { + address = bitbox.Address.toCashAddress(address); + } catch (_) { + rethrow; + } } - } - utxosToUse[i] = utxosToUse[i].copyWith(address: address); + utxosToUse[i] = utxosToUse[i].copyWith(address: address); + } } } From 07a717d20a0dfdfa1314f4bfd334342baf69e17c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 27 Oct 2023 11:37:50 -0600 Subject: [PATCH 379/379] SigningData toString --- lib/models/signing_data.dart | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/models/signing_data.dart b/lib/models/signing_data.dart index ac7a0a4ed..0937a2d8b 100644 --- a/lib/models/signing_data.dart +++ b/lib/models/signing_data.dart @@ -28,4 +28,15 @@ class SigningData { Uint8List? output; ECPair? keyPair; Uint8List? redeemScript; + + @override + String toString() { + return "SigningData{\n" + " derivePathType: $derivePathType,\n" + " utxo: $utxo,\n" + " output: $output,\n" + " keyPair: $keyPair,\n" + " redeemScript: $redeemScript,\n" + "}"; + } }