Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions cw_bitcoin/lib/electrum_transaction_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ElectrumTransactionBundle {
{required this.ins, required this.confirmations, this.time});

final BtcTransaction originalTransaction;
final List<BtcTransaction> ins;
final List<BtcTransaction?> ins;
final int? time;
final int confirmations;
}
Expand Down Expand Up @@ -127,9 +127,14 @@ class ElectrumTransactionInfo extends TransactionInfo {
List<String> inputAddresses = [];
List<String> outputAddresses = [];

var hasMissingInputTx = false;
for (var i = 0; i < bundle.originalTransaction.inputs.length; i++) {
final input = bundle.originalTransaction.inputs[i];
final inputTransaction = bundle.ins[i];
final inputTransaction = i < bundle.ins.length ? bundle.ins[i] : null;
if (inputTransaction == null || input.txIndex >= inputTransaction.outputs.length) {
hasMissingInputTx = true;
continue;
}
final outTransaction = inputTransaction.outputs[input.txIndex];
inputAmount += outTransaction.amount.toInt();
if (addresses.contains(addressFromOutputScript(outTransaction.scriptPubKey, network))) {
Expand Down Expand Up @@ -184,21 +189,27 @@ class ElectrumTransactionInfo extends TransactionInfo {
final b = tx.outputs.first.scriptPubKey.toBytes();
return b.length == 34 && b[0] == 88 && b[1] == 32;
};
final isHogEx = isHogExTx(bundle.originalTransaction) && isHogExTx(bundle.ins.first);
final firstInput = bundle.ins.isNotEmpty ? bundle.ins.first : null;
final isHogEx = firstInput != null &&
isHogExTx(bundle.originalTransaction) &&
isHogExTx(firstInput);

final fee = inputAmount - totalOutAmount;
final fee = hasMissingInputTx ? null : inputAmount - totalOutAmount;
final walletCurrency = walletTypeToCryptoCurrency(type);
final feeMoney = fee != null ? Money.fromInt(fee, walletCurrency) : null;
return ElectrumTransactionInfo(type,
id: bundle.originalTransaction.txId(),
height: height,
isPending: bundle.confirmations == 0,
isReplaced: false,
inputAddresses: inputAddresses,
outputAddresses: outputAddresses,
fee: Money.fromInt(fee, walletTypeToCryptoCurrency(type)),
fee: feeMoney,
direction: direction,
amount: Money.fromInt(amount, walletTypeToCryptoCurrency(type)),
amount: Money.fromInt(amount, walletCurrency),
date: date,
isHogEx: isHogEx,
additionalInfo: {'hasMissingInputTx': hasMissingInputTx},
confirmations: bundle.confirmations);
}

Expand Down
46 changes: 23 additions & 23 deletions cw_bitcoin/lib/electrum_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2118,6 +2118,9 @@ abstract class ElectrumWalletBase
for (int i = 0; i < bundle.originalTransaction.inputs.length; i++) {
final input = bundle.originalTransaction.inputs[i];
final inputTransaction = bundle.ins[i];
if (inputTransaction == null) {
throw Exception("Missing input transaction for fee calculation");
}
final vout = input.txIndex;
final outTransaction = inputTransaction.outputs[vout];
allInputsAmount += outTransaction.amount.toInt();
Expand Down Expand Up @@ -2146,6 +2149,9 @@ abstract class ElectrumWalletBase
for (var i = 0; i < bundle.originalTransaction.inputs.length; i++) {
final input = bundle.originalTransaction.inputs[i];
final inputTransaction = bundle.ins[i];
if (inputTransaction == null) {
throw Exception("Missing input transaction for replace-by-fee");
}
final vout = input.txIndex;
final outTransaction = inputTransaction.outputs[vout];
final address = addressFromOutputScript(outTransaction.scriptPubKey, network);
Expand Down Expand Up @@ -2434,20 +2440,24 @@ abstract class ElectrumWalletBase
}

final original = BtcTransaction.fromRaw(transactionHex);
final ins = <BtcTransaction>[];
final ins = <BtcTransaction?>[];

for (final vin in original.inputs) {
final verboseTransaction = await electrumClient.getTransactionVerbose(hash: vin.txId);
try {
final verboseTransaction = await electrumClient.getTransactionVerbose(hash: vin.txId);

final String inputTransactionHex;
final String inputTransactionHex;

if (verboseTransaction.isEmpty) {
inputTransactionHex = await electrumClient.getTransactionHex(hash: hash);
} else {
inputTransactionHex = verboseTransaction['hex'] as String;
}
if (verboseTransaction.isEmpty) {
inputTransactionHex = await electrumClient.getTransactionHex(hash: vin.txId);
} else {
inputTransactionHex = verboseTransaction['hex'] as String;
}

ins.add(BtcTransaction.fromRaw(inputTransactionHex));
ins.add(inputTransactionHex.isEmpty ? null : BtcTransaction.fromRaw(inputTransactionHex));
} catch (_) {
ins.add(null);
}
}

return ElectrumTransactionBundle(
Expand Down Expand Up @@ -3204,22 +3214,11 @@ abstract class ElectrumWalletBase
}
}

final ins = <BtcTransaction>[];
final inputTxids = inputTxidsByHash[txid] ?? const <String>[];

bool allInputsPresent = true;
for (final inputTxid in inputTxids) {
final inTx = parsedInputTxById[inputTxid];
if (inTx == null) {
allInputsPresent = false;
break;
}
ins.add(inTx);
}

if (!allInputsPresent || ins.length != original.inputs.length) {
continue;
}
final ins = <BtcTransaction?>[
for (final inputTxid in inputTxids) parsedInputTxById[inputTxid],
];

bundles[txid] = ElectrumTransactionBundle(
original,
Expand Down Expand Up @@ -3796,6 +3795,7 @@ abstract class ElectrumWalletBase
for (int i = 0; i < bundle.originalTransaction.inputs.length; i++) {
final input = bundle.originalTransaction.inputs[i];
final inputTransaction = bundle.ins[i];
if (inputTransaction == null) continue;
final vout = input.txIndex;
final outTransaction = inputTransaction.outputs[vout];
final address = addressFromOutputScript(outTransaction.scriptPubKey, network);
Expand Down
6 changes: 6 additions & 0 deletions lib/view_model/dashboard/transaction_list_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ class TransactionListItem extends ActionListItem with Keyable {
}

String get formattedTitle {

if (balanceViewModel.wallet.type == WalletType.bitcoin &&
transaction.additionalInfo['hasMissingInputTx'] == true) {
return 'Transaction has missing data';
}

if (transaction.additionalInfo['autoShield'] == true) {
return "Autoshield";
}
Expand Down
Loading