diff --git a/src/App/Localization/Loc.cs b/src/App/Localization/Loc.cs
index 1f623a2..3a8616a 100644
--- a/src/App/Localization/Loc.cs
+++ b/src/App/Localization/Loc.cs
@@ -60,6 +60,19 @@ public sealed class Loc
"Portefeuille SPV pour la cryptomonnaie Palladium (PLM).",
"Carteira SPV para a criptomoeda Palladium (PLM).",
"SPV-Wallet für die Kryptowährung Palladium (PLM)."],
+ ["help.tab.info"] = ["Info", "Info", "Info", "Info", "Info", "Info"],
+ ["help.tab.donate"] = ["Dona", "Donate", "Donar", "Faire un don", "Doar", "Spenden"],
+ ["donate.desc"] = [
+ "Se questo wallet ti è utile, considera una piccola donazione allo sviluppatore.",
+ "If you find this wallet useful, consider a small donation to the developer.",
+ "Si esta wallet te resulta útil, considera una pequeña donación al desarrollador.",
+ "Si ce portefeuille vous est utile, envisagez un petit don au développeur.",
+ "Se esta carteira é útil para você, considere uma pequena doação ao desenvolvedor.",
+ "Wenn Ihnen dieses Wallet nützlich ist, erwägen Sie eine kleine Spende an den Entwickler."],
+ ["donate.dev.address"] = ["Indirizzo sviluppatore", "Developer address", "Dirección del desarrollador", "Adresse du développeur", "Endereço do desenvolvedor", "Entwickleradresse"],
+ ["donate.amount"] = ["Importo donazione", "Donation amount", "Monto de donación", "Montant du don", "Valor da doação", "Spendenbetrag"],
+ ["donate.prepare"] = ["Prepara donazione", "Prepare donation", "Preparar donación", "Préparer le don", "Preparar doação", "Spende vorbereiten"],
+ ["donate.confirm"] = ["Conferma e invia", "Confirm and send", "Confirmar y enviar", "Confirmer et envoyer", "Confirmar e enviar", "Bestätigen und senden"],
["settings.unit.short"] = ["Unità", "Unit", "Unidad", "Unité", "Unidade", "Einheit"],
// Wizard
diff --git a/src/App/ViewModels/MainWindowViewModel.Donate.cs b/src/App/ViewModels/MainWindowViewModel.Donate.cs
new file mode 100644
index 0000000..b2eb638
--- /dev/null
+++ b/src/App/ViewModels/MainWindowViewModel.Donate.cs
@@ -0,0 +1,96 @@
+using System;
+using System.Threading.Tasks;
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+using NBitcoin;
+using PalladiumWallet.Core.Chain;
+using PalladiumWallet.Core.Net;
+using PalladiumWallet.Core.Wallet;
+
+namespace PalladiumWallet.App.ViewModels;
+
+public partial class MainWindowViewModel
+{
+ public const string DevAddress = "plm1qdq3gu2zvg9lyr8gxd6yln4wavc5tlp8prmvfay";
+
+ [ObservableProperty]
+ private string donateAmount = "";
+
+ [ObservableProperty]
+ private string donatePreview = "";
+
+ [ObservableProperty]
+ private bool hasPendingDonate;
+
+ private BuiltTransaction? _pendingDonate;
+
+ [RelayCommand]
+ private async Task PrepareDonate()
+ {
+ _pendingDonate = null;
+ HasPendingDonate = false;
+
+ if (_account is null || _doc?.Cache is null || _lastTransactions is null)
+ {
+ DonatePreview = "Sincronizza prima di inviare.";
+ return;
+ }
+ try
+ {
+ var destination = BitcoinAddress.Create(DevAddress, PalladiumNetworks.For(Net));
+ if (!CoinAmount.TryParseIn(DonateAmount.Trim(), _config.Unit, out var amount) || amount <= 0)
+ {
+ DonatePreview = "Importo non valido.";
+ return;
+ }
+ if (!decimal.TryParse(SendFeeRate, System.Globalization.NumberStyles.Any,
+ System.Globalization.CultureInfo.InvariantCulture, out var feeRate) || feeRate <= 0)
+ feeRate = 1m;
+
+ _pendingDonate = new TransactionFactory(_account).Build(
+ _doc.Cache.Utxos, _lastTransactions, destination, amount, feeRate,
+ _doc.Cache.NextChangeIndex, sendAll: false);
+
+ DonatePreview = $"txid {_pendingDonate.Txid[..16]}… · " +
+ $"fee {Fmt(_pendingDonate.Fee.Satoshi)} " +
+ $"({_pendingDonate.Transaction.GetVirtualSize()} vB)" +
+ (_pendingDonate.Signed ? "" : " · watch-only");
+ HasPendingDonate = _pendingDonate.Signed;
+ }
+ catch (Exception ex)
+ {
+ _pendingDonate = null;
+ HasPendingDonate = false;
+ DonatePreview = $"Errore: {ex.Message}";
+ }
+ await Task.CompletedTask;
+ }
+
+ [RelayCommand]
+ private async Task ConfirmDonate()
+ {
+ if (_pendingDonate is null || _client is null)
+ return;
+ try
+ {
+ var txid = await _client.BroadcastAsync(_pendingDonate.ToHex());
+ DonatePreview = $"Grazie! txid: {txid}";
+ DonateAmount = "";
+ _pendingDonate = null;
+ HasPendingDonate = false;
+ await ConnectAndSync();
+ }
+ catch (Exception ex)
+ {
+ DonatePreview = $"Errore broadcast: {ex.Message}";
+ }
+ }
+
+ private void ResetDonate()
+ {
+ DonateAmount = "";
+ DonatePreview = "";
+ HasPendingDonate = false;
+ _pendingDonate = null;
+ }
+}
diff --git a/src/App/ViewModels/MainWindowViewModel.Settings.cs b/src/App/ViewModels/MainWindowViewModel.Settings.cs
index 778e591..a147463 100644
--- a/src/App/ViewModels/MainWindowViewModel.Settings.cs
+++ b/src/App/ViewModels/MainWindowViewModel.Settings.cs
@@ -70,5 +70,5 @@ public partial class MainWindowViewModel
private void OpenHelp() => IsHelpOpen = true;
[RelayCommand]
- private void CloseHelp() => IsHelpOpen = false;
+ private void CloseHelp() { IsHelpOpen = false; ResetDonate(); }
}
diff --git a/src/App/Views/MainView.axaml b/src/App/Views/MainView.axaml
index 691cccd..3da5109 100644
--- a/src/App/Views/MainView.axaml
+++ b/src/App/Views/MainView.axaml
@@ -1378,12 +1378,68 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+