diff --git a/CLAUDE.md b/CLAUDE.md index 16e1f81..ec41280 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,6 +6,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co Operate as an **expert in cryptocurrencies and cryptography**: reason with the domain's rigor about UTXO consensus, HD key derivation (BIP32/39/SLIP-132), signature schemes and scripts (P2PKH/P2SH/P2WPKH, PSBT), address encoding (base58/bech32), Merkle/SPV proofs, and at-rest encryption. When a choice touches cryptographic correctness or fund safety, judge it through that lens and flag known risks and pitfalls (nonce reuse, missing validation, exposed keys/seed, wrong fee/coin-selection, unverified server responses). Explain trade-offs with technical precision; never take for granted what hasn't been verified. +## Language policy + +- **Conversation with the user**: Italian. +- **All code, comments, commit messages, and documentation files**: English only. + ## How to assist On **every requested change**, before implementing, judge whether it makes sense and say so plainly: if a request is useful and consistent with the project, proceed; if it is useless, redundant, already covered elsewhere, or risks degrading the code, **say so** with a short rationale and propose the better alternative (or doing nothing). No automatic agreement — an honest opinion is worth more than blind execution. diff --git a/src/App.Android/MainApplication.cs b/src/App.Android/MainApplication.cs index 7708e01..baf8031 100644 --- a/src/App.Android/MainApplication.cs +++ b/src/App.Android/MainApplication.cs @@ -10,9 +10,9 @@ using PalladiumWallet.Core.Storage; namespace PalladiumWallet.Mobile; -// In Avalonia 12 l'AppBuilder Android si configura nella sottoclasse Application -// (AvaloniaAndroidApplication), non più nell'Activity. allowBackup=false: -// il file wallet cifrato/seed non deve finire nei backup cloud automatici. +// In Avalonia 12 the Android AppBuilder is configured in the Application subclass +// (AvaloniaAndroidApplication), no longer in the Activity. allowBackup=false: +// the encrypted wallet file/seed must not end up in automatic cloud backups. [Application(Label = "Palladium Wallet", AllowBackup = false, Icon = "@mipmap/ic_launcher", RoundIcon = "@mipmap/ic_launcher_round")] public class MainApplication : AvaloniaAndroidApplication @@ -26,7 +26,7 @@ public class MainApplication : AvaloniaAndroidApplication { var activity = MainActivity.Current; diff --git a/src/App.Android/ScannerActivity.cs b/src/App.Android/ScannerActivity.cs index 9c12bf5..ff93294 100644 --- a/src/App.Android/ScannerActivity.cs +++ b/src/App.Android/ScannerActivity.cs @@ -16,8 +16,8 @@ using AndroidResult = Android.App.Result; namespace PalladiumWallet.Mobile; /// -/// Activity full-screen per la scansione QR via Camera2 + ZXing.Net. -/// Torna a MainActivity via SetResult con l'extra "qr" = testo del codice. +/// Full-screen activity for QR scanning via Camera2 + ZXing.Net. +/// Returns to MainActivity via SetResult with the extra "qr" = code text. /// [Activity(Theme = "@style/MyTheme.NoActionBar", ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait)] @@ -162,7 +162,7 @@ internal sealed class ScannerActivity : Activity, TextureView.ISurfaceTextureLis bmp.GetPixels(pixels, 0, w, 0, 0, w, h); bmp.Recycle(); - // ARGB int[] → RGB byte[] per ZXing.RGBLuminanceSource + // ARGB int[] → RGB byte[] for ZXing.RGBLuminanceSource var rgb = new byte[pixels.Length * 3]; for (int i = 0; i < pixels.Length; i++) { diff --git a/src/App/App.axaml b/src/App/App.axaml index 02c16c1..5f60c01 100644 --- a/src/App/App.axaml +++ b/src/App/App.axaml @@ -9,8 +9,8 @@ - + @@ -21,7 +21,7 @@ - + \ No newline at end of file diff --git a/src/App/App.axaml.cs b/src/App/App.axaml.cs index 0977a97..f76d859 100644 --- a/src/App/App.axaml.cs +++ b/src/App/App.axaml.cs @@ -17,8 +17,8 @@ public partial class App : Application { var vm = new MainWindowViewModel(); - // Desktop (Windows/Linux): finestra classica. Mobile (Android): vista - // singola. Stessa UI condivisa (MainView) e stesso ViewModel. + // Desktop (Windows/Linux): classic window. Mobile (Android): single + // view. Same shared UI (MainView) and same ViewModel. switch (ApplicationLifetime) { case IClassicDesktopStyleApplicationLifetime desktop: diff --git a/src/App/Localization/Loc.cs b/src/App/Localization/Loc.cs index c034c7b..fc2f2e6 100644 --- a/src/App/Localization/Loc.cs +++ b/src/App/Localization/Loc.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; namespace PalladiumWallet.App.Localization; /// -/// Localizzazione UI: dizionario chiave → traduzioni per lingua, con -/// indicizzatore bindabile da XAML ({Binding Loc[chiave]}). Al cambio lingua -/// il ViewModel sostituisce l'istanza così Avalonia rivaluta tutte le binding. +/// UI localisation: key → per-language translations dictionary, with an +/// indexer bindable from XAML ({Binding Loc[key]}). On language change the +/// ViewModel replaces the instance so Avalonia re-evaluates all bindings. /// public sealed class Loc { @@ -20,10 +20,10 @@ public sealed class Loc private Loc(string language) { Language = language; } /// - /// Crea una nuova istanza con la lingua specificata e aggiorna il singleton - /// usato da . Il ViewModel assegna questa istanza alla - /// propria property Loc così Avalonia vede un riferimento diverso e - /// rivaluta tutte le binding {Binding Loc[chiave]}. + /// Creates a new instance for the specified language and updates the singleton + /// used by . The ViewModel assigns this instance to its Loc + /// property so Avalonia sees a different reference and re-evaluates all + /// {Binding Loc[key]} bindings. /// internal static Loc SwitchTo(string language) { @@ -146,13 +146,13 @@ public sealed class Loc "Fügen Sie einen oder mehrere WIF-Schlüssel ein (einer pro Zeile). Sie können mehrere Schlüssel importieren, um mehrere Adressen mit demselben Wallet zu verwalten."], ["wiz.importwif.placeholder"] = ["K… / L… / 5… (una chiave per riga)", "K… / L… / 5… (one key per line)", "K… / L… / 5… (una clave por línea)", "K… / L… / 5… (une clé par ligne)", "K… / L… / 5… (uma chave por linha)", "K… / L… / 5… (ein Schlüssel pro Zeile)"], - // Messaggi di errore import + // Import error messages ["msg.xkey.required"] = ["Incolla una chiave estesa (xpub/xprv o variante).", "Paste an extended key (xpub/xprv or variant).", "Pega una clave extendida (xpub/xprv o variante).", "Collez une clé étendue (xpub/xprv ou variante).", "Cole uma chave estendida (xpub/xprv ou variante).", "Fügen Sie einen erweiterten Schlüssel ein (xpub/xprv oder Variante)."], ["msg.xkey.invalid"] = ["Chiave estesa non riconosciuta per questa rete.", "Extended key not recognised for this network.", "Clave extendida no reconocida para esta red.", "Clé étendue non reconnue pour ce réseau.", "Chave estendida não reconhecida para esta rede.", "Erweiterter Schlüssel für dieses Netzwerk nicht erkannt."], ["msg.wif.required"] = ["Incolla almeno una chiave WIF.", "Paste at least one WIF key.", "Pega al menos una clave WIF.", "Collez au moins une clé WIF.", "Cole pelo menos uma chave WIF.", "Fügen Sie mindestens einen WIF-Schlüssel ein."], ["msg.wif.invalid"] = ["Chiave WIF non valida per questa rete.", "WIF key not valid for this network.", "Clave WIF no válida para esta red.", "Clé WIF invalide pour ce réseau.", "Chave WIF inválida para esta rede.", "WIF-Schlüssel für dieses Netzwerk ungültig."], - // Pannello wallet + // Wallet panel ["wallet.close"] = ["Chiudi wallet", "Close wallet", "Cerrar wallet", "Fermer le wallet", "Fechar carteira", "Wallet schließen"], ["wallet.server"] = ["Server:", "Server:", "Servidor:", "Serveur :", "Servidor:", "Server:"], ["wallet.connect"] = ["Connetti e sincronizza", "Connect and sync", "Conectar y sincronizar", "Connecter et synchroniser", "Conectar e sincronizar", "Verbinden und synchronisieren"], @@ -188,7 +188,7 @@ public sealed class Loc ["addr.info.title"] = ["Informazioni indirizzo", "Address information", "Información de dirección", "Informations sur l'adresse", "Informações do endereço", "Adressinformationen"], ["addr.close"] = ["Chiudi", "Close", "Cerrar", "Fermer", "Fechar", "Schließen"], - // Storico → dettaglio transazione + // History → transaction detail ["history.hint"] = ["Doppio click su una transazione per i dettagli.", "Double-click a transaction for details.", "Doble clic en una transacción para ver los detalles.", "Double-cliquez sur une transaction pour les détails.", "Clique duplo numa transação para ver os detalhes.", "Doppelklick auf eine Transaktion für Details."], ["tx.title"] = ["Dettagli transazione", "Transaction details", "Detalles de la transacción", "Détails de la transaction", "Detalhes da transação", "Transaktionsdetails"], ["tx.close"] = ["Chiudi", "Close", "Cerrar", "Fermer", "Fechar", "Schließen"], @@ -231,7 +231,7 @@ public sealed class Loc ["send.scan"] = ["Scansiona QR", "Scan QR", "Escanear QR", "Scanner QR", "Escanear QR", "QR scannen"], ["send.confirm"] = ["CONFERMA E TRASMETTI", "CONFIRM AND BROADCAST", "CONFIRMAR Y TRANSMITIR", "CONFIRMER ET DIFFUSER", "CONFIRMAR E TRANSMITIR", "BESTÄTIGEN UND SENDEN"], - // Stato connessione + // Connection status ["conn.none"] = ["non connesso", "not connected", "no conectado", "non connecté", "não conectado", "nicht verbunden"], ["conn.disconnected"] = ["disconnesso", "disconnected", "desconectado", "déconnecté", "desconectado", "getrennt"], ["conn.reconnecting"] = ["riconnessione…", "reconnecting…", "reconectando…", "reconnexion…", "reconectando…", "Verbindung wird wiederhergestellt…"], @@ -240,7 +240,7 @@ public sealed class Loc ["conn.connectedto"] = ["connesso", "connected", "conectado", "connecté", "conectado", "verbunden"], ["conn.connectingto"] = ["connessione a", "connecting to", "conectando a", "connexion à", "conectando a", "Verbindung zu"], - // Messaggi di stato principali + // Main status messages ["msg.welcome.existing"] = [ "Trovato un wallet esistente su questa rete: aprilo, oppure creane un altro.", "Found an existing wallet on this network: open it, or create another one.", @@ -351,7 +351,7 @@ public sealed class Loc "SSL-Zertifikate zurückgesetzt: Verbindung erneut versuchen."], ["msg.error"] = ["Errore", "Error", "Error", "Erreur", "Erro", "Fehler"], - // Contatti + // Contacts ["contacts.name"] = ["Nome", "Name", "Nombre", "Nom", "Nome", "Name"], ["contacts.address"] = ["Indirizzo", "Address", "Dirección", "Adresse", "Endereço", "Adresse"], ["contacts.name.ph"] = ["Nome contatto", "Contact name", "Nombre del contacto", "Nom du contact", "Nome do contato", "Kontaktname"], @@ -360,7 +360,7 @@ public sealed class Loc ["contacts.remove"] = ["Rimuovi selezionato", "Remove selected", "Eliminar seleccionado", "Supprimer la sélection", "Remover selecionado", "Auswahl entfernen"], ["contacts.empty"] = ["Nessun contatto salvato.", "No saved contacts.", "No hay contactos guardados.", "Aucun contact enregistré.", "Nenhum contato salvo.", "Keine gespeicherten Kontakte."], - // Finestra impostazioni + // Settings window ["settings.title"] = ["Impostazioni", "Settings", "Configuración", "Paramètres", "Configurações", "Einstellungen"], ["settings.language"] = ["Lingua", "Language", "Idioma", "Langue", "Idioma", "Sprache"], ["settings.unit"] = ["Unità degli importi", "Amount unit", "Unidad de importes", "Unité des montants", "Unidade dos valores", "Betrageinheit"], @@ -368,7 +368,7 @@ public sealed class Loc ["settings.cancel"] = ["Annulla", "Cancel", "Cancelar", "Annuler", "Cancelar", "Abbrechen"], ["settings.server"] = ["Server di indicizzazione…", "Indexing server…", "Servidor de indexación…", "Serveur d'indexation…", "Servidor de indexação…", "Indexierungsserver…"], - // Finestra server + // Server window ["server.title"] = ["Server di indicizzazione", "Indexing server", "Servidor de indexación", "Serveur d'indexation", "Servidor de indexação", "Indexierungsserver"], ["server.host"] = ["Host", "Host", "Host", "Hôte", "Host", "Host"], ["server.port"] = ["Porta", "Port", "Puerto", "Port", "Porta", "Port"], diff --git a/src/App/Services/PlatformServices.cs b/src/App/Services/PlatformServices.cs index 06f69f4..1dcfd53 100644 --- a/src/App/Services/PlatformServices.cs +++ b/src/App/Services/PlatformServices.cs @@ -4,14 +4,14 @@ using System.Threading.Tasks; namespace PalladiumWallet.App.Services; /// -/// Seam per servizi specifici della piattaforma (Android/desktop). -/// Il head Android imposta i delegate in OnCreate; desktop li lascia null. +/// Seam for platform-specific services (Android/desktop). +/// The Android head sets the delegates in OnCreate; desktop leaves them null. /// public static class PlatformServices { /// - /// Apre lo scanner QR nativo e restituisce il testo raw del codice, - /// oppure null se l'utente annulla o lo scanner non è disponibile. + /// Opens the native QR scanner and returns the raw code text, + /// or null if the user cancels or the scanner is unavailable. /// public static Func>? ScanQrAsync { get; set; } } diff --git a/src/App/Styles/Controls.axaml b/src/App/Styles/Controls.axaml index 3649be8..e66f843 100644 --- a/src/App/Styles/Controls.axaml +++ b/src/App/Styles/Controls.axaml @@ -1,11 +1,11 @@ @@ -22,7 +22,7 @@ - + - + - + - + - + - + - + - + - + @@ -105,8 +105,8 @@ - - + + - - + + - + - + - + - + @@ -359,7 +359,7 @@ - + @@ -369,7 +369,7 @@ TextTrimming="CharacterEllipsis"/> - + @@ -389,7 +389,7 @@ - + @@ -404,7 +404,7 @@ - + - + @@ -446,7 +446,7 @@ - + - + @@ -488,7 +488,7 @@ - + - + - + @@ -533,7 +533,7 @@ - + @@ -550,7 +550,7 @@ - + @@ -560,7 +560,7 @@ - + - + @@ -595,19 +595,19 @@ - + - + - + - + - +