What changed, and why it matters
This update prevents a user's wallet from accidentally sending special Bitcoin assets called 'ordinals' into a privacy feature called MWEB. Ordinals are unique digital items stored on Bitcoin, and sending them into MWEB would permanently destroy them. The change filters out any UTXOs (chunks of Bitcoin) that carry ordinals before they can be pegged into MWEB.
Review and merge if the ordinal detection query is correct and complete. Consider adding tests to verify that ordinal-bearing UTXOs are excluded from MWEB peg-ins and that non-ordinal UTXOs remain eligible. Evaluate whether similar filtering is needed elsewhere, such as coin selection for regular sends or swaps.
Security signals we found
Asset loss prevention
UTXO filtering based on ordinal metadata
MWEB peg-in input sanitization
No explicit cryptographic or authorization changes
Evidence from the diff
The commit adds a filter in the MWEB peg-in logic that removes spendable UTXOs associated with ordinal inscriptions from the set of inputs used to create an MWEB peg-in transaction. It queries the local Isar database for ordinals matching the wallet ID, transaction ID, and output index of each candidate UTXO, and excludes any matches. This prevents ordinal-bearing UTXOs from being consumed in a peg-in, which would otherwise result in loss of the inscribed asset.
Changed components
lib/wallets/wallet/wallet_mixin_interfaces/mweb_interface.dartMWEB peg-in transaction constructionOrdinal UTXO handlingInspect captured patch +15 / −0
diff --git a/lib/wallets/wallet/wallet_mixin_interfaces/mweb_interface.dart b/lib/wallets/wallet/wallet_mixin_interfaces/mweb_interface.dart
index e183be6..bfeb24e 100644
--- a/lib/wallets/wallet/wallet_mixin_interfaces/mweb_interface.dart
+++ b/lib/wallets/wallet/wallet_mixin_interfaces/mweb_interface.dart
@@ -14,6 +14,7 @@ import '../../../models/input.dart';
import '../../../models/isar/models/blockchain_data/v2/output_v2.dart';
import '../../../models/isar/models/blockchain_data/v2/transaction_v2.dart';
import '../../../models/isar/models/isar_models.dart';
+import '../../../models/isar/ordinal.dart';
import '../../../services/event_bus/events/global/blocks_remaining_event.dart';
import '../../../services/event_bus/events/global/refresh_percent_changed_event.dart';
import '../../../services/event_bus/events/global/wallet_sync_status_changed_event.dart';
@@ -649,6 +650,20 @@ mixin MwebInterface<T extends ElectrumXCurrencyInterface>
),
);
+ // Never peg ordinal UTXOs into MWEB.
+ spendableUtxos.removeWhere((e) {
+ final ord = mainDB.isar.ordinals
+ .where()
+ .filter()
+ .walletIdEqualTo(walletId)
+ .and()
+ .utxoTXIDEqualTo(e.txid)
+ .and()
+ .utxoVOUTEqualTo(e.vout)
+ .findFirstSync();
+ return ord != null;
+ });
+
if (spendableUtxos.isEmpty) {
throw Exception("No available UTXOs found to anonymize");
}
Why this scored 59/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.