HD Wallet API
The HD Wallet API provides hierarchical deterministic wallet functionality, allowing you to derive multiple keys and addresses from a single master key. This is an alternative to the Account API that supports enhanced privacy through key derivation and follows BIP32/CIP1852 standards.
Key Features
Section titled “Key Features”- Hierarchical Key Derivation: Generate multiple keys from a single master key
- Separate Addresses: Use a new address for each payment. Addresses in one account share a stake key, so they can be linked on-chain
- BIP32/CIP1852 Compliance: Follow industry standards for key derivation
- Multi-Account Support: Manage multiple accounts within a single wallet
- Deterministic Generation: Same mnemonic always generates same addresses
Core Classes
Section titled “Core Classes”Wallet Interface
Section titled “Wallet Interface”The main interface for HD wallet operations, providing methods for address generation, account management, and transaction signing.
DefaultWallet Class
Section titled “DefaultWallet Class”The default implementation of the Wallet interface, supporting standard HD wallet functionality.
Create one with the static methods on Wallet: Wallet.create(network) for a new mnemonic, or Wallet.createFromMnemonic(network, mnemonic) to restore one.
Key Methods:
getBaseAddress()- Get base address at specific indexgetEntAddress()- Get enterprise address at specific indexsign()- Sign transactions with wallet keys
Usage Examples
Section titled “Usage Examples”Creating HD Wallets
Section titled “Creating HD Wallets”Create wallets with different mnemonic lengths and configurations:
// Create wallet with 24-word mnemonic (default)Wallet wallet = Wallet.create(Networks.testnet());String mnemonic = wallet.getMnemonic();System.out.println("Generated 24-word mnemonic");
// Create wallet with 15-word mnemonicWallet wallet15 = Wallet.create(Networks.testnet(), Words.FIFTEEN);String mnemonic15 = wallet15.getMnemonic();System.out.println("Generated 15-word mnemonic");
// Create wallet with 12-word mnemonicWallet wallet12 = Wallet.create(Networks.testnet(), Words.TWELVE);String mnemonic12 = wallet12.getMnemonic();System.out.println("Generated 12-word mnemonic");Restoring Wallets
Section titled “Restoring Wallets”Restore wallets from existing mnemonic phrases:
// Restore wallet from mnemonicString mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";Wallet restoredWallet = Wallet.createFromMnemonic(Networks.mainnet(), mnemonic);
// Restore wallet for specific accountWallet accountWallet = Wallet.createFromMnemonic(Networks.mainnet(), mnemonic, 1);Address Generation
Section titled “Address Generation”Generate multiple addresses from a single wallet:
// Generate base addresses at different indexesAddress address0 = wallet.getBaseAddress(0);Address address1 = wallet.getBaseAddress(1);Address address2 = wallet.getBaseAddress(2);
System.out.println("Address 0: " + address0.getAddress());System.out.println("Address 1: " + address1.getAddress());System.out.println("Address 2: " + address2.getAddress());
// Generate enterprise addresses (no staking)Address entAddress0 = wallet.getEntAddress(0);Address entAddress1 = wallet.getEntAddress(1);
System.out.println("Enterprise Address 0: " + entAddress0.getAddress());System.out.println("Enterprise Address 1: " + entAddress1.getAddress());Multi-Account Management
Section titled “Multi-Account Management”Manage multiple accounts within a single wallet:
// Get addresses for different accountsAddress account0Address = wallet.getBaseAddress(0, 0); // Account 0, Index 0Address account1Address = wallet.getBaseAddress(1, 0); // Account 1, Index 0Address account2Address = wallet.getBaseAddress(2, 0); // Account 2, Index 0
// Switch between accountswallet.setAccountNo(0); // Switch to account 0Address currentAccountAddress = wallet.getBaseAddress(0);
wallet.setAccountNo(1); // Switch to account 1Address newAccountAddress = wallet.getBaseAddress(0);Account Object Access
Section titled “Account Object Access”Get Account objects for transaction operations:
// Get account at specific index for current account numberAccount account0 = wallet.getAccountAtIndex(0);Account account1 = wallet.getAccountAtIndex(1);
// Get account for specific account number and indexAccount specificAccount = wallet.getAccount(1, 5); // Account 1, Index 5
// Use accounts for transaction signingString accountAddress = account0.baseAddress();Transaction signedTx = account0.sign(transaction);Advanced Usage
Section titled “Advanced Usage”A New Address for Each Payment
Section titled “A New Address for Each Payment”To give each payment its own address, increment the address index. This separates payment credentials, but base addresses in one account share a stake key, so anyone can link them on-chain:
// Generate a fresh address for each transactionAddress address0 = wallet.getBaseAddress(0); // First transactionAddress address1 = wallet.getBaseAddress(1); // Second transactionAddress address2 = wallet.getBaseAddress(2); // Third transactionWallet Recovery and Scanning
Section titled “Wallet Recovery and Scanning”Implement wallet recovery with address scanning:
// Configure wallet scanningDefaultWallet wallet = new DefaultWallet(Networks.testnet());
// Set gap limit for address scanningwallet.setGapLimit(50); // Scan 50 consecutive empty addresses
// Set specific indexes to scan (bypass gap limit)wallet.setIndexesToScan(new int[]{0, 1, 2, 5, 10, 20});
// Scan for used addressespublic List<Address> scanForUsedAddresses(Wallet wallet, UtxoSupplier utxoSupplier) { List<Address> usedAddresses = new ArrayList<>(); int gapCount = 0; int index = 0;
while (gapCount < wallet.getGapLimit()) { Address address = wallet.getBaseAddress(index); List<Utxo> utxos = utxoSupplier.getAll(address.getAddress());
if (!utxos.isEmpty()) { usedAddresses.add(address); gapCount = 0; // Reset gap counter } else { gapCount++; } index++; }
return usedAddresses;}Key Management
Section titled “Key Management”Access and manage wallet keys securely:
// Get root key pair (if available)Optional<HdKeyPair> rootKeyPair = wallet.getRootKeyPair();if (rootKeyPair.isPresent()) { HdKeyPair keyPair = rootKeyPair.get(); System.out.println("Root key available");}
// Get root private key bytesOptional<byte[]> rootPrivateKey = wallet.getRootPvtKey();if (rootPrivateKey.isPresent()) { byte[] keyBytes = rootPrivateKey.get(); System.out.println("Root private key: " + keyBytes.length + " bytes");}
// Get stake address for delegationString stakeAddress = wallet.getStakeAddress();System.out.println("Stake Address: " + stakeAddress);Transaction Signing
Section titled “Transaction Signing”With QuickTx, use the wallet as the sender and the signer. It selects the wallet’s UTXOs and signs with the right keys:
Tx tx = new Tx() .payToAddress(receiverAddress, Amount.ada(10)) .from(wallet);
TxResult result = new QuickTxBuilder(backendService) .compose(tx) .withSigner(SignerProviders.signerFrom(wallet)) .completeAndWait();To sign a transaction you built yourself, pass the WalletUtxos it spends. Each one needs its derivation path, which the wallet’s UTXO selection sets; without paths, signing fails with “No signers found!”:
Set<WalletUtxo> walletUtxos = ...; // the wallet UTXOs this transaction spendsTransaction signedTx = wallet.sign(transaction, walletUtxos);
// Sign with stake keyTransaction stakeSignedTx = wallet.signWithStakeKey(transaction);
// Combined signingTransaction fullySignedTx = wallet.sign( wallet.signWithStakeKey(transaction), walletUtxos);Best Practices
Section titled “Best Practices”Secure Wallet Creation
Section titled “Secure Wallet Creation”// Generate wallet securelyWallet secureWallet = Wallet.create(Networks.mainnet());String mnemonic = secureWallet.getMnemonic();
// Store mnemonic securely (encrypted storage recommended)// Never store mnemonic in plain textstoreSecurely(mnemonic);
// Recreate wallet when neededWallet restoredWallet = Wallet.createFromMnemonic(Networks.mainnet(), mnemonic);Address Management Strategy
Section titled “Address Management Strategy”Use different account numbers to organize addresses by purpose. Each account has its own stake key:
// Personal addresses (account 0)Address personalAddr = wallet.getBaseAddress(0, 0);
// Savings addresses (account 1)Address savingsAddr = wallet.getBaseAddress(1, 0);
// Business addresses (account 2)Address businessAddr = wallet.getBaseAddress(2, 0);HD Wallet vs Account API Comparison
Section titled “HD Wallet vs Account API Comparison”| Feature | HD Wallet API | Account API |
|---|---|---|
| Key Management | Hierarchical key derivation | Single key pair |
| Address Generation | Multiple derived addresses | Fixed addresses |
| Addresses per payment | A new one each time, linkable through the stake key | One per account instance |
| Use Case | Applications managing many addresses | Simple applications |
| Complexity | Medium to High | Low |
| Multi-Account | Native support | Manual management |
Use Account API if your application is using only one address or account.