public TransactionBroadcasterViewModel() : base("Transaction Broadcaster") { Global = Locator.Current.GetService <Global>(); ButtonText = "Broadcast Transaction"; this.WhenAnyValue(x => x.FinalTransaction) .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(x => { try { if (x is null) { TransactionDetails = null; } else { TransactionDetails = TransactionDetailsViewModel.FromBuildTxnResult(Global.BitcoinStore, PSBT.FromTransaction(x.Transaction, Global.Network)); NotificationHelpers.Information("Transaction imported successfully!"); } } catch (Exception ex) { TransactionDetails = null; NotificationHelpers.Error(ex.ToUserFriendlyString()); Logger.LogError(ex); } }); PasteCommand = ReactiveCommand.CreateFromTask(async() => { try { var textToPaste = await Application.Current.Clipboard.GetTextAsync(); if (string.IsNullOrWhiteSpace(textToPaste)) { FinalTransaction = null; NotificationHelpers.Information("Clipboard is empty!"); } else if (PSBT.TryParse(textToPaste, Global.Network ?? Network.Main, out var signedPsbt)) { if (!signedPsbt.IsAllFinalized()) { signedPsbt.Finalize(); } FinalTransaction = signedPsbt.ExtractSmartTransaction(); } else { FinalTransaction = new SmartTransaction(Transaction.Parse(textToPaste, Global.Network ?? Network.Main), WalletWasabi.Models.Height.Unknown); } } catch (Exception ex) { FinalTransaction = null; NotificationHelpers.Error(ex.ToUserFriendlyString()); Logger.LogError(ex); } }); IObservable <bool> broadcastTransactionCanExecute = this .WhenAny(x => x.FinalTransaction, (tx) => tx.Value is { })
public TransactionViewerViewModel() : base("Transaction") { Global = Locator.Current.GetService <Global>(); OpenTransactionBroadcaster = ReactiveCommand.Create(() => IoC.Get <IShell>().AddOrSelectDocument(() => new TransactionBroadcasterViewModel())); CopyBase64Psbt = ReactiveCommand.CreateFromTask(async() => { await Application.Current.Clipboard.SetTextAsync(PsbtBase64Text); NotificationHelpers.Information("PSBT Base64 string copied to clipboard!"); }); CopyTransactionHex = ReactiveCommand.CreateFromTask(async() => { await Application.Current.Clipboard.SetTextAsync(TransactionHexText); NotificationHelpers.Information("Transaction hex string copied to clipboard!"); }); ExportBinaryPsbt = ReactiveCommand.CreateFromTask(async() => { var psbtExtension = "psbt"; var sfd = new SaveFileDialog { DefaultExtension = psbtExtension, InitialFileName = TransactionDetails.TransactionId.Substring(0, 7), Title = "Export Binary PSBT" }; if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { var initialDirectory = Path.Combine("/media", Environment.UserName); if (!Directory.Exists(initialDirectory)) { initialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal); } sfd.Directory = initialDirectory; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { sfd.Directory = Environment.GetFolderPath(Environment.SpecialFolder.Personal); } var window = ((IClassicDesktopStyleApplicationLifetime)Application.Current.ApplicationLifetime).MainWindow; string fileFullName = await sfd.ShowAsync(window, fallBack: true); if (!string.IsNullOrWhiteSpace(fileFullName)) { var ext = Path.GetExtension(fileFullName); if (string.IsNullOrWhiteSpace(ext)) { fileFullName = $"{fileFullName}.{psbtExtension}"; } await File.WriteAllBytesAsync(fileFullName, PsbtBytes); NotificationHelpers.Success("PSBT file was exported."); } }); Observable .Merge(CopyBase64Psbt.ThrownExceptions) .Merge(CopyTransactionHex.ThrownExceptions) .Merge(ExportBinaryPsbt.ThrownExceptions) .Merge(OpenTransactionBroadcaster.ThrownExceptions) .ObserveOn(RxApp.TaskpoolScheduler) .Subscribe(ex => { Logger.LogError(ex); NotificationHelpers.Error(ex.ToUserFriendlyString()); }); }