mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 09:47:37 +00:00
WIP tx parse + link address to transaction
This commit is contained in:
parent
13e6fc6b47
commit
52d5ab0d33
13 changed files with 118 additions and 348 deletions
|
@ -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)
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:bech32/bech32.dart';
|
||||
|
@ -2011,79 +2012,40 @@ 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"];
|
||||
tx["height"] = txHash["height"];
|
||||
allTransactions.add(tx);
|
||||
}
|
||||
// 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) {
|
||||
for (int i = 0; i < (txObject["vin"] as List).length; i++) {
|
||||
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
//
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
addressInfo!['accountIndex'] as int,
|
||||
addressInfo['addressIndex'] as int,
|
||||
) ??
|
||||
"";
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
addressInfo!['accountIndex'] as int,
|
||||
addressInfo['addressIndex'] as int,
|
||||
) ??
|
||||
"";
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ mixin WalletDB {
|
|||
AddressSchema,
|
||||
],
|
||||
directory: (await StackFileSystem.applicationIsarDirectory()).path,
|
||||
inspector: false,
|
||||
inspector: true,
|
||||
name: walletId,
|
||||
);
|
||||
return true;
|
||||
|
|
Loading…
Reference in a new issue