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:
+21
-21
@@ -3,8 +3,8 @@ using NBitcoin;
|
||||
namespace PalladiumWallet.Core.Crypto;
|
||||
|
||||
/// <summary>
|
||||
/// Lingue wordlist BIP39 supportate (blueprint §4.1). Le liste sono incorporate
|
||||
/// in NBitcoin: nessun accesso a rete o filesystem.
|
||||
/// Supported BIP39 wordlist languages (blueprint §4.1). The lists are embedded
|
||||
/// in NBitcoin: no network or filesystem access required.
|
||||
/// </summary>
|
||||
public enum MnemonicLanguage
|
||||
{
|
||||
@@ -18,7 +18,7 @@ public enum MnemonicLanguage
|
||||
Czech,
|
||||
}
|
||||
|
||||
/// <summary>Numero di parole supportato in creazione (blueprint §4.1: 12 o 24).</summary>
|
||||
/// <summary>Supported word counts for mnemonic creation (blueprint §4.1: 12 or 24).</summary>
|
||||
public enum MnemonicLength
|
||||
{
|
||||
Twelve = 12,
|
||||
@@ -26,16 +26,16 @@ public enum MnemonicLength
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Facciata BIP39 su NBitcoin.Mnemonic (blueprint §4.1). NBitcoin copre già
|
||||
/// entropia→parole, checksum, normalizzazione NFKD e PBKDF2-HMAC-SHA512 a 2048
|
||||
/// round con salt "mnemonic"+passphrase: qui si restringe l'API ai casi del
|
||||
/// blueprint e si centralizza la mappa delle lingue. Quando arriverà il seed
|
||||
/// nativo versionato (§4.1 punto 1), il riconoscimento multi-schema sarà una
|
||||
/// catena di TryParse per schema.
|
||||
/// BIP39 facade over NBitcoin.Mnemonic (blueprint §4.1). NBitcoin already handles
|
||||
/// entropy→words, checksum, NFKD normalisation, and PBKDF2-HMAC-SHA512 with 2048
|
||||
/// rounds using salt "mnemonic"+passphrase. This class narrows the API to the
|
||||
/// blueprint use-cases and centralises the language map. When the native versioned
|
||||
/// seed arrives (§4.1 point 1), multi-scheme recognition will be a chain of
|
||||
/// TryParse calls per scheme.
|
||||
/// </summary>
|
||||
public static class Bip39
|
||||
{
|
||||
/// <summary>Genera una nuova mnemonica con entropia dal CSPRNG di sistema.</summary>
|
||||
/// <summary>Generates a new mnemonic using entropy from the system CSPRNG.</summary>
|
||||
public static Mnemonic Generate(MnemonicLength length, MnemonicLanguage language = MnemonicLanguage.English)
|
||||
{
|
||||
var wordCount = length == MnemonicLength.Twelve ? WordCount.Twelve : WordCount.TwentyFour;
|
||||
@@ -43,10 +43,10 @@ public static class Bip39
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Riconosce e valida una mnemonica BIP39: numero di parole, appartenenza alla
|
||||
/// wordlist e checksum. Se <paramref name="language"/> è indicata viene provata
|
||||
/// per prima; altrimenti la lingua è auto-rilevata (parole condivise tra liste
|
||||
/// possono rendere ambiguo l'autodetect: in import l'utente può forzarla).
|
||||
/// Recognises and validates a BIP39 mnemonic: word count, wordlist membership,
|
||||
/// and checksum. If <paramref name="language"/> is specified it is tried first;
|
||||
/// otherwise the language is auto-detected (words shared between lists can make
|
||||
/// autodetect ambiguous — the user can override it on import).
|
||||
/// </summary>
|
||||
public static bool TryParse(string text, out Mnemonic? mnemonic, MnemonicLanguage? language = null)
|
||||
{
|
||||
@@ -54,8 +54,8 @@ public static class Bip39
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return false;
|
||||
|
||||
// Solo trim esterno: la normalizzazione NFKD e lo spazio ideografico
|
||||
// giapponese li gestisce NBitcoin, il testo non va alterato (§4.1).
|
||||
// Outer trim only: NBitcoin handles NFKD normalisation and Japanese
|
||||
// ideographic spaces — the text must not be altered further (§4.1).
|
||||
text = text.Trim();
|
||||
|
||||
IEnumerable<Wordlist> candidates = language is not null
|
||||
@@ -67,7 +67,7 @@ public static class Bip39
|
||||
try
|
||||
{
|
||||
var parsed = new Mnemonic(text, wordlist);
|
||||
// Il costruttore NON verifica il checksum: controllo esplicito obbligatorio.
|
||||
// The constructor does NOT verify the checksum — explicit check is mandatory.
|
||||
if (parsed.IsValidChecksum && parsed.Words.Length is 12 or 15 or 18 or 21 or 24)
|
||||
{
|
||||
mnemonic = parsed;
|
||||
@@ -76,7 +76,7 @@ public static class Bip39
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
// Parole fuori wordlist o conteggio non valido: si prova oltre.
|
||||
// Words outside the wordlist or invalid count — try the next candidate.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,9 +84,9 @@ public static class Bip39
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mnemonica → seed di 64 byte (PBKDF2-HMAC-SHA512, 2048 round, salt
|
||||
/// "mnemonic"+passphrase). La passphrase cambia completamente il wallet
|
||||
/// derivato: avvisi UI obbligatori (§4.1).
|
||||
/// Mnemonic → 64-byte seed (PBKDF2-HMAC-SHA512, 2048 rounds, salt
|
||||
/// "mnemonic"+passphrase). The passphrase completely changes the derived
|
||||
/// wallet — mandatory UI warnings required (§4.1).
|
||||
/// </summary>
|
||||
public static byte[] ToSeed(Mnemonic mnemonic, string? passphrase = null) =>
|
||||
mnemonic.DeriveSeed(passphrase);
|
||||
|
||||
@@ -4,25 +4,25 @@ using PalladiumWallet.Core.Chain;
|
||||
namespace PalladiumWallet.Core.Crypto;
|
||||
|
||||
/// <summary>
|
||||
/// Costruzione dei derivation path BIP44/49/84 (blueprint §4.2) e mappatura
|
||||
/// ScriptKind → purpose / ScriptPubKeyType. I purpose sono costanti di protocollo
|
||||
/// BIP (chain-independent); il coin_type viene sempre dal ChainProfile.
|
||||
/// BIP44/49/84 derivation path construction (blueprint §4.2) and mapping of
|
||||
/// ScriptKind → purpose / ScriptPubKeyType. Purposes are BIP protocol constants
|
||||
/// (chain-independent); coin_type always comes from the ChainProfile.
|
||||
/// </summary>
|
||||
public static class DerivationPaths
|
||||
{
|
||||
/// <summary>Purpose BIP44 (P2PKH legacy).</summary>
|
||||
/// <summary>BIP44 purpose (P2PKH legacy).</summary>
|
||||
public const int PurposeLegacy = 44;
|
||||
|
||||
/// <summary>Purpose BIP49 (P2SH-P2WPKH).</summary>
|
||||
/// <summary>BIP49 purpose (P2SH-P2WPKH).</summary>
|
||||
public const int PurposeWrappedSegwit = 49;
|
||||
|
||||
/// <summary>Purpose BIP84 (P2WPKH nativo).</summary>
|
||||
/// <summary>BIP84 purpose (native P2WPKH).</summary>
|
||||
public const int PurposeNativeSegwit = 84;
|
||||
|
||||
/// <summary>Purpose BIP48 (multisig — fase successiva, §16 passo 8).</summary>
|
||||
/// <summary>BIP48 purpose (multisig — next phase, §16 step 8).</summary>
|
||||
public const int PurposeMultisig = 48;
|
||||
|
||||
/// <summary>Purpose BIP86 (P2TR key-path, Taproot).</summary>
|
||||
/// <summary>BIP86 purpose (P2TR key-path, Taproot).</summary>
|
||||
public const int PurposeTaproot = 86;
|
||||
|
||||
public static int PurposeFor(ScriptKind kind) => kind switch
|
||||
@@ -36,9 +36,9 @@ public static class DerivationPaths
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Tipo di scriptPubKey NBitcoin per la derivazione da pubkey singola.
|
||||
/// I tipi multisig derivano da redeem script, non da una pubkey: arriveranno
|
||||
/// con i wallet M-di-N (§4.5).
|
||||
/// NBitcoin scriptPubKey type for single-pubkey derivation.
|
||||
/// Multisig types are derived from a redeem script, not a pubkey — they will
|
||||
/// arrive with M-of-N wallet support (§4.5).
|
||||
/// </summary>
|
||||
public static ScriptPubKeyType ScriptPubKeyTypeFor(ScriptKind kind) => kind switch
|
||||
{
|
||||
@@ -48,13 +48,13 @@ public static class DerivationPaths
|
||||
ScriptKind.Taproot => ScriptPubKeyType.TaprootBIP86,
|
||||
ScriptKind.WrappedSegwitMultisig or ScriptKind.NativeSegwitMultisig =>
|
||||
throw new NotSupportedException(
|
||||
"I tipi multisig derivano da redeem script: supporto previsto con i wallet M-di-N (§4.5)."),
|
||||
"Multisig types are derived from a redeem script: support planned with M-of-N wallets (§4.5)."),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(kind)),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Path di account relativo alla root: purpose'/coin'/account' (§4.2).
|
||||
/// Il coin_type è quello del profilo (746 mainnet, 1 testnet).
|
||||
/// Account path relative to the root: purpose'/coin'/account' (§4.2).
|
||||
/// coin_type is taken from the profile (746 mainnet, 1 testnet).
|
||||
/// </summary>
|
||||
public static KeyPath AccountPath(ScriptKind kind, ChainProfile profile, int account = 0)
|
||||
{
|
||||
@@ -64,7 +64,7 @@ public static class DerivationPaths
|
||||
$"{PurposeFor(kind)}'/{profile.Bip44CoinType}'/{account}'");
|
||||
}
|
||||
|
||||
/// <summary>Sottopath non-hardened change/index sotto l'account (change=0 receiving, change=1 change).</summary>
|
||||
/// <summary>Non-hardened change/index sub-path under the account (change=0 receiving, change=1 change).</summary>
|
||||
public static KeyPath AddressSubPath(bool isChange, int index)
|
||||
{
|
||||
if (index < 0)
|
||||
@@ -73,8 +73,8 @@ public static class DerivationPaths
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parsing di derivation path personalizzati in import (Sparrow-like, §4.2):
|
||||
/// accetta il prefisso "m/" opzionale e gli hardened marker ' oppure h.
|
||||
/// Parsing of custom derivation paths on import (Sparrow-like, §4.2):
|
||||
/// accepts the optional "m/" prefix and hardened markers ' or h.
|
||||
/// </summary>
|
||||
public static bool TryParse(string path, out KeyPath? keyPath)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -4,31 +4,31 @@ using PalladiumWallet.Core.Chain;
|
||||
namespace PalladiumWallet.Core.Crypto;
|
||||
|
||||
/// <summary>
|
||||
/// Astrazione su tutti i tipi di account wallet (HD da seed, HD da xpub/xprv importata,
|
||||
/// chiavi WIF importate). Consente a WalletSynchronizer e TransactionFactory di operare
|
||||
/// indipendentemente dal tipo di keystore sottostante (blueprint §4.4–§4.5).
|
||||
/// Abstraction over all wallet account types (HD from seed, HD from imported xpub/xprv,
|
||||
/// imported WIF keys). Allows WalletSynchronizer and TransactionFactory to operate
|
||||
/// independently of the underlying keystore type (blueprint §4.4–§4.5).
|
||||
/// </summary>
|
||||
public interface IWalletAccount
|
||||
{
|
||||
ScriptKind Kind { get; }
|
||||
ChainProfile Profile { get; }
|
||||
|
||||
/// <summary>True se l'account non può firmare (assenza di chiavi private).</summary>
|
||||
/// <summary>True if the account cannot sign (no private keys present).</summary>
|
||||
bool IsWatchOnly { get; }
|
||||
|
||||
BitcoinAddress GetAddress(bool isChange, int index);
|
||||
BitcoinAddress GetReceiveAddress(int index);
|
||||
BitcoinAddress GetChangeAddress(int index);
|
||||
|
||||
/// <summary>Null se la chiave pubblica non è ricavabile dall'account (indirizzi puri watch-only).</summary>
|
||||
/// <summary>Null if the public key cannot be derived from the account (pure watch-only addresses).</summary>
|
||||
PubKey? GetPublicKey(bool isChange, int index);
|
||||
|
||||
/// <summary>Null se l'account è watch-only o l'indice è fuori range.</summary>
|
||||
/// <summary>Null if the account is watch-only or the index is out of range.</summary>
|
||||
Key? GetPrivateKey(bool isChange, int index);
|
||||
|
||||
/// <summary>
|
||||
/// Per gli account con indirizzi fissi (WIF importati) restituisce la lista
|
||||
/// completa da scansionare; null per gli account HD che usano il gap limit.
|
||||
/// For accounts with fixed addresses (imported WIF keys) returns the full list
|
||||
/// to scan; null for HD accounts that use the gap limit.
|
||||
/// </summary>
|
||||
IReadOnlyList<(BitcoinAddress Address, bool IsChange, int Index)>? FixedAddresses { get; }
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ using PalladiumWallet.Core.Chain;
|
||||
namespace PalladiumWallet.Core.Crypto;
|
||||
|
||||
/// <summary>
|
||||
/// Account da chiavi WIF singole importate (blueprint §4.4 — "Imported"):
|
||||
/// lista fissa di indirizzi, nessuna derivazione HD, nessuna catena di change.
|
||||
/// Il change va sempre al primo indirizzo importato.
|
||||
/// Account built from individually imported WIF keys (blueprint §4.4 — "Imported"):
|
||||
/// fixed list of addresses, no HD derivation, no change chain.
|
||||
/// Change always goes back to the first imported address.
|
||||
/// </summary>
|
||||
public sealed class ImportedKeyAccount : IWalletAccount
|
||||
{
|
||||
@@ -24,7 +24,7 @@ public sealed class ImportedKeyAccount : IWalletAccount
|
||||
ScriptKind kind, ChainProfile profile)
|
||||
{
|
||||
if (entries.Count == 0)
|
||||
throw new ArgumentException("Almeno un indirizzo richiesto.", nameof(entries));
|
||||
throw new ArgumentException("At least one address is required.", nameof(entries));
|
||||
_entries = [.. entries];
|
||||
Kind = kind;
|
||||
Profile = profile;
|
||||
@@ -39,7 +39,7 @@ public sealed class ImportedKeyAccount : IWalletAccount
|
||||
|
||||
public BitcoinAddress GetReceiveAddress(int index) => GetAddress(false, index);
|
||||
|
||||
/// <summary>Il change torna sempre al primo indirizzo importato.</summary>
|
||||
/// <summary>Change always returns to the first imported address.</summary>
|
||||
public BitcoinAddress GetChangeAddress(int index) => _entries[0].Address;
|
||||
|
||||
public PubKey? GetPublicKey(bool isChange, int index)
|
||||
|
||||
@@ -20,8 +20,8 @@ public static class Slip132
|
||||
Encoders.Base58Check.EncodeData([.. profile.ExtKeyHeaders[kind].PrivateBytes(), .. key.ToBytes()]);
|
||||
|
||||
/// <summary>
|
||||
/// Riconosce l'header (→ ScriptKind) e decodifica una chiave pubblica estesa:
|
||||
/// è la via dell'import watch-only (§4.4).
|
||||
/// Recognises the header (→ ScriptKind) and decodes an extended public key:
|
||||
/// this is the watch-only import path (§4.4).
|
||||
/// </summary>
|
||||
public static bool TryDecodePublic(string encoded, ChainProfile profile,
|
||||
out ExtPubKey? key, out ScriptKind kind)
|
||||
|
||||
Reference in New Issue
Block a user