detect hogex inputs and only require 6 confs if so (#2786)
Hector Chu committed
Jan 9, 2026 at 16:19 UTC
ff88fa8dc8ced05705e2c7ad55b15db8ccfda35d
4 files changed
+16
-9
cw_bitcoin/lib/bitcoin_unspent.dart
+1
@@ -25,6 +25,7 @@ class BitcoinUnspent extends Unspent {
25
}
26
27
final BaseBitcoinAddressRecord bitcoinAddressRecord;
28
+ bool? isPegOut;
29
}
30
31
class BitcoinSilentPaymentsUnspent extends BitcoinUnspent {
cw_bitcoin/lib/electrum_transaction_info.dart
+12
@@ -25,6 +25,7 @@ class ElectrumTransactionBundle {
25
class ElectrumTransactionInfo extends TransactionInfo {
26
List<BitcoinSilentPaymentsUnspent>? unspents;
27
bool isReceivedSilentPayment;
28
+ bool isHogEx;
29
30
ElectrumTransactionInfo(
31
this.type, {
@@ -42,6 +43,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
43
String? to,
44
this.unspents,
45
this.isReceivedSilentPayment = false,
46
+ this.isHogEx = false,
47
Map<String, dynamic>? additionalInfo,
48
}) {
49
this.id = id;
@@ -174,6 +176,15 @@ class ElectrumTransactionInfo extends TransactionInfo {
176
amount = receivedAmounts.reduce((a, b) => a + b);
177
}
178
179
+ // MWEB HogEx
180
+ final isHogExTx = (BtcTransaction tx) {
181
+ if (tx.inputs.isEmpty || tx.inputs.first.txIndex > 0 || tx.outputs.isEmpty)
182
+ return false;
183
+ final b = tx.outputs.first.scriptPubKey.toBytes();
184
+ return b.length == 34 && b[0] == 88 && b[1] == 32;
185
+ };
186
+ final isHogEx = isHogExTx(bundle.originalTransaction) && isHogExTx(bundle.ins.first);
187
+
188
final fee = inputAmount - totalOutAmount;
189
return ElectrumTransactionInfo(type,
190
id: bundle.originalTransaction.txId(),
@@ -186,6 +197,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
197
direction: direction,
198
amount: amount,
199
date: date,
200
+ isHogEx: isHogEx,
201
confirmations: bundle.confirmations);
202
}
203
cw_bitcoin/lib/electrum_wallet.dart
+1
@@ -1740,6 +1740,7 @@ abstract class ElectrumWalletBase
1740
final tx = await fetchTransactionInfo(hash: coin.hash);
1741
coin.isChange = address.isHidden;
1742
coin.confirmations = tx?.confirmations;
1743
+ coin.isPegOut = tx?.isHogEx;
1744
1745
updatedUnspentCoins.add(coin);
1746
} catch (_) {}
cw_bitcoin/lib/litecoin_wallet.dart
+2
-9
@@ -1214,21 +1214,14 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
1214
} else {
1215
// check if any of the inputs of this transaction are hog-ex:
1216
// this list is only non-mweb inputs:
1217
- bool isHogEx = true;
1218
-
1217
final coin = unspentCoins
1218
.firstWhere((coin) => coin.hash == utxo.utxo.txHash && coin.vout == utxo.utxo.vout);
1221
-
1222
- // TODO: detect actual hog-ex inputs
1223
-
1224
- if (!isHogEx) {
1225
- continue;
1226
- }
1219
+ if (coin.isPegOut != true) continue;
1220
1221
int confirmations = coin.confirmations ?? 0;
1222
if (confirmations < 6) {
1223
throw Exception(
1231
- "A transaction input has less than 6 confirmations, please try again later.");
1224
+ "A transaction input is an MWEB peg-out and has less than 6 confirmations, please try again later.");
1225
}
1226
}
1227
}