Nethereum.HdWallet
5.8.0
Prefix Reserved
dotnet add package Nethereum.HdWallet --version 5.8.0
NuGet\Install-Package Nethereum.HdWallet -Version 5.8.0
<PackageReference Include="Nethereum.HdWallet" Version="5.8.0" />
<PackageVersion Include="Nethereum.HdWallet" Version="5.8.0" />
<PackageReference Include="Nethereum.HdWallet" />
paket add Nethereum.HdWallet --version 5.8.0
#r "nuget: Nethereum.HdWallet, 5.8.0"
#:package Nethereum.HdWallet@5.8.0
#addin nuget:?package=Nethereum.HdWallet&version=5.8.0
#tool nuget:?package=Nethereum.HdWallet&version=5.8.0
Nethereum.HDWallet
BIP32 and BIP39 hierarchical deterministic (HD) wallet implementation for generating Ethereum-compatible addresses from mnemonic seed phrases.
Overview
Nethereum.HDWallet implements BIP32 (Hierarchical Deterministic Wallets) and BIP39 (Mnemonic Code for Generating Deterministic Keys) standards to generate an HD tree of Ethereum addresses from a single mnemonic seed phrase. This is the same standard used by MetaMask, TREZOR, MyEtherWallet, Ledger, Jaxx, Exodus, and most hardware/software wallets.
Key Features:
- Generate 12/15/18/21/24-word mnemonic seed phrases (BIP39)
- Derive unlimited Ethereum addresses from a single seed
- Two standard derivation paths:
m/44'/60'/0'/0/x(default) andm/44'/60'/0'/x(Ledger/Electrum) - Compatible with MetaMask, TREZOR, Ledger, MyEtherWallet
- Watch-only public wallets (no private key exposure)
- Direct integration with Web3.Account for transactions
Use Cases:
- Multi-account wallet applications
- Hardware wallet compatibility
- Backup and recovery using mnemonic phrases
- Secure key management without exposing master private key
- Account abstraction and wallet-as-a-service
Installation
dotnet add package Nethereum.HDWallet
Dependencies
External:
- NBitcoin (v7.0.6) - Bitcoin and cryptographic primitives (BIP32/BIP39 implementation)
Nethereum:
- Nethereum.Web3 - Web3 client and account integration
Quick Start
using Nethereum.HdWallet;
using NBitcoin;
// Generate new wallet with random 12-word seed
var wallet = new Wallet(Wordlist.English, WordCount.Twelve);
// Get first 5 addresses
var addresses = wallet.GetAddresses(5);
// Get account for index 0 (for signing transactions)
var account = wallet.GetAccount(0);
// Use with Web3
var web3 = new Web3.Web3(account, "https://mainnet.infura.io/v3/YOUR-PROJECT-ID");
BIP32/BIP39 Standards
BIP39 (Mnemonic Codes)
- Converts random entropy into human-readable words
- Supports 12, 15, 18, 21, or 24 words
- Each word list contains 2048 words
- Optional passphrase for additional security (TREZOR-style)
BIP32 (Hierarchical Deterministic Wallets)
- Derives child keys from master key
- Two derivation paths supported:
m/44'/60'/0'/0/x- Default (MetaMask, TREZOR App, MyEtherWallet, Jaxx, Exodus)m/44'/60'/0'/x- Electrum/Ledger (Electrum, MyEtherWallet Ledger, Ledger Chrome, imToken)
Usage Examples
Example 1: Generate Wallet with Random Seed
using Nethereum.HdWallet;
using NBitcoin;
// Generate wallet with 12-word mnemonic (most common)
var wallet = new Wallet(Wordlist.English, WordCount.Twelve);
Console.WriteLine("Mnemonic: " + string.Join(" ", wallet.Words));
// Example: "army van defense carry jealous true garbage claim echo media make crunch"
Console.WriteLine("Seed: " + wallet.Seed);
// Hex-encoded seed derived from mnemonic
Console.WriteLine("Checksum Valid: " + wallet.IsMnemonicValidChecksum);
// true
// Get first address
var firstAddress = wallet.GetAccount(0).Address;
Console.WriteLine("Address 0: " + firstAddress);
Example 2: Restore Wallet from Existing Mnemonic (Real Test Example)
using Nethereum.HdWallet;
// Restore wallet from mnemonic (e.g., from backup)
const string words = "ripple scissors kick mammal hire column oak again sun offer wealth tomorrow wagon turn fatal";
const string password = "TREZOR"; // Optional password (leave empty string if unused)
var wallet = new Wallet(words, password);
// Wallet is now restored with all the same addresses
var account = wallet.GetAccount(0);
// Use with Web3 for transactions
var web3 = new Web3.Web3(account, "https://mainnet.infura.io/v3/YOUR-PROJECT-ID");
// All addresses derived from this seed will match the original wallet
Example 3: Generate Multiple Addresses
using Nethereum.HdWallet;
using NBitcoin;
var wallet = new Wallet(Wordlist.English, WordCount.Twelve);
// Get first 20 addresses (default)
string[] addresses = wallet.GetAddresses(20);
for (int i = 0; i < addresses.Length; i++)
{
Console.WriteLine($"Account {i}: {addresses[i]}");
}
// Output:
// Account 0: 0x742d35Cc6634C0532925a3b844Bc454e4438f44e
// Account 1: 0x5aeda56215b167893e80b4fe645ba6d5bab767de
// Account 2: 0x6330a553fc93768f612722bb8c2ec78ac90b3bbc
// ...
Example 4: Get Private Key by Index or Address
using Nethereum.HdWallet;
using Nethereum.Hex.HexConvertors.Extensions;
using NBitcoin;
var wallet = new Wallet(Wordlist.English, WordCount.Twelve);
// Get private key by index
byte[] privateKey0 = wallet.GetPrivateKey(0);
Console.WriteLine("Private Key 0: " + privateKey0.ToHex());
// Get private key by address (useful for account recovery)
string targetAddress = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e";
byte[] privateKeyByAddress = wallet.GetPrivateKey(targetAddress, maxIndexSearch: 20);
if (privateKeyByAddress != null)
{
Console.WriteLine("Found private key for address!");
}
else
{
Console.WriteLine("Address not found in first 20 accounts");
}
Example 5: Use Electrum/Ledger Derivation Path
using Nethereum.HdWallet;
using NBitcoin;
// Use Electrum/Ledger path instead of default
var wallet = new Wallet(
Wordlist.English,
WordCount.Twelve,
seedPassword: null,
path: Wallet.ELECTRUM_LEDGER_PATH // "m/44'/60'/0'/x"
);
// Addresses will match Ledger hardware wallet
var addresses = wallet.GetAddresses(5);
Example 6: Generate Wallet with Seed Password (TREZOR-Style)
using Nethereum.HdWallet;
using NBitcoin;
// Same mnemonic + different password = completely different addresses
const string mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
var wallet1 = new Wallet(mnemonic, seedPassword: "password123");
var wallet2 = new Wallet(mnemonic, seedPassword: "different_password");
var address1 = wallet1.GetAccount(0).Address;
var address2 = wallet2.GetAccount(0).Address;
Console.WriteLine("Wallet 1 Address: " + address1);
Console.WriteLine("Wallet 2 Address: " + address2);
// Completely different addresses from same mnemonic!
// This is the 25th word / passphrase feature
// Used for plausible deniability and additional security
Example 7: Public Wallet (Watch-Only, No Private Keys)
using Nethereum.HdWallet;
using NBitcoin;
// Full wallet (has private keys)
var fullWallet = new Wallet(Wordlist.English, WordCount.Twelve);
// Extract public wallet (no private keys exposed)
PublicWallet publicWallet = fullWallet.GetMasterPublicWallet();
// Can generate addresses but cannot sign transactions
string[] watchAddresses = publicWallet.GetAddresses(10);
Console.WriteLine("Watch-only addresses:");
foreach (var address in watchAddresses)
{
Console.WriteLine(address);
}
// Use case: Server-side address generation without private key exposure
// Server can generate addresses, but cannot spend funds
Example 8: Share Extended Public Key (xPub)
using Nethereum.HdWallet;
using Nethereum.Hex.HexConvertors.Extensions;
using NBitcoin;
var wallet = new Wallet(Wordlist.English, WordCount.Twelve);
// Get extended public key (xPub)
var extPubKey = wallet.GetMasterExtPubKey();
byte[] xPubBytes = extPubKey.PubKey.ToBytes();
Console.WriteLine("Extended Public Key: " + xPubBytes.ToHex());
// Share xPub with third-party service
// They can generate addresses but cannot access private keys
// Recreate PublicWallet from xPub on another system
var remotePublicWallet = new PublicWallet(xPubBytes);
var remoteAddresses = remotePublicWallet.GetAddresses(5);
// Addresses match original wallet without exposing private keys
Example 9: Using HDWallet with Web3 Transactions
using Nethereum.HdWallet;
using Nethereum.Web3;
using Nethereum.Hex.HexTypes;
using NBitcoin;
// Create wallet
var wallet = new Wallet(Wordlist.English, WordCount.Twelve);
// Get account 0 with chain ID
var account = wallet.GetAccount(0, chainId: 1); // 1 = Ethereum mainnet
// Create Web3 instance with account
var web3 = new Web3(account, "https://mainnet.infura.io/v3/YOUR-PROJECT-ID");
// Send transaction
var toAddress = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e";
var transactionHash = await web3.Eth.GetEtherTransferService()
.TransferEtherAndWaitForReceiptAsync(toAddress, 0.01m);
Console.WriteLine("Transaction sent: " + transactionHash);
// Use different account from same wallet
var account5 = wallet.GetAccount(5, chainId: 1);
var web3Account5 = new Web3(account5, "https://mainnet.infura.io/v3/YOUR-PROJECT-ID");
API Reference
Wallet
Main class for HD wallet operations with private key access.
public class Wallet
{
// Constants
public const string DEFAULT_PATH = "m/44'/60'/0'/0/x"; // MetaMask, TREZOR, MEW
public const string ELECTRUM_LEDGER_PATH = "m/44'/60'/0'/x"; // Electrum, Ledger
// Constructors
public Wallet(Wordlist wordList, WordCount wordCount, string seedPassword = null, string path = DEFAULT_PATH);
public Wallet(string words, string seedPassword, string path = DEFAULT_PATH);
public Wallet(byte[] seed, string path = DEFAULT_PATH);
// Properties
public string Seed { get; }
public string[] Words { get; }
public bool IsMnemonicValidChecksum { get; }
public string Path { get; }
// Methods
public string[] GetAddresses(int numberOfAddresses = 20);
public byte[] GetPrivateKey(int index);
public byte[] GetPrivateKey(string address, int maxIndexSearch = 20);
public byte[] GetPublicKey(int index);
public Account GetAccount(int index, BigInteger? chainId = null);
public Account GetAccount(string address, int maxIndexSearch = 20, BigInteger? chainId = null);
// Advanced
public ExtKey GetMasterExtKey();
public ExtPubKey GetMasterExtPubKey();
public PublicWallet GetMasterPublicWallet();
public ExtKey GetExtKey(int index, bool hardened = false);
public ExtPubKey GetExtPubKey(int index, bool hardened = false);
public EthECKey GetEthereumKey(int index);
}
PublicWallet
Watch-only wallet (no private key access).
public class PublicWallet
{
// Constructors
public PublicWallet(ExtPubKey extPubKey);
public PublicWallet(ExtKey extKey);
public PublicWallet(byte[] extPublicKey);
public PublicWallet(string extPublicKey);
// Properties
public ExtPubKey ExtPubKey { get; }
// Methods
public string[] GetAddresses(int numberOfAddresses = 20);
public string GetAddress(int index);
public ExtPubKey GetExtPubKey(int index);
public PublicWallet GetChildPublicWallet(int index);
public byte[] GetExtendedPublicKey();
}
Important Notes
Seed Passwords (25th Word)
var wallet1 = new Wallet(mnemonic, seedPassword: ""); // No password
var wallet2 = new Wallet(mnemonic, seedPassword: "secret"); // With password
// SAME mnemonic + DIFFERENT password = DIFFERENT addresses
- Seed password acts as a "25th word"
- Provides plausible deniability (duress wallet)
- Adds extra security layer
- Must be remembered (not part of mnemonic backup)
Derivation Paths
| Path | Format | Used By |
|---|---|---|
| Default | m/44'/60'/0'/0/x |
MetaMask, TREZOR, MEW, Jaxx, Exodus |
| Ledger | m/44'/60'/0'/x |
Ledger, Electrum, MEW (Ledger mode), imToken |
Important: Different paths = different addresses from same seed.
Word Counts
| Words | Entropy | Security | Use Case |
|---|---|---|---|
| 12 | 128-bit | Standard | Most wallets (recommended) |
| 15 | 160-bit | Higher | Enhanced security |
| 18 | 192-bit | Higher | Enhanced security |
| 21 | 224-bit | Highest | Maximum security |
| 24 | 256-bit | Highest | Maximum security |
Recommendation: 12 words is standard and provides excellent security for most use cases.
Account Indexing
// MetaMask account numbering
var account0 = wallet.GetAccount(0); // MetaMask "Account 1"
var account1 = wallet.GetAccount(1); // MetaMask "Account 2"
var account2 = wallet.GetAccount(2); // MetaMask "Account 3"
Note: Index starts at 0, but user-facing UIs typically show "Account 1", "Account 2", etc.
Public Wallet Use Cases
// Use case 1: Payment processor
// Generate addresses on server without private keys
var publicWallet = GetPublicWalletFromSecureStorage();
var depositAddress = publicWallet.GetAddress(customerID);
// Use case 2: Accounting/auditing
// View all addresses and balances without spending ability
// Use case 3: Address generation service
// Generate addresses for users without key exposure
Related Packages
Used By (Consumers)
- Nethereum.Accounts - Account management
- Wallet applications
- Multi-sig services
- Payment processors
Dependencies
- Nethereum.Web3 - Web3 integration
- Nethereum.Signer - Transaction signing
- NBitcoin - BIP32/BIP39 implementation
Additional Resources
- BIP32 Specification
- BIP39 Specification
- BIP44 Specification
- Nethereum Documentation
- Ian Coleman's BIP39 Tool - Test derivation paths
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net452 is compatible. net46 was computed. net461 is compatible. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.5.2
- NBitcoin (>= 7.0.6)
- Nethereum.Web3 (>= 5.8.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
.NETFramework 4.6.1
- NBitcoin (>= 7.0.6)
- Nethereum.Web3 (>= 5.8.0)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
-
.NETStandard 2.0
- NBitcoin (>= 7.0.6)
- Nethereum.Web3 (>= 5.8.0)
- NETStandard.Library (>= 2.0.3)
- Newtonsoft.Json (>= 11.0.2 && < 14.0.0)
NuGet packages (40)
Showing the top 5 NuGet packages that depend on Nethereum.HdWallet:
| Package | Downloads |
|---|---|
|
Sonolib
Sono crypto library |
|
|
Tatum.CSharp.Evm.Local
Evm SDK v2 |
|
|
Tatum.CSharp.Ethereum
Ethereum SDK v2 |
|
|
Tatum.CSharp.Nft
Nft SDK v2 |
|
|
SwitchWallet.NEthereumWrapper
wrapper for Nethereum library. Exposing the most commonly used functionalities of the library |
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on Nethereum.HdWallet:
| Repository | Stars |
|---|---|
|
WalletConnect/WalletConnectSharp
[Deprecated] A C# implementation of the WalletConnect protocol
|
| Version | Downloads | Last Updated |
|---|---|---|
| 5.8.0 | 43 | 1/6/2026 |
| 5.0.0 | 28,566 | 5/28/2025 |
| 4.29.0 | 63,903 | 2/10/2025 |
| 4.28.0 | 31,150 | 1/7/2025 |
| 4.27.1 | 2,168 | 12/24/2024 |
| 4.27.0 | 442 | 12/24/2024 |
| 4.26.0 | 16,007 | 10/1/2024 |
| 4.25.0 | 1,514 | 9/19/2024 |
| 4.21.4 | 28,974 | 8/9/2024 |
| 4.21.3 | 6,667 | 7/22/2024 |
| 4.21.2 | 15,055 | 6/26/2024 |
| 4.21.1 | 529 | 6/26/2024 |
| 4.21.0 | 969 | 6/18/2024 |
| 4.20.0 | 172,052 | 3/28/2024 |
| 4.19.0 | 12,372 | 2/16/2024 |
| 4.18.0 | 53,312 | 11/21/2023 |
| 4.17.1 | 28,338 | 9/28/2023 |
| 4.17.0 | 913 | 9/27/2023 |
| 4.16.0 | 7,961 | 8/14/2023 |
| 4.15.2 | 27,954 | 7/11/2023 |
| 4.15.1 | 1,116 | 7/11/2023 |
| 4.15.0 | 6,467 | 7/11/2023 |
| 4.14.0 | 37,839 | 3/19/2023 |
| 4.13.0 | 5,670 | 2/18/2023 |
| 4.12.0 | 110,999 | 12/9/2022 |
| 4.11.0 | 41,745 | 10/27/2022 |
| 4.9.0 | 12,665 | 9/27/2022 |
| 4.8.0 | 31,485 | 8/24/2022 |
| 4.7.0 | 10,538 | 7/20/2022 |
| 4.6.1 | 10,608 | 6/18/2022 |
| 4.6.0 | 1,573 | 6/16/2022 |
| 4.5.0 | 6,572 | 5/13/2022 |
| 4.4.1 | 2,662 | 4/27/2022 |
| 4.4.0 | 1,439 | 4/27/2022 |
| 4.3.0 | 4,922 | 4/12/2022 |
| 4.2.0 | 17,720 | 2/18/2022 |
| 4.1.1 | 298,251 | 11/4/2021 |
| 4.1.0 | 4,793 | 10/15/2021 |
| 4.0.5 | 7,618 | 8/12/2021 |
| 4.0.4 | 1,389 | 8/10/2021 |
| 4.0.3 | 1,584 | 8/8/2021 |
| 4.0.2 | 1,529 | 8/5/2021 |
| 4.0.1 | 2,010 | 7/28/2021 |
| 4.0.0 | 5,493 | 7/26/2021 |
| 3.8.0 | 60,926 | 7/3/2020 |
| 3.7.1 | 25,695 | 2/13/2020 |
| 3.7.0 | 1,926 | 2/13/2020 |
| 3.6.0 | 3,229 | 1/27/2020 |
| 3.5.0 | 7,150 | 12/31/2019 |
| 3.4.0 | 7,336 | 7/29/2019 |
| 3.2.0 | 28,974 | 4/8/2019 |
| 3.1.2 | 3,088 | 3/13/2019 |
| 3.1.1 | 1,854 | 3/12/2019 |
| 3.1.0 | 1,851 | 3/12/2019 |
| 3.0.0 | 23,096 | 11/28/2018 |
| 3.0.0-rc3 | 1,813 | 10/25/2018 |
| 3.0.0-rc2 | 1,745 | 10/24/2018 |
| 3.0.0-rc1 | 2,009 | 7/25/2018 |
| 2.5.1 | 15,137 | 6/5/2018 |
| 2.5.0 | 2,257 | 6/4/2018 |
| 2.4.0 | 22,566 | 3/11/2018 |
| 2.3.1 | 2,886 | 3/7/2018 |
| 2.3.0 | 2,518 | 3/6/2018 |
| 2.2.3 | 4,250 | 12/16/2017 |
| 2.2.2 | 2,706 | 12/16/2017 |
| 2.2.0 | 2,714 | 12/8/2017 |
| 2.1.0 | 2,873 | 10/23/2017 |