From 652da68e257da55f681d21297023e473a353f35d Mon Sep 17 00:00:00 2001 From: Likho Date: Tue, 30 Aug 2022 07:26:45 -0500 Subject: [PATCH] Open wallet once and store instrance --- crypto_plugins/flutter_libepiccash | 2 +- .../coins/epiccash/epiccash_wallet.dart | 315 ++++++++---------- 2 files changed, 140 insertions(+), 177 deletions(-) diff --git a/crypto_plugins/flutter_libepiccash b/crypto_plugins/flutter_libepiccash index b9423d604..a1826673d 160000 --- a/crypto_plugins/flutter_libepiccash +++ b/crypto_plugins/flutter_libepiccash @@ -1 +1 @@ -Subproject commit b9423d604eca52f3ea3c3f1ded52c0ad07248837 +Subproject commit a1826673d6643c8ec24ad96ce538434a60c6e4fb diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart index c0cb9e4e9..d46512bfb 100644 --- a/lib/services/coins/epiccash/epiccash_wallet.dart +++ b/lib/services/coins/epiccash/epiccash_wallet.dart @@ -7,6 +7,7 @@ import 'package:decimal/decimal.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_libepiccash/epic_cash.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:hive/hive.dart'; import 'package:http/http.dart'; import 'package:mutex/mutex.dart'; import 'package:path_provider/path_provider.dart'; @@ -61,123 +62,110 @@ Future executeNative(Map arguments) async { final function = arguments['function'] as String; try { if (function == "scanOutPuts") { - final config = arguments['config'] as String?; - final password = arguments['password'] as String?; + final wallet = arguments['wallet'] as String?; final startHeight = arguments['startHeight'] as int?; final numberOfBlocks = arguments['numberOfBlocks'] as int?; Map result = {}; - if (!(config == null || - password == null || + if (!(wallet == null || startHeight == null || numberOfBlocks == null)) { var outputs = - await scanOutPuts(config, password, startHeight, numberOfBlocks); + await scanOutPuts(wallet, startHeight, numberOfBlocks); result['outputs'] = outputs; sendPort.send(result); return; } } else if (function == "getPendingSlates") { - final config = arguments['config'] as String?; - final password = arguments['password'] as String?; + final wallet = arguments['wallet'] as String?; final secretKeyIndex = arguments['secretKeyIndex'] as int?; final slates = arguments['slates'] as String; Map result = {}; - if (!(config == null || password == null || secretKeyIndex == null)) { + if (!(wallet == null || secretKeyIndex == null)) { Logging.instance .log("SECRET_KEY_INDEX_IS $secretKeyIndex", level: LogLevel.Info); result['result'] = - await getPendingSlates(config, password, secretKeyIndex, slates); + await getPendingSlates(wallet, secretKeyIndex, slates); sendPort.send(result); return; } } else if (function == "subscribeRequest") { - final config = arguments['config'] as String?; - final password = arguments['password'] as String?; + final wallet = arguments['wallet'] as String?; final secretKeyIndex = arguments['secretKeyIndex'] as int?; final epicboxConfig = arguments['epicboxConfig'] as String?; Map result = {}; - if (!(config == null || - password == null || + if (!(wallet == null || secretKeyIndex == null || epicboxConfig == null)) { Logging.instance .log("SECRET_KEY_INDEX_IS $secretKeyIndex", level: LogLevel.Info); result['result'] = await getSubscribeRequest( - config, password, secretKeyIndex, epicboxConfig); + wallet, secretKeyIndex, epicboxConfig); sendPort.send(result); return; } } else if (function == "processSlates") { - final config = arguments['config'] as String?; - final password = arguments['password'] as String?; + final wallet = arguments['wallet'] as String?; final slates = arguments['slates']; Map result = {}; - if (!(config == null || password == null || slates == null)) { + if (!(wallet == null || slates == null)) { result['result'] = - await processSlates(config, password, slates.toString()); + await processSlates(wallet, slates.toString()); sendPort.send(result); return; } } else if (function == "getWalletInfo") { - final config = arguments['config'] as String?; - final password = arguments['password'] as String?; + final wallet = arguments['wallet'] as String?; final refreshFromNode = arguments['refreshFromNode'] as int?; final minimumConfirmations = arguments['minimumConfirmations'] as int?; Map result = {}; - if (!(config == null || - password == null || + if (!(wallet == null || refreshFromNode == null || minimumConfirmations == null)) { var res = await getWalletInfo( - config, password, refreshFromNode, minimumConfirmations); + wallet, refreshFromNode, minimumConfirmations); result['result'] = res; sendPort.send(result); return; } } else if (function == "getTransactions") { - final config = arguments['config'] as String?; - final password = arguments['password'] as String?; + final wallet = arguments['wallet'] as String?; final refreshFromNode = arguments['refreshFromNode'] as int?; Map result = {}; - if (!(config == null || password == null || refreshFromNode == null)) { - var res = await getTransactions(config, password, refreshFromNode); + if (!(wallet == null || refreshFromNode == null)) { + var res = await getTransactions(wallet, refreshFromNode); result['result'] = res; sendPort.send(result); return; } } else if (function == "startSync") { - final config = arguments['config'] as String?; - final password = arguments['password'] as String?; + final wallet = arguments['wallet'] as String?; const int refreshFromNode = 1; Map result = {}; - if (!(config == null || password == null)) { - var res = await getWalletInfo(config, password, refreshFromNode, 10); + if (!(wallet == null)) { + var res = await getWalletInfo(wallet, refreshFromNode, 10); result['result'] = res; sendPort.send(result); return; } } else if (function == "getTransactionFees") { - final config = arguments['config'] as String?; - final password = arguments['password'] as String?; + final wallet = arguments['wallet'] as String?; final amount = arguments['amount'] as int?; final minimumConfirmations = arguments['minimumConfirmations'] as int?; Map result = {}; - if (!(config == null || - password == null || + if (!(wallet == null || amount == null || minimumConfirmations == null)) { var res = await getTransactionFees( - config, password, amount, minimumConfirmations); + wallet, amount, minimumConfirmations); result['result'] = res; sendPort.send(result); return; } } else if (function == "createTransaction") { - final config = arguments['config'] as String?; - final password = arguments['password'] as String?; + final wallet = arguments['wallet'] as String?; final amount = arguments['amount'] as int?; final address = arguments['address'] as String?; final secretKeyIndex = arguments['secretKeyIndex'] as int?; @@ -185,14 +173,13 @@ Future executeNative(Map arguments) async { final minimumConfirmations = arguments['minimumConfirmations'] as int?; Map result = {}; - if (!(config == null || - password == null || + if (!(wallet == null || amount == null || address == null || secretKeyIndex == null || epicboxConfig == null || minimumConfirmations == null)) { - var res = await createTransaction(config, password, amount, address, + var res = await createTransaction(wallet, amount, address, secretKeyIndex, epicboxConfig, minimumConfirmations); result['result'] = res; sendPort.send(result); @@ -225,14 +212,14 @@ void stop(ReceivePort port) { // Keep Wrapper functions outside of the class to avoid memory leaks and errors about receive ports and illegal arguments. // TODO: Can get rid of this wrapper and call it in a full isolate instead of compute() if we want more control over this Future _cancelTransactionWrapper( - Tuple3 data) async { + Tuple2 data) async { // assuming this returns an empty string on success // or an error message string on failure - return cancelTransaction(data.item1, data.item2, data.item3); + return cancelTransaction(data.item1, data.item2); } -Future _deleteWalletWrapper(Tuple2 data) async { - return deleteWallet(data.item1, data.item2); +Future _deleteWalletWrapper(String wallet) async { + return deleteWallet(wallet); } Future deleteEpicWallet({ @@ -255,9 +242,9 @@ Future deleteEpicWallet({ config = jsonEncode(editConfig); } - final password = await secureStore.read(key: '${walletId}_password'); + final wallet = await secureStore.read(key: '${walletId}_wallet'); - return compute(_deleteWalletWrapper, Tuple2(config!, password!)); + return compute(_deleteWalletWrapper, wallet!); } Future _initWalletWrapper( @@ -268,9 +255,9 @@ Future _initWalletWrapper( } Future _initGetAddressInfoWrapper( - Tuple4 data) async { + Tuple3 data) async { String walletAddress = - getAddressInfo(data.item1, data.item2, data.item3, data.item4); + getAddressInfo(data.item1, data.item2, data.item3); return walletAddress; } @@ -564,16 +551,14 @@ class EpicCashWallet extends CoinServiceAPI { Future startSync() async { Logging.instance.log("request start sync", level: LogLevel.Info); - final config = await getRealConfig(); - final password = await _secureStore.read(key: '${_walletId}_password'); + final wallet = await _secureStore.read(key: '${_walletId}_wallet'); if (!syncMutex.isLocked) { await syncMutex.protect(() async { Logging.instance.log("sync started", level: LogLevel.Info); ReceivePort receivePort = await getIsolate({ "function": "startSync", - "config": config, - "password": password!, + "wallet": wallet!, }, name: walletName); this.receivePort = receivePort; @@ -596,17 +581,14 @@ class EpicCashWallet extends CoinServiceAPI { } Future allWalletBalances() async { - final config = await getRealConfig(); - final password = await _secureStore.read(key: '${_walletId}_password'); - + final wallet = await _secureStore.read(key: '${_walletId}_wallet'); const refreshFromNode = 0; dynamic message; await m.protect(() async { ReceivePort receivePort = await getIsolate({ "function": "getWalletInfo", - "config": config, - "password": password!, + "wallet": wallet!, "refreshFromNode": refreshFromNode, "minimumConfirmations": MINIMUM_CONFIRMATIONS, }, name: walletName); @@ -652,9 +634,7 @@ class EpicCashWallet extends CoinServiceAPI { late PriceAPI _priceAPI; Future cancelPendingTransactionAndPost(String tx_slate_id) async { - final String config = await getRealConfig(); - final String password = - (await _secureStore.read(key: '${_walletId}_password'))!; + final wallet = await _secureStore.read(key: '${_walletId}_wallet'); final int? receivingIndex = DB.instance .get(boxName: walletId, key: "receivingIndex") as int?; final epicboxConfig = @@ -677,8 +657,7 @@ class EpicCashWallet extends CoinServiceAPI { await m.protect(() async { ReceivePort receivePort = await getIsolate({ "function": "subscribeRequest", - "config": config, - "password": password, + "wallet": wallet, "secretKeyIndex": currentReceivingIndex!, "epicboxConfig": epicboxConfig, }, name: walletName); @@ -713,17 +692,15 @@ class EpicCashWallet extends CoinServiceAPI { // /// returns an empty String on success, error message on failure Future cancelPendingTransaction(String tx_slate_id) async { - final String config = await getRealConfig(); - final String password = - (await _secureStore.read(key: '${_walletId}_password'))!; + final String wallet = + (await _secureStore.read(key: '${_walletId}_wallet'))!; String? result; await m.protect(() async { result = await compute( _cancelTransactionWrapper, - Tuple3( - config, - password, + Tuple2( + wallet, tx_slate_id, ), ); @@ -734,8 +711,7 @@ class EpicCashWallet extends CoinServiceAPI { @override Future confirmSend({required Map txData}) async { try { - final config = await getRealConfig(); - final password = await _secureStore.read(key: '${_walletId}_password'); + final wallet = await _secureStore.read(key: '${_walletId}_wallet'); final epicboxConfig = await _secureStore.read(key: '${_walletId}_epicboxConfig'); @@ -744,8 +720,7 @@ class EpicCashWallet extends CoinServiceAPI { await m.protect(() async { ReceivePort receivePort = await getIsolate({ "function": "createTransaction", - "config": config, - "password": password!, + "wallet": wallet!, "amount": txData['recipientAmt'], "address": txData['addresss'], "secretKeyIndex": 0, @@ -782,17 +757,18 @@ class EpicCashWallet extends CoinServiceAPI { txData['addresss'] as String, postSlateRequest as String); Logging.instance .log("POST_SLATE_IS $postToServer", level: LogLevel.Info); - //await postSlate final txCreateResult = decodeData[0]; // //TODO: second problem - final transaction = txCreateResult[0]; - - // final wallet = await Hive.openBox(_walletId); - // final slateToAddresses = (await wallet.get("slate_to_address")) as Map?; - // slateToAddresses![transaction[0]['tx_slate_id']] = txData['addresss']; - // await wallet.put('slate_to_address', slateToAddresses); - // return transaction[0]['tx_slate_id'] as String; - return ""; + final transaction = json.decode(txCreateResult as String); + final tx = transaction[0]; + final txLogEntry = json.decode(tx as String); + final txLogEntryFirst = txLogEntry[0]; + Logger.print("TX_LOG_ENTRY_IS $txLogEntryFirst"); + final wallet = await Hive.openBox(_walletId); + final slateToAddresses = (await wallet.get("slate_to_address")) as Map?; + slateToAddresses?[txLogEntryFirst['tx_slate_id']] = txData['addresss']; + await wallet.put('slate_to_address', slateToAddresses); + return txLogEntryFirst['tx_slate_id'] as String; } } catch (e, s) { Logging.instance.log("Error sending $e - $s", level: LogLevel.Error); @@ -806,8 +782,7 @@ class EpicCashWallet extends CoinServiceAPI { Future _getCurrentAddressForChain( int chain, ) async { - final config = await getRealConfig(); - final password = await _secureStore.read(key: '${_walletId}_password'); + final wallet = await _secureStore.read(key: '${_walletId}_wallet'); final epicboxConfig = await _secureStore.read(key: '${_walletId}_epicboxConfig'); @@ -815,7 +790,7 @@ class EpicCashWallet extends CoinServiceAPI { await m.protect(() async { walletAddress = await compute( _initGetAddressInfoWrapper, - Tuple4(config, password!, chain, epicboxConfig!), + Tuple3(wallet!, chain, epicboxConfig!), ); }); Logging.instance @@ -920,6 +895,13 @@ class EpicCashWallet extends CoinServiceAPI { Logging.instance.log("Opening existing ${coin.prettyName} wallet", level: LogLevel.Info); + final config = await getRealConfig(); + final password = + await _secureStore.read(key: '${_walletId}_password'); + + final walletOpen = openWallet(config!, password!); + await _secureStore.write(key: '${_walletId}_wallet', value: walletOpen); + if ((DB.instance.get(boxName: walletId, key: "id")) == null) { debugPrint("Exception was thrown"); throw Exception( @@ -937,8 +919,7 @@ class EpicCashWallet extends CoinServiceAPI { } Future storeEpicboxInfo() async { - final config = await getRealConfig(); - final password = await _secureStore.read(key: '${_walletId}_password'); + final wallet = await _secureStore.read(key: '${_walletId}_wallet'); int index = 0; Logging.instance.log("This index is $index", level: LogLevel.Info); @@ -948,7 +929,7 @@ class EpicCashWallet extends CoinServiceAPI { await m.protect(() async { walletAddress = await compute( _initGetAddressInfoWrapper, - Tuple4(config, password!, index, epicboxConfig!), + Tuple3(wallet!, index, epicboxConfig!), ); }); Logging.instance @@ -1008,6 +989,10 @@ class EpicCashWallet extends CoinServiceAPI { ); }); + //Open wallet + final walletOpen = openWallet(stringConfig, password); + await _secureStore.write(key: '${_walletId}_wallet', value: walletOpen); + //Store Epic box address info await storeEpicboxInfo(); @@ -1106,16 +1091,14 @@ class EpicCashWallet extends CoinServiceAPI { Future nativeFee(int satoshiAmount, {bool ifErrorEstimateFee = false}) async { - final config = await getRealConfig(); - final password = await _secureStore.read(key: '${_walletId}_password'); + final wallet = await _secureStore.read(key: '${_walletId}_wallet'); try { String? transactionFees; await m.protect(() async { ReceivePort receivePort = await getIsolate({ "function": "getTransactionFees", - "config": config, - "password": password!, + "wallet": wallet!, "amount": satoshiAmount, "minimumConfirmations": MINIMUM_CONFIRMATIONS, }, name: walletName); @@ -1241,8 +1224,8 @@ class EpicCashWallet extends CoinServiceAPI { Future startScans() async { try { - String stringConfig = await getConfig(); - final password = await _secureStore.read(key: '${_walletId}_password'); + + final wallet = await _secureStore.read(key: '${_walletId}_wallet'); var restoreHeight = DB.instance.get(boxName: walletId, key: "restoreHeight"); @@ -1272,8 +1255,7 @@ class EpicCashWallet extends CoinServiceAPI { await m.protect(() async { ReceivePort receivePort = await getIsolate({ "function": "scanOutPuts", - "config": stringConfig, - "password": password, + "wallet": wallet!, "startHeight": lastScannedBlock, "numberOfBlocks": MAX_PER_LOOP, }, name: walletName); @@ -1356,9 +1338,6 @@ class EpicCashWallet extends CoinServiceAPI { ), ); - //Store Epic box address info - await storeEpicboxInfo(); - await DB.instance .put(boxName: walletId, key: "restoreHeight", value: height); @@ -1387,27 +1366,13 @@ class EpicCashWallet extends CoinServiceAPI { await DB.instance .put(boxName: walletId, key: "isFavorite", value: false); - //Scan wallet - await m.protect(() async { - ReceivePort receivePort = await getIsolate({ - "function": "scanOutPuts", - "config": stringConfig, - "password": password, - "startHeight": 1550000, - "numberOfBlocks": 100, - }, name: walletName); + //Open Wallet + final walletOpen = openWallet(stringConfig, password); + await _secureStore.write(key: '${_walletId}_wallet', value: walletOpen); + + //Store Epic box address info + await storeEpicboxInfo(); - var message = await receivePort.first; - if (message is String) { - Logging.instance - .log("this is a string $message", level: LogLevel.Error); - stop(receivePort); - throw Exception("scanOutPuts isolate failed"); - } - stop(receivePort); - Logging.instance - .log('Closing scanOutPuts!\n $message', level: LogLevel.Info); - }); } catch (e, s) { Logging.instance .log("Error recovering wallet $e\n$s", level: LogLevel.Error); @@ -1588,16 +1553,14 @@ class EpicCashWallet extends CoinServiceAPI { currentReceivingIndex++) { final currentAddress = await _getCurrentAddressForChain(currentReceivingIndex); - final config = await getRealConfig(); - final password = await _secureStore.read(key: '${_walletId}_password'); + final wallet = await _secureStore.read(key: '${_walletId}_wallet'); final epicboxConfig = await _secureStore.read(key: '${_walletId}_epicboxConfig'); dynamic subscribeRequest; await m.protect(() async { ReceivePort receivePort = await getIsolate({ "function": "subscribeRequest", - "config": config, - "password": password, + "wallet": wallet, "secretKeyIndex": currentReceivingIndex, "epicboxConfig": epicboxConfig, }, name: walletName); @@ -1636,8 +1599,7 @@ class EpicCashWallet extends CoinServiceAPI { await m.protect(() async { ReceivePort receivePort = await getIsolate({ "function": "getPendingSlates", - "config": config, - "password": password, + "wallet": wallet!, "secretKeyIndex": currentReceivingIndex, "slates": encoded, }, name: walletName); @@ -1668,8 +1630,7 @@ class EpicCashWallet extends CoinServiceAPI { await m.protect(() async { ReceivePort receivePort = await getIsolate({ "function": "processSlates", - "config": config, - "password": password, + "wallet": wallet!, "slates": slateMessage }, name: walletName); @@ -1689,51 +1650,57 @@ class EpicCashWallet extends CoinServiceAPI { await deleteSlate(currentAddress, subscribeRequest['signature'] as String, slate as String); } - var decodedResponse = json.decode(response); - Logging.instance.log("PROCESS_SLATE_RESPONSE $response", + + Logging.instance.log("RESPONSE_FOR_PROCESS_IS $response", + level: LogLevel.Info); + Logging.instance.log("PROCESS_SLATE_RESPONSE $response", level: LogLevel.Info); - final processStatus = json.decode(decodedResponse[0] as String); - String slateStatus = processStatus['status'] as String; - // Logging.instance.log("THIS_TEXT $processStatus"); - if (slateStatus == "PendingProcessing") { - //Encrypt slate - // - String encryptedSlate = await getEncryptedSlate( - config, - password!, - slateSender, - currentReceivingIndex, - epicboxConfig!, - decodedResponse[1] as String); - - final postSlateToServer = - await postSlate(slateSender, encryptedSlate); - - await deleteSlate(currentAddress, - subscribeRequest['signature'] as String, slate as String); - Logging.instance.log("POST_SLATE_RESPONSE $postSlateToServer", + if (response.contains("Error Wallet store error: DB Not Found Error")) { + //Already processed - to be deleted + //TODO - DELETE ALREADY PROCESSED SLATE + Logging.instance.log("SLATE ALREADY PROCESSED - NEEDS TO BE DELETED $response", level: LogLevel.Info); } else { - //Finalise Slate - final processSlate = json.decode(decodedResponse[1] as String); - Logging.instance.log( - "PROCESSED_SLATE_TO_FINALIZE $processSlate", - level: LogLevel.Info); - final tx = json.decode(processSlate[0] as String); - Logging.instance.log("TX_IS $tx", level: LogLevel.Info); - String txSlateId = tx[0]['tx_slate_id'] as String; - Logging.instance - .log("TX_SLATE_ID_IS $txSlateId", level: LogLevel.Info); -// - final postToNode = await postSlateToNode( - config, password!, currentReceivingIndex, txSlateId); - await deleteSlate(currentAddress, - subscribeRequest['signature'] as String, slate as String); - Logging.instance.log("POST_SLATE_RESPONSE $postToNode", - level: LogLevel.Info); - //Post Slate to Node - Logging.instance.log("Finalise slate", level: LogLevel.Info); + var decodedResponse = json.decode(response); + final processStatus = json.decode(decodedResponse[0] as String); + String slateStatus = processStatus['status'] as String; + if (slateStatus == "PendingProcessing") { + //Encrypt slate + String encryptedSlate = await getEncryptedSlate( + wallet!, + slateSender, + currentReceivingIndex, + epicboxConfig!, + decodedResponse[1] as String); + + final postSlateToServer = + await postSlate(slateSender, encryptedSlate); + + await deleteSlate(currentAddress, + subscribeRequest['signature'] as String, slate as String); + Logging.instance.log("POST_SLATE_RESPONSE $postSlateToServer", + level: LogLevel.Info); + } else { + //Finalise Slate + final processSlate = json.decode(decodedResponse[1] as String); + Logging.instance.log( + "PROCESSED_SLATE_TO_FINALIZE $processSlate", + level: LogLevel.Info); + final tx = json.decode(processSlate[0] as String); + Logging.instance.log("TX_IS $tx", level: LogLevel.Info); + String txSlateId = tx[0]['tx_slate_id'] as String; + Logging.instance + .log("TX_SLATE_ID_IS $txSlateId", level: LogLevel.Info); + final postToNode = await postSlateToNode( + wallet!, txSlateId); + await deleteSlate(currentAddress, + subscribeRequest['signature'] as String, slate as String); + Logging.instance.log("POST_SLATE_RESPONSE $postToNode", + level: LogLevel.Info); + //Post Slate to Node + Logging.instance.log("Finalise slate", level: LogLevel.Info); + } } } catch (e, s) { Logging.instance.log("$e\n$s", level: LogLevel.Info); @@ -1751,8 +1718,7 @@ class EpicCashWallet extends CoinServiceAPI { Future processAllCancels() async { Logging.instance.log("processAllCancels", level: LogLevel.Info); - final config = await getRealConfig(); - final password = await _secureStore.read(key: '${_walletId}_password'); + final wallet = await _secureStore.read(key: '${_walletId}_wallet'); final epicboxConfig = await _secureStore.read(key: '${_walletId}_epicboxConfig'); final int? receivingIndex = DB.instance @@ -1768,8 +1734,7 @@ class EpicCashWallet extends CoinServiceAPI { await m.protect(() async { ReceivePort receivePort = await getIsolate({ "function": "subscribeRequest", - "config": config, - "password": password, + "wallet": wallet!, "secretKeyIndex": currentReceivingIndex, "epicboxConfig": epicboxConfig, }, name: walletName); @@ -2036,16 +2001,14 @@ class EpicCashWallet extends CoinServiceAPI { Future _fetchTransactionData() async { final currentChainHeight = await chainHeight; - final config = await getRealConfig(); - final password = await _secureStore.read(key: '${_walletId}_password'); + final wallet = await _secureStore.read(key: '${_walletId}_wallet'); const refreshFromNode = 0; dynamic message; await m.protect(() async { ReceivePort receivePort = await getIsolate({ "function": "getTransactions", - "config": config, - "password": password!, + "wallet": wallet!, "refreshFromNode": refreshFromNode, }, name: walletName);