feat: add ordinal spend warning to confirm transaction view
What changed, and why it matters
This commit adds a warning message shown to users when they are about to spend a Bitcoin UTXO that contains an ordinal inscription. It is a user-interface safety feature, not a fix for a code vulnerability. It helps prevent users from accidentally spending or losing valuable or meaningful inscription assets.
No security action required. Treat as a normal feature addition. Optionally review whether the ordinal lookup correctly handles all input types and whether the warning should block confirmation rather than just inform.
Security signals we found
User-facing safety warning for accidental asset loss
No changes to cryptographic, signing, or network code
No input validation or access-control changes
No bug fix or vulnerability remediation evident in diff
Evidence from the diff
The change introduces a new Builder widget in the transaction confirmation view. Before confirming a send, it checks each selected UTXO against the local Isar database’s ordinals collection. If any input matches a known ordinal by walletId, txid, and vout, a warning banner is displayed. The commit only adds UI logic and database reads; it does not modify transaction construction, signing, or validation.
Changed components
lib/pages/send_view/confirm_transaction_view.dartInspect captured patch +68 / −0
diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart
index dfd6c98..bdce989 100644
--- a/lib/pages/send_view/confirm_transaction_view.dart
+++ b/lib/pages/send_view/confirm_transaction_view.dart
@@ -14,10 +14,13 @@ import 'dart:io';
import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
+import 'package:isar_community/isar.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
+import '../../models/input.dart';
import '../../models/isar/models/transaction_note.dart';
+import '../../models/isar/ordinal.dart';
import '../../notifications/show_flush_bar.dart';
import '../../pages_desktop_specific/coin_control/desktop_coin_control_use_dialog.dart';
import '../../pages_desktop_specific/my_stack_view/wallet_view/sub_widgets/desktop_auth_send.dart';
@@ -1418,6 +1421,71 @@ class _ConfirmTransactionViewState
),
),
),
+ // Ordinal UTXO spend warning
+ Builder(
+ builder: (context) {
+ final usedUtxos = widget.txData.usedUTXOs;
+ if (usedUtxos == null || usedUtxos.isEmpty) {
+ return const SizedBox.shrink();
+ }
+
+ final db = ref.read(mainDBProvider);
+ bool hasOrdinal = false;
+ for (final input in usedUtxos) {
+ if (input is StandardInput) {
+ final ordinal = db.isar.ordinals
+ .where()
+ .filter()
+ .walletIdEqualTo(walletId)
+ .and()
+ .utxoTXIDEqualTo(input.utxo.txid)
+ .and()
+ .utxoVOUTEqualTo(input.utxo.vout)
+ .findFirstSync();
+ if (ordinal != null) {
+ hasOrdinal = true;
+ break;
+ }
+ }
+ }
+
+ if (!hasOrdinal) return const SizedBox.shrink();
+
+ return Padding(
+ padding: isDesktop
+ ? const EdgeInsets.symmetric(horizontal: 32, vertical: 8)
+ : const EdgeInsets.symmetric(vertical: 8),
+ child: RoundedContainer(
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.warningBackground,
+ child: Row(
+ children: [
+ Icon(
+ Icons.warning_amber_rounded,
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.warningForeground,
+ size: 20,
+ ),
+ const SizedBox(width: 8),
+ Expanded(
+ child: Text(
+ "This transaction spends a UTXO containing "
+ "an ordinal inscription.",
+ style: STextStyles.smallMed12(context).copyWith(
+ color: Theme.of(
+ context,
+ ).extension<StackColors>()!.warningForeground,
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ },
+ ),
SizedBox(height: isDesktop ? 28 : 16),
Padding(
padding: isDesktop
Why this scored 19/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.