From 34c73f253d20d502b4046725366b4bf2d5e85efd Mon Sep 17 00:00:00 2001 From: sneurlax Date: Mon, 4 May 2026 16:14:43 -0500 Subject: [PATCH 1/2] fix: throw if inscription number is null safer than colliding with the genesis inscription --- lib/dto/ordinals/inscription_data.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dto/ordinals/inscription_data.dart b/lib/dto/ordinals/inscription_data.dart index 19d6ae9a9..1045bbc8b 100644 --- a/lib/dto/ordinals/inscription_data.dart +++ b/lib/dto/ordinals/inscription_data.dart @@ -73,7 +73,7 @@ class InscriptionData { return InscriptionData( inscriptionId: inscriptionId, - inscriptionNumber: json['inscription_number'] as int? ?? 0, + inscriptionNumber: json['inscription_number'] as int, address: json['address'] as String? ?? '', preview: contentUrl, content: contentUrl, From 914c31d826db68e186b74b8ee7908d70b248aa55 Mon Sep 17 00:00:00 2001 From: sneurlax Date: Mon, 4 May 2026 17:30:05 -0500 Subject: [PATCH 2/2] perf(ordinals): cache ordinal-spend check off the build path --- .../send_view/confirm_transaction_view.dart | 126 +++++++++--------- 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/lib/pages/send_view/confirm_transaction_view.dart b/lib/pages/send_view/confirm_transaction_view.dart index 84af61974..d9256457a 100644 --- a/lib/pages/send_view/confirm_transaction_view.dart +++ b/lib/pages/send_view/confirm_transaction_view.dart @@ -47,6 +47,7 @@ import '../../wallets/wallet/impl/epiccash_wallet.dart'; import '../../wallets/wallet/impl/firo_wallet.dart'; import '../../wallets/wallet/impl/mimblewimblecoin_wallet.dart'; import '../../wallets/wallet/impl/solana_wallet.dart'; +import '../../wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart'; import '../../wallets/wallet/wallet_mixin_interfaces/paynym_interface.dart'; import '../../widgets/background.dart'; import '../../widgets/conditional_parent.dart'; @@ -110,6 +111,36 @@ class _ConfirmTransactionViewState late final FocusNode _onChainNoteFocusNode; late final TextEditingController onChainNoteController; + bool _spendsOrdinal = false; + + Future _checkForOrdinalSpend() async { + final wallet = ref.read(pWallets).getWallet(walletId); + if (wallet is! OrdinalsInterface) return; + + final usedUtxos = widget.txData.usedUTXOs; + if (usedUtxos == null || usedUtxos.isEmpty) return; + + final db = ref.read(mainDBProvider); + for (final input in usedUtxos) { + if (input is! StandardInput) continue; + final ordinal = await db.isar.ordinals + .where() + .filter() + .walletIdEqualTo(walletId) + .and() + .utxoTXIDEqualTo(input.utxo.txid) + .and() + .utxoVOUTEqualTo(input.utxo.vout) + .findFirst(); + if (ordinal != null) { + if (mounted) { + setState(() => _spendsOrdinal = true); + } + return; + } + } + } + /// Handle MWC slatepack creation for manual exchange. Future _handleMwcSlatepackCreation( BuildContext context, @@ -537,6 +568,8 @@ class _ConfirmTransactionViewState onChainNoteController.text = widget.txData.noteOnChain ?? ""; super.initState(); + + _checkForOrdinalSpend(); } @override @@ -1421,71 +1454,40 @@ 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()!.warningBackground, - child: Row( - children: [ - Icon( - Icons.warning_amber_rounded, - color: Theme.of( - context, - ).extension()!.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()!.warningForeground, - ), + if (_spendsOrdinal) + Padding( + padding: isDesktop + ? const EdgeInsets.symmetric(horizontal: 32, vertical: 8) + : const EdgeInsets.symmetric(vertical: 8), + child: RoundedContainer( + color: Theme.of( + context, + ).extension()!.warningBackground, + child: Row( + children: [ + Icon( + Icons.warning_amber_rounded, + color: Theme.of( + context, + ).extension()!.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()!.warningForeground, ), ), - ], - ), + ), + ], ), - ); - }, - ), + ), + ), SizedBox(height: isDesktop ? 28 : 16), Padding( padding: isDesktop