docs: translate all code comments to English (language policy)

Translate every Italian /// XML doc comment, <!-- --> XAML comment, and
// inline comment to English across all source files (Core, App, tests).
Add the language policy to CLAUDE.md (conversation Italian; all code
and docs English). Update one test assertion that checked an Italian
exception message that was also translated.
This commit is contained in:
2026-06-16 14:40:06 +02:00
parent 4b82a0852c
commit 3d5a226a5a
59 changed files with 721 additions and 716 deletions
+28 -28
View File
@@ -4,12 +4,12 @@ using PalladiumWallet.Core.Chain;
namespace PalladiumWallet.Core.Crypto;
/// <summary>
/// Account HD single-sig (blueprint §4.2/§4.4): chiave estesa di account (xprv,
/// oppure solo xpub = watch-only) + tipo di script + profilo di rete. Deriva
/// indirizzi receiving (change=0) e change (change=1) on-demand per indice.
/// Gli indirizzi si derivano sempre dall'xpub di account (sottopath non-hardened),
/// quindi il watch-only funziona per costruzione. Il keystore completo
/// (cifratura, factory dal file wallet, §4.5) arriva con la persistenza (§8).
/// Single-sig HD account (blueprint §4.2/§4.4): extended account key (xprv,
/// or xpub-only = watch-only) + script type + network profile. Derives receiving
/// (change=0) and change (change=1) addresses on-demand by index.
/// Addresses are always derived from the account xpub (non-hardened sub-path),
/// so watch-only works by construction. The full keystore
/// (encryption, factory from wallet file, §4.5) arrives with persistence (§8).
/// </summary>
public sealed class HdAccount : IWalletAccount
{
@@ -18,25 +18,25 @@ public sealed class HdAccount : IWalletAccount
public ScriptKind Kind { get; }
public ChainProfile Profile { get; }
/// <summary>Path dell'account relativo alla root (es. 84'/746'/0', o personalizzato).</summary>
/// <summary>Account path relative to the root (e.g. 84'/746'/0', or custom).</summary>
public KeyPath AccountPath { get; }
/// <summary>
/// Fingerprint della chiave master: con <see cref="AccountPath"/> forma le
/// origin info richieste dalle PSBT (§6.5). Zero se ignota (xpub importata
/// senza metadati).
/// Master key fingerprint: together with <see cref="AccountPath"/> forms the
/// origin info required by PSBTs (§6.5). Zero if unknown (imported xpub
/// without metadata).
/// </summary>
public HDFingerprint MasterFingerprint { get; }
public ExtPubKey AccountXpub { get; }
/// <summary>True se l'account conosce solo la xpub: costruisce ma non firma (§4.5).</summary>
/// <summary>True if the account only knows the xpub: can build but not sign (§4.5).</summary>
public bool IsWatchOnly => _accountXprv is null;
private HdAccount(ExtKey? accountXprv, ExtPubKey accountXpub, ScriptKind kind,
ChainProfile profile, KeyPath accountPath, HDFingerprint masterFingerprint)
{
// Valida subito la mappatura (i tipi multisig non sono supportati qui).
// Validate the mapping immediately (multisig types are not supported here).
DerivationPaths.ScriptPubKeyTypeFor(kind);
_accountXprv = accountXprv;
AccountXpub = accountXpub;
@@ -46,7 +46,7 @@ public sealed class HdAccount : IWalletAccount
MasterFingerprint = masterFingerprint;
}
/// <summary>Caso principale: mnemonica BIP39 (+ passphrase opzionale) → account standard.</summary>
/// <summary>Main case: BIP39 mnemonic (+ optional passphrase) → standard account.</summary>
public static HdAccount FromMnemonic(Mnemonic mnemonic, string? passphrase,
ScriptKind kind, ChainProfile profile, int account = 0) =>
FromSeed(Bip39.ToSeed(mnemonic, passphrase), kind, profile, account);
@@ -55,22 +55,22 @@ public sealed class HdAccount : IWalletAccount
FromSeed(seed, kind, profile, DerivationPaths.AccountPath(kind, profile, account));
/// <summary>
/// Import con derivation path personalizzato (§4.2, Sparrow-like):
/// <paramref name="kind"/> determina solo il tipo di indirizzo generato.
/// Import with a custom derivation path (§4.2, Sparrow-like):
/// <paramref name="kind"/> only determines the generated address type.
/// </summary>
public static HdAccount FromSeed(byte[] seed, ScriptKind kind, ChainProfile profile, KeyPath accountPath)
{
var root = ExtKey.CreateFromSeed(seed);
// L'account si deriva sempre dalla xprv: i livelli hardened del path
// non sono derivabili da una xpub.
// The account is always derived from the xprv: hardened path levels
// cannot be derived from an xpub alone.
var accountXprv = root.Derive(accountPath);
return new HdAccount(accountXprv, accountXprv.Neuter(), kind, profile,
accountPath, root.Neuter().PubKey.GetHDFingerPrint());
}
/// <summary>
/// Watch-only da xpub di account (§4.4): fingerprint e path sono noti solo
/// se forniti da chi importa (servono per le origin info PSBT).
/// Watch-only from account xpub (§4.4): fingerprint and path are known only
/// if supplied by the importer (required for PSBT origin info).
/// </summary>
public static HdAccount FromAccountXpub(ExtPubKey accountXpub, ScriptKind kind,
ChainProfile profile, KeyPath? accountPath = null, HDFingerprint? masterFingerprint = null) =>
@@ -78,7 +78,7 @@ public sealed class HdAccount : IWalletAccount
accountPath ?? DerivationPaths.AccountPath(kind, profile),
masterFingerprint ?? default);
/// <summary>Import spendibile da xprv di account.</summary>
/// <summary>Spendable import from account xprv.</summary>
public static HdAccount FromAccountXprv(ExtKey accountXprv, ScriptKind kind,
ChainProfile profile, KeyPath? accountPath = null, HDFingerprint? masterFingerprint = null) =>
new(accountXprv, accountXprv.Neuter(), kind, profile,
@@ -97,27 +97,27 @@ public sealed class HdAccount : IWalletAccount
public PubKey? GetPublicKey(bool isChange, int index) =>
AccountXpub.Derive(DerivationPaths.AddressSubPath(isChange, index)).PubKey;
/// <summary>Chiave privata di un indirizzo; null se watch-only (§17).</summary>
/// <summary>Private key for an address; null if watch-only (§17).</summary>
public Key? GetPrivateKey(bool isChange, int index) =>
IsWatchOnly ? null : GetExtPrivateKey(isChange, index).PrivateKey;
/// <summary>Gli account HD usano il gap limit: nessuna lista fissa di indirizzi.</summary>
/// <summary>HD accounts use the gap limit: no fixed address list.</summary>
public IReadOnlyList<(BitcoinAddress Address, bool IsChange, int Index)>? FixedAddresses => null;
/// <summary>
/// Chiave privata estesa di un indirizzo. Lancia se watch-only: nessuna
/// chiave privata è derivabile dalle sole pubbliche (§17).
/// Extended private key for an address. Throws if watch-only: no private key
/// can be derived from public keys alone (§17).
/// </summary>
public ExtKey GetExtPrivateKey(bool isChange, int index) =>
(_accountXprv ?? throw new InvalidOperationException("Account watch-only: non può firmare."))
(_accountXprv ?? throw new InvalidOperationException("Watch-only account: cannot sign."))
.Derive(DerivationPaths.AddressSubPath(isChange, index));
/// <summary>Xpub di account in formato SLIP-132 (xpub/ypub/zpub secondo Kind).</summary>
/// <summary>Account xpub in SLIP-132 format (xpub/ypub/zpub according to Kind).</summary>
public string ToSlip132() => Slip132.Encode(AccountXpub, Kind, Profile);
/// <summary>Xprv di account in formato SLIP-132. Lancia se watch-only.</summary>
/// <summary>Account xprv in SLIP-132 format. Throws if watch-only.</summary>
public string ToSlip132Private() =>
Slip132.Encode(
_accountXprv ?? throw new InvalidOperationException("Account watch-only: nessuna chiave privata."),
_accountXprv ?? throw new InvalidOperationException("Watch-only account: no private key."),
Kind, Profile);
}