WIP tx parse + link address to transaction

This commit is contained in:
julian 2023-01-13 11:11:41 -06:00
parent 13e6fc6b47
commit 52d5ab0d33
13 changed files with 118 additions and 348 deletions

View file

@ -1,5 +1,6 @@
import 'package:isar/isar.dart';
import 'package:stackwallet/models/isar/models/address/crypto_currency_address.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
import 'package:stackwallet/services/coins/coin_paynym_extension.dart';
part 'address.g.dart';
@ -12,7 +13,7 @@ class AddressException extends SWException {
class Address extends CryptoCurrencyAddress {
Id id = Isar.autoIncrement;
@Index(unique: true, replace: true)
@Index(unique: true)
late String value;
late List<byte> publicKey;
@ -26,6 +27,8 @@ class Address extends CryptoCurrencyAddress {
@enumerated
late AddressSubType subType;
final transaction = IsarLink<Transaction>();
int derivationChain() {
if (subType == AddressSubType.receiving) {
return 0; // 0 for receiving (external)

View file

@ -1,6 +1,7 @@
import 'dart:math';
import 'package:isar/isar.dart';
import 'package:stackwallet/models/isar/models/address/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/models/isar/models/transaction_note.dart';
@ -11,7 +12,7 @@ part 'transaction.g.dart';
class Transaction {
Id id = Isar.autoIncrement;
@Index(unique: true, replace: true)
@Index(unique: true)
late String txid;
@Index()
@ -30,8 +31,6 @@ class Transaction {
late int fee;
late String address;
late int? height;
late bool isCancelled;
@ -42,6 +41,9 @@ class Transaction {
late String? otherData;
@Backlink(to: "transaction")
final address = IsarLink<Address>();
final inputs = IsarLinks<Input>();
final outputs = IsarLinks<Output>();

View file

@ -4,11 +4,13 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/contact.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/transaction.dart';
import 'package:stackwallet/models/transaction_filter.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/transaction_details_view.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_search_filter_view.dart';
import 'package:stackwallet/providers/blockchain/dogecoin/current_height_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';
@ -33,9 +35,6 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
import 'package:stackwallet/widgets/transaction_card.dart';
import 'package:tuple/tuple.dart';
import '../../../models/isar/models/blockchain_data/transaction.dart';
import '../../../providers/blockchain/dogecoin/current_height_provider.dart';
class AllTransactionsView extends ConsumerStatefulWidget {
const AllTransactionsView({
Key? key,
@ -137,7 +136,8 @@ class _TransactionDetailsViewState extends ConsumerState<AllTransactionsView> {
.isNotEmpty;
// check if address contains
contains |= tx.address.toLowerCase().contains(keyword);
contains |=
tx.address.value?.value.toLowerCase().contains(keyword) ?? false;
// check if note contains
contains |= notes[tx.txid] != null &&

View file

@ -610,13 +610,15 @@ class _TransactionDetailsViewState
TransactionType.incoming
? FutureBuilder(
future: fetchContactNameFor(
_transaction.address),
_transaction.address
.value!.value),
builder: (builderContext,
AsyncSnapshot<String>
snapshot) {
String
addressOrContactName =
_transaction.address;
_transaction.address
.value!.value;
if (snapshot.connectionState ==
ConnectionState
.done &&
@ -644,7 +646,8 @@ class _TransactionDetailsViewState
},
)
: SelectableText(
_transaction.address,
_transaction
.address.value!.value,
style: isDesktop
? STextStyles
.desktopTextExtraExtraSmall(
@ -665,7 +668,7 @@ class _TransactionDetailsViewState
),
if (isDesktop)
IconCopyButton(
data: _transaction.address,
data: _transaction.address.value!.value,
),
],
),

View file

@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:bech32/bech32.dart';
@ -2011,78 +2012,39 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB {
final List<isar_models.Address> allAddresses =
await _fetchAllOwnAddresses();
// final changeAddresses = DB.instance.get<dynamic>(
// boxName: walletId, key: 'changeAddressesP2WPKH') as List<dynamic>;
// final changeAddressesP2PKH =
// DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2PKH')
// as List<dynamic>;
// final changeAddressesP2SH =
// DB.instance.get<dynamic>(boxName: walletId, key: 'changeAddressesP2SH')
// as List<dynamic>;
//
// for (var i = 0; i < changeAddressesP2PKH.length; i++) {
// changeAddresses.add(changeAddressesP2PKH[i] as String);
// }
// for (var i = 0; i < changeAddressesP2SH.length; i++) {
// changeAddresses.add(changeAddressesP2SH[i] as String);
// }
final receivingAddresses = allAddresses
.where((e) => e.subType == isar_models.AddressSubType.receiving);
final changeAddresses = allAddresses
.where((e) => e.subType == isar_models.AddressSubType.change);
final List<Map<String, dynamic>> allTxHashes =
await _fetchHistory(allAddresses.map((e) => e.value).toList());
final List<Map<String, dynamic>> allReceivingTxHashes =
await _fetchHistory(receivingAddresses.map((e) => e.value).toList());
// final cachedTransactions =
// DB.instance.get<dynamic>(boxName: walletId, key: 'latest_tx_model')
// as TransactionData?;
// int latestTxnBlockHeight =
// DB.instance.get<dynamic>(boxName: walletId, key: "storedTxnDataHeight")
// as int? ??
// 0;
// final unconfirmedCachedTransactions =
// cachedTransactions?.getAllTransactions() ?? {};
// unconfirmedCachedTransactions
// .removeWhere((key, value) => value.confirmedStatus);
//
// if (cachedTransactions != null) {
// for (final tx in allTxHashes.toList(growable: false)) {
// final txHeight = tx["height"] as int;
// if (txHeight > 0 &&
// txHeight < latestTxnBlockHeight - MINIMUM_CONFIRMATIONS) {
// if (unconfirmedCachedTransactions[tx["tx_hash"] as String] == null) {
// allTxHashes.remove(tx);
// }
// }
// }
// }
//
// // prefetch/cache
// Set<String> hashes = {};
// for (var element in allTxHashes) {
// for (var element in allReceivingTxHashes) {
// hashes.add(element['tx_hash'] as String);
// }
List<String> hashes =
allTxHashes.map((e) => e['tx_hash'] as String).toList(growable: false);
await fastFetch(hashes.toList());
// await fastFetch(hashes.toList());
List<Map<String, dynamic>> allTransactions = [];
for (final txHash in allTxHashes) {
for (final txHash in allReceivingTxHashes) {
final tx = await cachedElectrumXClient.getTransaction(
txHash: txHash["tx_hash"] as String,
verbose: true,
coin: coin,
);
if (!_duplicateTxCheck(allTransactions, tx["txid"] as String)) {
tx["address"] = txHash["address"];
// if (!_duplicateTxCheck(allTransactions, tx["txid"] as String)) {
tx["address"] = await isar.addresses
.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);
Set<String> vHashes = {};
for (final txObject in allTransactions) {
@ -2094,7 +2056,14 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB {
}
await fastFetch(vHashes.toList());
final List<isar_models.Transaction> txns = [];
for (final txObject in allTransactions) {
final pretty = const JsonEncoder.withIndent(" ").convert(txObject);
print("=========================================================");
log(pretty);
final txn = await parseTransaction(
txObject,
cachedElectrumXClient,
@ -2103,260 +2072,11 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB {
MINIMUM_CONFIRMATIONS,
);
// final tx = await isar.transactions
// .filter()
// .txidMatches(midSortedTx.txid)
// .findFirst();
// // we don't need to check this but it saves a write tx instead of overwriting the transaction in Isar
// if (tx == null) {
await isar.writeTxn(() async {
await isar.transactions.put(txn);
});
// }
// List<String> sendersArray = [];
// List<String> recipientsArray = [];
//
// // Usually only has value when txType = 'Send'
// int inputAmtSentFromWallet = 0;
// // Usually has value regardless of txType due to change addresses
// int outputAmtAddressedToWallet = 0;
// int fee = 0;
//
// Map<String, dynamic> midSortedTx = {};
//
// for (int i = 0; i < (txObject["vin"] as List).length; i++) {
// final input = txObject["vin"]![i] as Map;
// final prevTxid = input["txid"] as String;
// final prevOut = input["vout"] as int;
//
// final tx = await _cachedElectrumXClient.getTransaction(
// txHash: prevTxid,
// coin: coin,
// );
//
// for (final out in tx["vout"] as List) {
// if (prevOut == out["n"]) {
// final address = out["scriptPubKey"]["address"] as String?;
// if (address != null) {
// sendersArray.add(address);
// }
// }
// }
// }
//
// Logging.instance.log("sendersArray: $sendersArray", level: LogLevel.Info);
//
// for (final output in txObject["vout"] as List) {
// final address = output["scriptPubKey"]["address"] as String?;
// if (address != null) {
// recipientsArray.add(address);
// }
// }
//
// Logging.instance
// .log("recipientsArray: $recipientsArray", level: LogLevel.Info);
//
// final foundInSenders =
// allAddresses.any((element) => sendersArray.contains(element));
// Logging.instance
// .log("foundInSenders: $foundInSenders", level: LogLevel.Info);
//
// // If txType = Sent, then calculate inputAmtSentFromWallet
// if (foundInSenders) {
// int totalInput = 0;
// for (int i = 0; i < (txObject["vin"] as List).length; i++) {
// final input = txObject["vin"]![i] as Map;
// final prevTxid = input["txid"] as String;
// final prevOut = input["vout"] as int;
// final tx = await _cachedElectrumXClient.getTransaction(
// txHash: prevTxid,
// coin: coin,
// );
//
// for (final out in tx["vout"] as List) {
// if (prevOut == out["n"]) {
// inputAmtSentFromWallet +=
// (Decimal.parse(out["value"]!.toString()) *
// Decimal.fromInt(Constants.satsPerCoin(coin)))
// .toBigInt()
// .toInt();
// }
// }
// }
// totalInput = inputAmtSentFromWallet;
// int totalOutput = 0;
//
// for (final output in txObject["vout"] as List) {
// final String address = output["scriptPubKey"]!["address"] as String;
// final value = output["value"]!;
// final _value = (Decimal.parse(value.toString()) *
// Decimal.fromInt(Constants.satsPerCoin(coin)))
// .toBigInt()
// .toInt();
// totalOutput += _value;
// if (changeAddresses.contains(address)) {
// inputAmtSentFromWallet -= _value;
// } else {
// // change address from 'sent from' to the 'sent to' address
// txObject["address"] = address;
// }
// }
// // calculate transaction fee
// fee = totalInput - totalOutput;
// // subtract fee from sent to calculate correct value of sent tx
// inputAmtSentFromWallet -= fee;
// } else {
// // counters for fee calculation
// int totalOut = 0;
// int totalIn = 0;
//
// // add up received tx value
// for (final output in txObject["vout"] as List) {
// final address = output["scriptPubKey"]["address"];
// if (address != null) {
// final value = (Decimal.parse(output["value"].toString()) *
// Decimal.fromInt(Constants.satsPerCoin(coin)))
// .toBigInt()
// .toInt();
// totalOut += value;
// if (allAddresses.contains(address)) {
// outputAmtAddressedToWallet += value;
// }
// }
// }
//
// // calculate fee for received tx
// for (int i = 0; i < (txObject["vin"] as List).length; i++) {
// final input = txObject["vin"][i] as Map;
// final prevTxid = input["txid"] as String;
// final prevOut = input["vout"] as int;
// final tx = await _cachedElectrumXClient.getTransaction(
// txHash: prevTxid,
// coin: coin,
// );
//
// for (final out in tx["vout"] as List) {
// if (prevOut == out["n"]) {
// totalIn += (Decimal.parse(out["value"].toString()) *
// Decimal.fromInt(Constants.satsPerCoin(coin)))
// .toBigInt()
// .toInt();
// }
// }
// }
// fee = totalIn - totalOut;
// }
//
// // create final tx map
// midSortedTx["txid"] = txObject["txid"];
// midSortedTx["confirmed_status"] = (txObject["confirmations"] != null) &&
// (txObject["confirmations"] as int >= MINIMUM_CONFIRMATIONS);
// midSortedTx["confirmations"] = txObject["confirmations"] ?? 0;
// midSortedTx["timestamp"] = txObject["blocktime"] ??
// (DateTime.now().millisecondsSinceEpoch ~/ 1000);
//
// if (foundInSenders) {
// midSortedTx["txType"] = "Sent";
// midSortedTx["amount"] = inputAmtSentFromWallet;
// final String worthNow =
// ((currentPrice * Decimal.fromInt(inputAmtSentFromWallet)) /
// Decimal.fromInt(Constants.satsPerCoin(coin)))
// .toDecimal(scaleOnInfinitePrecision: 2)
// .toStringAsFixed(2);
// midSortedTx["worthNow"] = worthNow;
// midSortedTx["worthAtBlockTimestamp"] = worthNow;
// } else {
// midSortedTx["txType"] = "Received";
// midSortedTx["amount"] = outputAmtAddressedToWallet;
// final worthNow =
// ((currentPrice * Decimal.fromInt(outputAmtAddressedToWallet)) /
// Decimal.fromInt(Constants.satsPerCoin(coin)))
// .toDecimal(scaleOnInfinitePrecision: 2)
// .toStringAsFixed(2);
// midSortedTx["worthNow"] = worthNow;
// }
// midSortedTx["aliens"] = <dynamic>[];
// midSortedTx["fees"] = fee;
// midSortedTx["address"] = txObject["address"];
// midSortedTx["inputSize"] = txObject["vin"].length;
// midSortedTx["outputSize"] = txObject["vout"].length;
// midSortedTx["inputs"] = txObject["vin"];
// midSortedTx["outputs"] = txObject["vout"];
//
// final int height = txObject["height"] as int;
// midSortedTx["height"] = height;
//
// if (height >= latestTxnBlockHeight) {
// latestTxnBlockHeight = height;
// }
//
// midSortedArray.add(midSortedTx);
txns.add(txn);
}
// // sort by date ---- //TODO not sure if needed
// // shouldn't be any issues with a null timestamp but I got one at some point?
// midSortedArray
// .sort((a, b) => (b["timestamp"] as int) - (a["timestamp"] as int));
// // {
// // final aT = a["timestamp"];
// // final bT = b["timestamp"];
// //
// // if (aT == null && bT == null) {
// // return 0;
// // } else if (aT == null) {
// // return -1;
// // } else if (bT == null) {
// // return 1;
// // } else {
// // return bT - aT;
// // }
// // });
//
// // buildDateTimeChunks
// final Map<String, dynamic> result = {"dateTimeChunks": <dynamic>[]};
// final dateArray = <dynamic>[];
//
// 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"] = <Map<String, dynamic>>[];
// }
// chunk["transactions"].add(txObject);
// }
// });
// } else {
// dateArray.add(txTimeArray[1]);
// final chunk = {
// "timestamp": txTimeArray[0],
// "transactions": [txObject],
// };
// result["dateTimeChunks"].add(chunk);
// }
// }
//
// final transactionsMap = cachedTransactions?.getAllTransactions() ?? {};
// transactionsMap
// .addAll(TransactionData.fromJson(result).getAllTransactions());
//
// final txModel = TransactionData.fromMap(transactionsMap);
//
// await DB.instance.put<dynamic>(
// boxName: walletId,
// key: 'storedTxnDataHeight',
// value: latestTxnBlockHeight);
// await DB.instance.put<dynamic>(
// boxName: walletId, key: 'latest_tx_model', value: txModel);
//
// cachedTxData = txModel;
// return txModel;
await isar.writeTxn(() async {
await isar.transactions.putAll(txns);
});
}
int estimateTxFee({required int vSize, required int feeRatePerKB}) {
@ -3017,6 +2737,11 @@ class BitcoinWallet extends CoinServiceAPI with WalletCache, WalletDB {
// back up data
// await _rescanBackup();
await isar.writeTxn(() async {
await isar.transactions.clear();
await isar.addresses.clear();
});
try {
final mnemonic = await _secureStore.read(key: '${_walletId}_mnemonic');
await _recoverWalletFromBIP32SeedPhrase(

View file

@ -1949,7 +1949,10 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB {
// Logging.instance.log("TRANSACTION: ${jsonEncode(tx)}");
if (!_duplicateTxCheck(allTransactions, tx["txid"] as String)) {
tx["address"] = txHash["address"];
tx["address"] = await isar.addresses
.filter()
.valueEqualTo(txHash["address"] as String)
.findFirst();
tx["height"] = txHash["height"];
allTransactions.add(tx);
}
@ -2076,7 +2079,7 @@ class BitcoinCashWallet extends CoinServiceAPI with WalletCache, WalletDB {
tx.subType = isar_models.TransactionSubType.none;
tx.fee = fee;
tx.address = txData["address"] as String;
tx.address.value = txData["address"] as isar_models.Address;
for (final json in txData["vin"] as List) {
bool isCoinBase = json['coinbase'] != null;

View file

@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:developer';
import 'dart:typed_data';
import 'package:bip47/bip47.dart';
@ -669,6 +670,10 @@ Future<Transaction> parseTransaction(
tx.timestamp = txData["blocktime"] as int? ??
(DateTime.now().millisecondsSinceEpoch ~/ 1000);
// this should be the address we used to originally fetch the tx so we should
// be able to easily figure out if the tx is a send or receive
tx.address.value = txData["address"] as Address;
if (mySentFromAddresses.isNotEmpty && myReceivedOnAddresses.isNotEmpty) {
// tx is sent to self
tx.type = TransactionType.sentToSelf;
@ -688,7 +693,11 @@ Future<Transaction> parseTransaction(
tx.subType = TransactionSubType.none;
tx.fee = fee;
tx.address = txData["address"] as String;
log("tx.address: ${tx.address}");
log("mySentFromAddresses: $mySentFromAddresses");
log("myReceivedOnAddresses: $myReceivedOnAddresses");
log("myChangeReceivedOnAddresses: $myChangeReceivedOnAddresses");
for (final json in txData["vin"] as List) {
bool isCoinBase = json['coinbase'] != null;

View file

@ -2041,9 +2041,10 @@ class EpicCashWallet extends CoinServiceAPI
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.
txn.address = address;
// 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.
txn.address.value =
await isar.addresses.filter().valueEqualTo(address).findFirst();
txn.height = txHeight;
//

View file

@ -425,7 +425,7 @@ Future<Map<dynamic, dynamic>> staticProcessRestore(
..fee = sharedFee
..inputs.addAll(element.inputs)
..outputs.addAll(element.outputs)
..address = element.address
..address.value = element.address.value
..height = element.height
..subType = isar_models.TransactionSubType.mint
..otherData = txid
@ -2955,7 +2955,10 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive {
Decimal.parse(transactionInfo["amount"].toString()), coin)
..fee = Format.decimalAmountToSatoshis(
Decimal.parse(transactionInfo["fees"].toString()), coin)
..address = transactionInfo["address"] as String
..address.value = await isar.addresses
.filter()
.valueEqualTo(transactionInfo["address"] as String)
.findFirst()
..height = transactionInfo["height"] as int?
..subType = transactionInfo["subType"] == "mint"
? isar_models.TransactionSubType.mint
@ -4731,7 +4734,10 @@ class FiroWallet extends CoinServiceAPI with WalletCache, WalletDB, FiroHive {
..subType = isar_models.TransactionSubType.join
..fee = Format.decimalAmountToSatoshis(
Decimal.parse(tx["fees"].toString()), coin)
..address = tx["address"] as String
..address.value = await isar.addresses
.filter()
.valueEqualTo(tx["address"] as String)
.findFirst()
..amount = Format.decimalAmountToSatoshis(
Decimal.parse(tx["amount"].toString()), coin)
..isCancelled = false

View file

@ -868,15 +868,21 @@ class MoneroWallet extends CoinServiceAPI with WalletCache, WalletDB {
if (tx.value.direction == TransactionDirection.incoming) {
final addressInfo = tx.value.additionalInfo;
txn.address = walletBase?.getTransactionAddress(
final addressString = walletBase?.getTransactionAddress(
addressInfo!['accountIndex'] as int,
addressInfo['addressIndex'] as int,
) ??
"";
);
if (addressString != null) {
txn.address.value = await isar.addresses
.filter()
.valueEqualTo(addressString)
.findFirst();
}
txn.type = isar_models.TransactionType.incoming;
} else {
txn.address = "";
// txn.address = "";
txn.type = isar_models.TransactionType.outgoing;
}

View file

@ -2015,7 +2015,10 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB {
// Logging.instance.log("TRANSACTION: ${jsonEncode(tx)}");
// TODO fix this for sent to self transactions?
if (!_duplicateTxCheck(allTransactions, tx["txid"] as String)) {
tx["address"] = txHash["address"];
tx["address"] = await isar.addresses
.filter()
.valueEqualTo(txHash["address"] as String)
.findFirst();
tx["height"] = txHash["height"];
allTransactions.add(tx);
}
@ -2150,7 +2153,10 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB {
inputAmtSentFromWallet -= _value;
} else {
// change address from 'sent from' to the 'sent to' address
txObject["address"] = address;
txObject["address"] = await isar.addresses
.filter()
.valueEqualTo(address)
.findFirst();
}
} catch (s) {
Logging.instance.log(s.toString(), level: LogLevel.Warning);
@ -2263,7 +2269,7 @@ class ParticlWallet extends CoinServiceAPI with WalletCache, WalletDB {
tx.subType = isar_models.TransactionSubType.none;
tx.fee = fee;
tx.address = midSortedTx["address"] as String;
tx.address.value = midSortedTx["address"] as isar_models.Address?;
for (final json in midSortedTx["vin"] as List) {
bool isCoinBase = json['coinbase'] != null;

View file

@ -937,15 +937,21 @@ class WowneroWallet extends CoinServiceAPI with WalletCache, WalletDB {
if (tx.value.direction == TransactionDirection.incoming) {
final addressInfo = tx.value.additionalInfo;
txn.address = walletBase?.getTransactionAddress(
final addressString = walletBase?.getTransactionAddress(
addressInfo!['accountIndex'] as int,
addressInfo['addressIndex'] as int,
) ??
"";
);
if (addressString != null) {
txn.address.value = await isar.addresses
.filter()
.valueEqualTo(addressString)
.findFirst();
}
txn.type = isar_models.TransactionType.incoming;
} else {
txn.address = "";
// txn.address = "";
txn.type = isar_models.TransactionType.outgoing;
}

View file

@ -22,7 +22,7 @@ mixin WalletDB {
AddressSchema,
],
directory: (await StackFileSystem.applicationIsarDirectory()).path,
inspector: false,
inspector: true,
name: walletId,
);
return true;