diff --git a/lib/services/coins/epiccash/epiccash_wallet.dart b/lib/services/coins/epiccash/epiccash_wallet.dart index c5bae8bb7..fa2d3aa49 100644 --- a/lib/services/coins/epiccash/epiccash_wallet.dart +++ b/lib/services/coins/epiccash/epiccash_wallet.dart @@ -6,15 +6,15 @@ import 'dart:isolate'; import 'package:decimal/decimal.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_libepiccash/epic_cash.dart'; -import 'package:hive/hive.dart'; import 'package:http/http.dart'; +import 'package:isar/isar.dart'; import 'package:mutex/mutex.dart'; import 'package:stack_wallet_backup/generate_password.dart'; import 'package:stackwallet/hive/db.dart'; +import 'package:stackwallet/models/balance.dart'; +import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/node_model.dart'; import 'package:stackwallet/models/paymint/fee_object_model.dart'; -import 'package:stackwallet/models/paymint/transactions_model.dart'; -import 'package:stackwallet/models/paymint/utxo_model.dart'; import 'package:stackwallet/pages/settings_views/global_settings_view/manage_nodes_views/add_edit_node_view.dart'; import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/event_bus/events/global/blocks_remaining_event.dart'; @@ -24,11 +24,11 @@ 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/node_service.dart'; -import 'package:stackwallet/services/price.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; +import 'package:stackwallet/utilities/format.dart'; import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/prefs.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; @@ -383,8 +383,8 @@ Future getSlates(String receiveAddress, String signature) async { } } -Future postCancel( - String receiveAddress, String slate_id, signature, sendersAddress) async { +Future postCancel(String receiveAddress, String slateId, + String? signature, String sendersAddress) async { Logging.instance.log("postCancel", level: LogLevel.Info); final Client client = Client(); try { @@ -395,18 +395,18 @@ Future postCancel( "id": "0", 'receivingAddress': receiveAddress, "signature": signature, - 'slate': slate_id, + 'slate': slateId, "sendersAddress": sendersAddress, }); - final epicpost = await client.post( + final epicPost = await client.post( uri, headers: {'Content-Type': 'application/json'}, body: body, ); // TODO: should the following be removed for security reasons in production? - Logging.instance.log(epicpost.statusCode.toString(), level: LogLevel.Info); - Logging.instance.log(epicpost.body.toString(), level: LogLevel.Info); - final response = jsonDecode(epicpost.body.toString()); + Logging.instance.log(epicPost.statusCode.toString(), level: LogLevel.Info); + Logging.instance.log(epicPost.body.toString(), level: LogLevel.Info); + final response = jsonDecode(epicPost.body.toString()); if (response['status'] == 'success') { return true; } else { @@ -525,17 +525,16 @@ class EpicCashWallet extends CoinServiceAPI { NodeModel? _epicNode; + late Isar isar; + EpicCashWallet( {required String walletId, required String walletName, required Coin coin, - PriceAPI? priceAPI, required SecureStorageInterface secureStore}) { _walletId = walletId; _walletName = walletName; _coin = coin; - - _priceAPI = priceAPI ?? PriceAPI(Client()); _secureStore = secureStore; Logging.instance.log("$walletName isolate length: ${isolates.length}", @@ -580,18 +579,6 @@ class EpicCashWallet extends CoinServiceAPI { } } - @override - Future> get allOwnAddresses => - _allOwnAddresses ??= _fetchAllOwnAddresses(); - Future>? _allOwnAddresses; - - Future> _fetchAllOwnAddresses() async { - List addresses = []; - final ownAddress = await _getCurrentAddressForChain(0); - addresses.add(ownAddress); - return addresses; - } - late ReceivePort receivePort; Future startSync() async { @@ -655,19 +642,6 @@ class EpicCashWallet extends CoinServiceAPI { return walletBalances; } - @override - Future get availableBalance async { - String walletBalances = await allWalletBalances(); - var jsonBalances = json.decode(walletBalances); - final double spendable = - jsonBalances['amount_currently_spendable'] as double; - return Decimal.parse(spendable.toString()); - } - - @override - // TODO: implement balanceMinusMaxFee - Future get balanceMinusMaxFee => throw UnimplementedError(); - Timer? timer; late Coin _coin; @@ -676,9 +650,7 @@ class EpicCashWallet extends CoinServiceAPI { late SecureStorageInterface _secureStore; - late PriceAPI _priceAPI; - - Future cancelPendingTransactionAndPost(String tx_slate_id) async { + Future cancelPendingTransactionAndPost(String txSlateId) async { final wallet = await _secureStore.read(key: '${_walletId}_wallet'); final int? receivingIndex = DB.instance .get(boxName: walletId, key: "receivingIndex") as int?; @@ -686,8 +658,8 @@ class EpicCashWallet extends CoinServiceAPI { await _secureStore.read(key: '${_walletId}_epicboxConfig'); final slatesToCommits = await getSlatesToCommits(); - final receiveAddress = slatesToCommits[tx_slate_id]['to'] as String; - final sendersAddress = slatesToCommits[tx_slate_id]['from'] as String; + final receiveAddress = slatesToCommits[txSlateId]['to'] as String; + final sendersAddress = slatesToCommits[txSlateId]['from'] as String; int? currentReceivingIndex; for (int i = 0; i <= receivingIndex!; i++) { @@ -722,11 +694,10 @@ class EpicCashWallet extends CoinServiceAPI { String? signature = subscribeRequest['signature'] as String?; String? result; try { - result = await cancelPendingTransaction(tx_slate_id); + result = await cancelPendingTransaction(txSlateId); Logging.instance.log("result?: $result", level: LogLevel.Info); if (!(result.toLowerCase().contains("error"))) { - await postCancel( - receiveAddress, tx_slate_id, signature, sendersAddress); + await postCancel(receiveAddress, txSlateId, signature, sendersAddress); } } catch (e, s) { Logging.instance.log("$e, $s", level: LogLevel.Error); @@ -736,7 +707,7 @@ class EpicCashWallet extends CoinServiceAPI { // /// returns an empty String on success, error message on failure - Future cancelPendingTransaction(String tx_slate_id) async { + Future cancelPendingTransaction(String txSlateId) async { final String wallet = (await _secureStore.read(key: '${_walletId}_wallet'))!; @@ -746,7 +717,7 @@ class EpicCashWallet extends CoinServiceAPI { _cancelTransactionWrapper, Tuple2( wallet, - tx_slate_id, + txSlateId, ), ); }); @@ -847,12 +818,18 @@ class EpicCashWallet extends CoinServiceAPI { 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? ?? {}; + final slateToAddresses = DB.instance.get( + boxName: walletId, + key: "slate_to_address", + ) as Map? ?? + {}; final slateId = txLogEntryFirst['tx_slate_id'] as String; slateToAddresses[slateId] = txData['addresss']; - await wallet.put('slate_to_address', slateToAddresses); + await DB.instance.put( + boxName: walletId, + key: "slate_to_address", + value: slateToAddresses, + ); final slatesToCommits = await getSlatesToCommits(); String? commitId = slatesToCommits[slateId]?['commitId'] as String?; Logging.instance.log("sent commitId: $commitId", level: LogLevel.Info); @@ -979,6 +956,22 @@ class EpicCashWallet extends CoinServiceAPI { return; } + Future _isarInit() async { + isar = await Isar.open( + [ + isar_models.TransactionSchema, + isar_models.TransactionNoteSchema, + isar_models.InputSchema, + isar_models.OutputSchema, + isar_models.UTXOSchema, + isar_models.AddressSchema, + ], + directory: (await StackFileSystem.applicationIsarDirectory()).path, + inspector: false, + name: walletId, + ); + } + @override Future initializeExisting() async { Logging.instance.log("Opening existing ${coin.prettyName} wallet", @@ -998,12 +991,8 @@ class EpicCashWallet extends CoinServiceAPI { } await _prefs.init(); await updateNode(false); - final data = - DB.instance.get(boxName: walletId, key: "latest_tx_model") - as TransactionData?; - if (data != null) { - _transactionData = Future(() => data); - } + await _isarInit(); + await _refreshBalance(); // TODO: is there anything else that should be set up here whenever this wallet is first loaded again? } @@ -1148,15 +1137,6 @@ class EpicCashWallet extends CoinServiceAPI { @override Future> get mnemonic => _getMnemonicList(); - @override - Future get pendingBalance async { - String walletBalances = await allWalletBalances(); - final jsonBalances = json.decode(walletBalances); - final double pending = - jsonBalances['amount_awaiting_confirmation'] as double; - return Decimal.parse(pending.toString()); - } - @override Future> prepareSend( {required String address, @@ -1494,6 +1474,7 @@ class EpicCashWallet extends CoinServiceAPI { return latestHeight!; } + @override int get storedChainHeight { return DB.instance.get(boxName: walletId, key: "storedChainHeight") as int? ?? @@ -1676,7 +1657,7 @@ class EpicCashWallet extends CoinServiceAPI { currentAddress, subscribeRequest['signature'] as String); if (unprocessedSlates == null || unprocessedSlates is! List) { Logging.instance.log( - "index $currentReceivingIndex at $currentReceivingAddress does not have any slates", + "index $currentReceivingIndex at ${await currentReceivingAddress} does not have any slates", level: LogLevel.Info); continue; } @@ -1814,7 +1795,7 @@ class EpicCashWallet extends CoinServiceAPI { await _secureStore.read(key: '${_walletId}_epicboxConfig'); final int? receivingIndex = DB.instance .get(boxName: walletId, key: "receivingIndex") as int?; - final tData = await _transactionData; + for (int currentReceivingIndex = 0; receivingIndex != null && currentReceivingIndex <= receivingIndex; currentReceivingIndex++) { @@ -1847,16 +1828,16 @@ class EpicCashWallet extends CoinServiceAPI { final slatesToCommits = await getSlatesToCommits(); for (final cancel in cancels as List) { - final tx_slate_id = cancel.keys.first as String; - if (slatesToCommits[tx_slate_id] == null) { + final txSlateId = cancel.keys.first as String; + if (slatesToCommits[txSlateId] == null) { continue; } final cancelRequestSender = ((cancel as Map).values.first) as String; final receiveAddressFromMap = - slatesToCommits[tx_slate_id]['to'] as String; + slatesToCommits[txSlateId]['to'] as String; final sendersAddressFromMap = - slatesToCommits[tx_slate_id]['from'] as String; - final commitId = slatesToCommits[tx_slate_id]['commitId'] as String; + slatesToCommits[txSlateId]['from'] as String; + final commitId = slatesToCommits[txSlateId]['commitId'] as String; if (sendersAddressFromMap != cancelRequestSender) { Logging.instance.log("this was not signed by the correct address", @@ -1864,11 +1845,12 @@ class EpicCashWallet extends CoinServiceAPI { continue; } - String? result; try { - result = await cancelPendingTransaction(tx_slate_id); - if (tData?.findTransaction(commitId)?.isCancelled ?? false == true) { - await deleteCancels(receiveAddressFromMap, signature, tx_slate_id); + await cancelPendingTransaction(txSlateId); + final tx = + await isar.transactions.where().txidEqualTo(commitId).findFirst(); + if ((tx?.isCancelled ?? false) == true) { + await deleteCancels(receiveAddressFromMap, signature, txSlateId); } } catch (e, s) { Logging.instance.log("$e, $s", level: LogLevel.Error); @@ -1933,7 +1915,7 @@ class EpicCashWallet extends CoinServiceAPI { await processAllSlates(); await processAllCancels(); - startSync(); + unawaited(startSync()); GlobalEventBus.instance.fire(RefreshPercentChangedEvent(0.0, walletId)); @@ -1955,16 +1937,16 @@ class EpicCashWallet extends CoinServiceAPI { unawaited(updateStoredChainHeight(newHeight: currentHeight)); } - final newTxData = _fetchTransactionData(); + await _refreshTransactions(); GlobalEventBus.instance .fire(RefreshPercentChangedEvent(0.50, walletId)); - _transactionData = Future(() => newTxData); - GlobalEventBus.instance.fire(UpdatedInBackgroundEvent( "New data found in $walletName in background!", walletId)); } + await _refreshBalance(); + GlobalEventBus.instance.fire(RefreshPercentChangedEvent(1.0, walletId)); GlobalEventBus.instance.fire( WalletSyncStatusChangedEvent( @@ -2020,15 +2002,6 @@ class EpicCashWallet extends CoinServiceAPI { // TODO: do a quick check to see if there is any new data that would require a refresh } - @override - Future send( - {required String toAddress, - required int amount, - Map args = const {}}) { - // TODO: implement send - throw UnimplementedError(); - } - @override Future testNetworkConnection() async { try { @@ -2084,18 +2057,8 @@ class EpicCashWallet extends CoinServiceAPI { @override bool get isConnected => _isConnected; - @override - Future get totalBalance async { - String walletBalances = await allWalletBalances(); - var jsonBalances = json.decode(walletBalances); - double total = jsonBalances['total'] as double; - double awaiting = jsonBalances['amount_awaiting_finalization'] as double; - total = total + awaiting; - return Decimal.parse(total.toString()); - } - - Future _fetchTransactionData() async { - final currentChainHeight = await chainHeight; + Future _refreshTransactions() async { + // final currentChainHeight = await chainHeight; final wallet = await _secureStore.read(key: '${_walletId}_wallet'); const refreshFromNode = 0; @@ -2121,38 +2084,28 @@ class EpicCashWallet extends CoinServiceAPI { // return message; final String transactions = message['result'] as String; final jsonTransactions = json.decode(transactions) as List; - // for (var el in jsonTransactions) { - // Logging.instance.log("gettran: $el", - // normalLength: false, addToDebugMessagesDB: true); - // } - final priceData = - await _priceAPI.getPricesAnd24hChange(baseCurrency: _prefs.currency); - Decimal currentPrice = priceData[coin]?.item1 ?? Decimal.zero; - final List> midSortedArray = []; + final List midSortedArray = []; int latestTxnBlockHeight = DB.instance.get(boxName: walletId, key: "storedTxnDataHeight") as int? ?? 0; final slatesToCommits = await getSlatesToCommits(); - final cachedTransactions = - DB.instance.get(boxName: walletId, key: 'latest_tx_model') - as TransactionData?; - var cachedMap = cachedTransactions?.getAllTransactions(); + for (var tx in jsonTransactions) { Logging.instance.log("tx: $tx", level: LogLevel.Info); final txHeight = tx["kernel_lookup_min_height"] as int? ?? 0; - // TODO: does "confirmed" mean finalized? If so please remove this todo - final isConfirmed = tx["confirmed"] as bool; - // TODO: since we are now caching tx history in hive are we losing anything by skipping here? - // TODO: we can skip this filtering if it causes issues as the cache is later merged with updated data anyways - // this would just make processing and updating cache more efficient - if (txHeight > 0 && - txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS && - isConfirmed) { - continue; - } + // // TODO: does "confirmed" mean finalized? If so please remove this todo + // final isConfirmed = tx["confirmed"] as bool; + // // TODO: since we are now caching tx history in hive are we losing anything by skipping here? + // // TODO: we can skip this filtering if it causes issues as the cache is later merged with updated data anyways + // // this would just make processing and updating cache more efficient + // if (txHeight > 0 && + // txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS && + // isConfirmed) { + // continue; + // } // Logging.instance.log("Transactions listed below"); // Logging.instance.log(jsonTransactions); int amt = 0; @@ -2165,20 +2118,18 @@ class EpicCashWallet extends CoinServiceAPI { int fee = int.parse((tx['fee'] ?? "0") as String); amt = debit - credit - fee; } - final String worthNow = - (currentPrice * Decimal.parse(amt.toString())).toStringAsFixed(2); DateTime dt = DateTime.parse(tx["creation_ts"] as String); - Map midSortedTx = {}; - midSortedTx["txType"] = (tx["tx_type"] == "TxReceived" || + final txn = isar_models.Transaction(); + txn.type = (tx["tx_type"] == "TxReceived" || tx["tx_type"] == "TxReceivedCancelled") - ? "Received" - : "Sent"; + ? isar_models.TransactionType.incoming + : isar_models.TransactionType.outgoing; + String? slateId = tx['tx_slate_id'] as String?; String? address = slatesToCommits[slateId] - ?[midSortedTx["txType"] == "TxReceived" ? "from" : "to"] - as String? ?? + ?[tx["tx_type"] == "TxReceived" ? "from" : "to"] as String? ?? ""; String? commitId = slatesToCommits[slateId]?['commitId'] as String?; Logging.instance.log( @@ -2188,116 +2139,99 @@ class EpicCashWallet extends CoinServiceAPI { bool isCancelled = tx["tx_type"] == "TxSentCancelled" || tx["tx_type"] == "TxReceivedCancelled"; - midSortedTx["slateId"] = slateId; - midSortedTx["isCancelled"] = isCancelled; - midSortedTx["txid"] = commitId ?? tx["id"].toString(); - midSortedTx["confirmed_status"] = isConfirmed; - midSortedTx["timestamp"] = (dt.millisecondsSinceEpoch ~/ 1000); - midSortedTx["amount"] = amt; - midSortedTx["worthNow"] = worthNow; - midSortedTx["worthAtBlockTimestamp"] = worthNow; - midSortedTx["fees"] = - (tx["fee"] == null) ? 0 : int.parse(tx["fee"] as String); - midSortedTx["address"] = + txn.slateId = slateId; + txn.isCancelled = isCancelled; + txn.txid = commitId ?? tx["id"].toString(); + txn.timestamp = (dt.millisecondsSinceEpoch ~/ 1000); + txn.amount = amt; + txn.fee = (tx["fee"] == null) ? 0 : int.parse(tx["fee"] as String); + txn.address = ""; // for this when you send a transaction you will just need to save in a hashmap in hive with the key being the txid, and the value being the address it was sent to. then you can look this value up right here in your hashmap. - midSortedTx["address"] = address; - midSortedTx["height"] = txHeight; - int confirmations = 0; - try { - confirmations = currentChainHeight - txHeight; - } catch (e, s) { - //todo: come back to this - debugPrint("$e $s"); - } - midSortedTx["confirmations"] = confirmations; + txn.address = address; + txn.height = txHeight; - midSortedTx["inputSize"] = tx["num_inputs"]; - midSortedTx["outputSize"] = tx["num_outputs"]; - midSortedTx["aliens"] = []; - midSortedTx["inputs"] = []; - midSortedTx["outputs"] = []; - midSortedTx["tx_slate_id"] = tx["tx_slate_id"]; - midSortedTx["key_id"] = tx["parent_key_id"]; - midSortedTx["otherData"] = tx["id"].toString(); + // + // midSortedTx["inputSize"] = tx["num_inputs"]; + // midSortedTx["outputSize"] = tx["num_outputs"]; + // midSortedTx["aliens"] = []; + // midSortedTx["inputs"] = []; + // midSortedTx["outputs"] = []; + + // key id not used afaik? + // midSortedTx["key_id"] = tx["parent_key_id"]; + + txn.otherData = tx["id"].toString(); if (txHeight >= latestTxnBlockHeight) { latestTxnBlockHeight = txHeight; } - midSortedArray.add(midSortedTx); - cachedMap?.remove(tx["id"].toString()); - cachedMap?.remove(commitId); - Logging.instance.log("cmap: $cachedMap", level: LogLevel.Info); + midSortedArray.add(txn); + // cachedMap?.remove(tx["id"].toString()); + // cachedMap?.remove(commitId); + // Logging.instance.log("cmap: $cachedMap", level: LogLevel.Info); } - midSortedArray - .sort((a, b) => (b["timestamp"] as int) - (a["timestamp"] as int)); + await isar + .writeTxn(() async => await isar.transactions.putAll(midSortedArray)); - final Map result = {"dateTimeChunks": []}; - final dateArray = []; - - for (int i = 0; i < midSortedArray.length; i++) { - final txObject = midSortedArray[i]; - final date = extractDateFromTimestamp(txObject["timestamp"] as int); - - final txTimeArray = [txObject["timestamp"], date]; - - if (dateArray.contains(txTimeArray[1])) { - result["dateTimeChunks"].forEach((dynamic chunk) { - if (extractDateFromTimestamp(chunk["timestamp"] as int) == - txTimeArray[1]) { - if (chunk["transactions"] == null) { - chunk["transactions"] = >[]; - } - chunk["transactions"].add(txObject); - } - }); - } else { - dateArray.add(txTimeArray[1]); - - final chunk = { - "timestamp": txTimeArray[0], - "transactions": [txObject], - }; - - // result["dateTimeChunks"]. - result["dateTimeChunks"].add(chunk); - } - } - final transactionsMap = - TransactionData.fromJson(result).getAllTransactions(); - if (cachedMap != null) { - transactionsMap.addAll(cachedMap); - } - - final txModel = TransactionData.fromMap(transactionsMap); - - await DB.instance.put( - boxName: walletId, - key: 'storedTxnDataHeight', - value: latestTxnBlockHeight); - await DB.instance.put( - boxName: walletId, key: 'latest_tx_model', value: txModel); - - return txModel; + // midSortedArray + // .sort((a, b) => (b["timestamp"] as int) - (a["timestamp"] as int)); + // + // final Map result = {"dateTimeChunks": []}; + // final dateArray = []; + // + // for (int i = 0; i < midSortedArray.length; i++) { + // final txObject = midSortedArray[i]; + // final date = extractDateFromTimestamp(txObject["timestamp"] as int); + // + // final txTimeArray = [txObject["timestamp"], date]; + // + // if (dateArray.contains(txTimeArray[1])) { + // result["dateTimeChunks"].forEach((dynamic chunk) { + // if (extractDateFromTimestamp(chunk["timestamp"] as int) == + // txTimeArray[1]) { + // if (chunk["transactions"] == null) { + // chunk["transactions"] = >[]; + // } + // chunk["transactions"].add(txObject); + // } + // }); + // } else { + // dateArray.add(txTimeArray[1]); + // + // final chunk = { + // "timestamp": txTimeArray[0], + // "transactions": [txObject], + // }; + // + // // result["dateTimeChunks"]. + // result["dateTimeChunks"].add(chunk); + // } + // } + // final transactionsMap = + // TransactionData.fromJson(result).getAllTransactions(); + // if (cachedMap != null) { + // transactionsMap.addAll(cachedMap); + // } + // + // final txModel = TransactionData.fromMap(transactionsMap); + // + // await DB.instance.put( + // boxName: walletId, + // key: 'storedTxnDataHeight', + // value: latestTxnBlockHeight); + // await DB.instance.put( + // boxName: walletId, key: 'latest_tx_model', value: txModel); + // + // return txModel; } - @override - Future get transactionData => - _transactionData ??= _fetchTransactionData(); - Future? _transactionData; - - // not used in epic - TransactionData? cachedTxData; - @override Future updateSentCachedTxData(Map txData) async { // not used in epic } - @override - Future> get unspentOutputs => throw UnimplementedError(); - @override bool validateAddress(String address) { if (address.startsWith("http://") || address.startsWith("https://")) { @@ -2345,7 +2279,6 @@ class EpicCashWallet extends CoinServiceAPI { @override Future estimateFeeFor(int satoshiAmount, int feeRate) async { int currentFee = await nativeFee(satoshiAmount, ifErrorEstimateFee: true); - // TODO: implement this return currentFee; } @@ -2353,18 +2286,6 @@ class EpicCashWallet extends CoinServiceAPI { @override Future generateNewAddress() async { try { - // await incrementAddressIndexForChain( - // 0); // First increment the receiving index - // final newReceivingIndex = - // DB.instance.get(boxName: walletId, key: 'receivingIndex') - // as int; // Check the new receiving index - // final newReceivingAddress = await _generateAddressForChain(0, - // newReceivingIndex); // Use new index to derive a new receiving address - // await addToAddressesArrayForChain(newReceivingAddress, - // 0); // Add that new receiving address to the array of receiving addresses - // _currentReceivingAddress = Future(() => - // newReceivingAddress); // Set the new receiving address that the service - return true; } catch (e, s) { Logging.instance.log( @@ -2373,4 +2294,47 @@ class EpicCashWallet extends CoinServiceAPI { return false; } } + + Future _refreshBalance() async { + String walletBalances = await allWalletBalances(); + var jsonBalances = json.decode(walletBalances); + + final spendable = + (jsonBalances['amount_currently_spendable'] as double).toString(); + + final pending = + (jsonBalances['amount_awaiting_confirmation'] as double).toString(); + + final total = (jsonBalances['total'] as double).toString(); + final awaiting = + (jsonBalances['amount_awaiting_finalization'] as double).toString(); + + _balance = Balance( + coin: coin, + total: Format.decimalAmountToSatoshis( + Decimal.parse(total) + Decimal.parse(awaiting), + coin, + ), + spendable: Format.decimalAmountToSatoshis( + Decimal.parse(spendable), + coin, + ), + blockedTotal: 0, + pendingSpendable: Format.decimalAmountToSatoshis( + Decimal.parse(pending), + coin, + ), + ); + } + + @override + Balance get balance => _balance!; + Balance? _balance; + + @override + Future> get utxos => throw UnimplementedError(); + + @override + Future> get transactions => + isar.transactions.where().findAll(); }