@@ -15,8 +15,11 @@ import '../../models/isar/models/blockchain_data/utxo.dart';
1515import '../../models/isar/ordinal.dart' ;
1616import '../../networking/http.dart' ;
1717import '../../notifications/show_flush_bar.dart' ;
18+ import '../../pages/send_view/confirm_transaction_view.dart' ;
1819import '../../providers/db/main_db_provider.dart' ;
1920import '../../providers/global/prefs_provider.dart' ;
21+ import '../../providers/global/wallets_provider.dart' ;
22+ import '../../route_generator.dart' ;
2023import '../../services/tor_service.dart' ;
2124import '../../themes/stack_colors.dart' ;
2225import '../../utilities/amount/amount.dart' ;
@@ -27,11 +30,14 @@ import '../../utilities/fs.dart';
2730import '../../utilities/show_loading.dart' ;
2831import '../../utilities/text_styles.dart' ;
2932import '../../wallets/isar/providers/wallet_info_provider.dart' ;
33+ import '../../wallets/wallet/wallet_mixin_interfaces/ordinals_interface.dart' ;
3034import '../../widgets/background.dart' ;
3135import '../../widgets/custom_buttons/app_bar_icon_button.dart' ;
36+ import '../../widgets/desktop/primary_button.dart' ;
3237import '../../widgets/desktop/secondary_button.dart' ;
3338import '../../widgets/ordinal_image.dart' ;
3439import '../../widgets/rounded_white_container.dart' ;
40+ import 'widgets/dialogs.dart' ;
3541
3642class OrdinalDetailsView extends ConsumerStatefulWidget {
3743 const OrdinalDetailsView ({
@@ -350,33 +356,130 @@ class _OrdinalImageGroup extends ConsumerWidget {
350356 },
351357 ),
352358 ),
353- // const SizedBox(
354- // width: _spacing,
355- // ),
356- // Expanded(
357- // child: PrimaryButton(
358- // label: "Send",
359- // icon: SvgPicture.asset(
360- // Assets.svg.send,
361- // width: 10,
362- // height: 10,
363- // color: Theme.of(context)
364- // .extension<StackColors>()!
365- // .buttonTextPrimary,
366- // ),
367- // buttonHeight: ButtonHeight.l,
368- // iconSpacing: 4,
369- // onPressed: () async {
370- // final response = await showDialog<String?>(
371- // context: context,
372- // builder: (_) => const SendOrdinalUnfreezeDialog(),
373- // );
374- // if (response == "unfreeze") {
375- // // TODO: unfreeze and go to send ord screen
376- // }
377- // },
378- // ),
379- // ),
359+ const SizedBox (width: _spacing),
360+ Expanded (
361+ child: PrimaryButton (
362+ label: "Send" ,
363+ icon: SvgPicture .asset (
364+ Assets .svg.send,
365+ width: 10 ,
366+ height: 10 ,
367+ color: Theme .of (
368+ context,
369+ ).extension < StackColors > ()! .buttonTextPrimary,
370+ ),
371+ buttonHeight: ButtonHeight .l,
372+ iconSpacing: 4 ,
373+ onPressed: () async {
374+ final utxo = ordinal.getUTXO (ref.read (mainDBProvider));
375+ if (utxo == null ) {
376+ unawaited (
377+ showFloatingFlushBar (
378+ type: FlushBarType .warning,
379+ message: "Could not find ordinal UTXO" ,
380+ context: context,
381+ ),
382+ );
383+ return ;
384+ }
385+
386+ // Step 1: Confirm unfreeze
387+ if (utxo.isBlocked) {
388+ final unfreezeResponse = await showDialog <String ?>(
389+ context: context,
390+ builder: (_) => const SendOrdinalUnfreezeDialog (),
391+ );
392+ if (unfreezeResponse != "unfreeze" ) return ;
393+ }
394+
395+ if (! context.mounted) return ;
396+
397+ // Step 2: Get recipient address
398+ final address = await showDialog <String ?>(
399+ context: context,
400+ builder: (_) => OrdinalRecipientAddressDialog (
401+ inscriptionNumber: ordinal.inscriptionNumber,
402+ ),
403+ );
404+ if (address == null || address.isEmpty) return ;
405+
406+ // Validate address
407+ final wallet = ref.read (pWallets).getWallet (walletId);
408+ if (! wallet.cryptoCurrency.validateAddress (address)) {
409+ if (context.mounted) {
410+ unawaited (
411+ showFloatingFlushBar (
412+ type: FlushBarType .warning,
413+ message: "Invalid address" ,
414+ context: context,
415+ ),
416+ );
417+ }
418+ return ;
419+ }
420+
421+ if (! context.mounted) return ;
422+
423+ // Step 3: Prepare the transaction
424+ final OrdinalsInterface ? ordinalsWallet =
425+ wallet is OrdinalsInterface ? wallet : null ;
426+ if (ordinalsWallet == null ) {
427+ unawaited (
428+ showFloatingFlushBar (
429+ type: FlushBarType .warning,
430+ message: "Wallet does not support ordinals" ,
431+ context: context,
432+ ),
433+ );
434+ return ;
435+ }
436+
437+ bool didError = false ;
438+ final txData = await showLoading (
439+ whileFuture: ordinalsWallet.prepareOrdinalSend (
440+ ordinalUtxo: utxo,
441+ recipientAddress: address,
442+ ),
443+ context: context,
444+ rootNavigator: true ,
445+ message: "Preparing transaction..." ,
446+ onException: (e) {
447+ didError = true ;
448+ String msg = e.toString ();
449+ while (msg.isNotEmpty &&
450+ msg.startsWith ("Exception:" )) {
451+ msg = msg.substring (10 ).trim ();
452+ }
453+ if (context.mounted) {
454+ showFloatingFlushBar (
455+ type: FlushBarType .warning,
456+ message: msg,
457+ context: context,
458+ );
459+ }
460+ },
461+ );
462+
463+ if (didError || txData == null || ! context.mounted) return ;
464+
465+ // Step 4: Navigate to confirm transaction view
466+ await Navigator .of (context).push (
467+ RouteGenerator .getRoute <void >(
468+ shouldUseMaterialRoute:
469+ RouteGenerator .useMaterialPageRoute,
470+ builder: (_) => ConfirmTransactionView (
471+ walletId: walletId,
472+ txData: txData,
473+ onSuccess: () {},
474+ ),
475+ settings: const RouteSettings (
476+ name: ConfirmTransactionView .routeName,
477+ ),
478+ ),
479+ );
480+ },
481+ ),
482+ ),
380483 ],
381484 ),
382485 ],
0 commit comments