This tutorial will guide you through installing and using the BIP32/BIP39 library for the first time. By the end, you'll be able to generate mnemonic phrases, validate them, and derive cryptographic keys.
Before starting, ensure you have:
- Java 21 or higher installed
- Maven 3.6+ installed
- Basic understanding of Java programming
Add the library to your project's pom.xml:
<dependency>
<groupId>xyz.tcheeric</groupId>
<artifactId>bip-utils</artifactId>
<version>2.0.0</version>
</dependency>Build your project to download dependencies:
mvn clean installLet's generate and work with a BIP39 mnemonic phrase.
Create a new Java class:
package com.example;
import xyz.tcheeric.bips.bip39.Bip39;
public class FirstMnemonic {
public static void main(String[] args) {
// Generate a 12-word mnemonic
String mnemonic = Bip39.generateMnemonic(12);
System.out.println("Your mnemonic phrase:");
System.out.println(mnemonic);
}
}Run this program. You should see output like:
Your mnemonic phrase:
witch collapse practice feed shame open despair creek road again ice least
Note: Your mnemonic will be different each time you run the program because it's randomly generated.
Add validation to ensure the mnemonic is correct:
package com.example;
import xyz.tcheeric.bips.bip39.Bip39;
public class ValidateMnemonic {
public static void main(String[] args) {
String mnemonic = Bip39.generateMnemonic(12);
// Validate the mnemonic
boolean isValid = Bip39.isValidMnemonic(mnemonic);
System.out.println("Mnemonic: " + mnemonic);
System.out.println("Is valid: " + isValid);
}
}Output:
Mnemonic: witch collapse practice feed shame open despair creek road again ice least
Is valid: true
Convert your mnemonic to a binary seed:
package com.example;
import xyz.tcheeric.bips.bip39.Bip39;
public class MnemonicToSeed {
public static void main(String[] args) {
String mnemonic = Bip39.generateMnemonic(12);
// Convert to seed (without passphrase)
byte[] seed = Bip39.mnemonicToSeed(mnemonic, "");
System.out.println("Mnemonic: " + mnemonic);
System.out.println("Seed length: " + seed.length + " bytes");
System.out.println("Seed (hex): " + bytesToHex(seed));
}
private static String bytesToHex(byte[] bytes) {
StringBuilder hex = new StringBuilder();
for (byte b : bytes) {
hex.append(String.format("%02x", b));
}
return hex.toString();
}
}Output:
Mnemonic: witch collapse practice feed shame open despair creek road again ice least
Seed length: 64 bytes
Seed (hex): 5c3e6f89a4d7b2c1e8f9d3a2b4c5e6f7...
Now let's derive a cryptographic key from the mnemonic.
package com.example;
import xyz.tcheeric.bips.bip39.Bip39;
import org.bitcoinj.crypto.DeterministicKey;
public class DeriveKeys {
public static void main(String[] args) {
// Generate mnemonic
String mnemonic = Bip39.generateMnemonic(12);
// Derive master key
DeterministicKey masterKey = Bip39.mnemonicToMasterKey(mnemonic, "");
System.out.println("Mnemonic: " + mnemonic);
System.out.println("Master key derived successfully!");
System.out.println("Has private key: " + masterKey.hasPrivKey());
}
}Output:
Mnemonic: witch collapse practice feed shame open despair creek road again ice least
Master key derived successfully!
Has private key: true
Derive a child key using a BIP32 path:
package com.example;
import xyz.tcheeric.bips.bip39.Bip39;
import xyz.tcheeric.bips.bip32.Bip32;
import org.bitcoinj.crypto.DeterministicKey;
public class DeriveChildKey {
public static void main(String[] args) {
// Generate and derive master key
String mnemonic = Bip39.generateMnemonic(12);
DeterministicKey masterKey = Bip39.mnemonicToMasterKey(mnemonic, "");
// Derive child key (first Bitcoin address)
String path = "m/44'/0'/0'/0/0";
DeterministicKey childKey = Bip32.deriveKey(masterKey, path);
System.out.println("Mnemonic: " + mnemonic);
System.out.println("Derivation path: " + path);
System.out.println("Child key derived successfully!");
// Get the private key bytes
byte[] privateKey = Bip32.getPrivateKeyBytes(childKey);
System.out.println("Private key length: " + privateKey.length + " bytes");
}
}Output:
Mnemonic: witch collapse practice feed shame open despair creek road again ice least
Derivation path: m/44'/0'/0'/0/0
Child key derived successfully!
Private key length: 32 bytes
Here's a complete example that puts it all together:
package com.example;
import xyz.tcheeric.bips.bip39.Bip39;
import xyz.tcheeric.bips.bip32.Bip32;
import org.bitcoinj.crypto.DeterministicKey;
public class CompleteExample {
public static void main(String[] args) {
// Step 1: Generate a mnemonic
System.out.println("=== Step 1: Generate Mnemonic ===");
String mnemonic = Bip39.generateMnemonic(12);
System.out.println("Mnemonic: " + mnemonic);
// Step 2: Validate it
System.out.println("\n=== Step 2: Validate Mnemonic ===");
boolean isValid = Bip39.isValidMnemonic(mnemonic);
System.out.println("Valid: " + isValid);
// Step 3: Convert to seed
System.out.println("\n=== Step 3: Convert to Seed ===");
byte[] seed = Bip39.mnemonicToSeed(mnemonic, "");
System.out.println("Seed length: " + seed.length + " bytes");
// Step 4: Derive master key
System.out.println("\n=== Step 4: Derive Master Key ===");
DeterministicKey masterKey = Bip32.deriveMasterKey(seed);
System.out.println("Master key created");
// Step 5: Derive child keys
System.out.println("\n=== Step 5: Derive Child Keys ===");
for (int i = 0; i < 3; i++) {
String path = "m/44'/0'/0'/0/" + i;
DeterministicKey childKey = Bip32.deriveKey(masterKey, path);
byte[] privateKey = Bip32.getPrivateKeyBytes(childKey);
System.out.println("Path " + path + ":");
System.out.println(" Private key: " + bytesToHex(privateKey).substring(0, 16) + "...");
}
}
private static String bytesToHex(byte[] bytes) {
StringBuilder hex = new StringBuilder();
for (byte b : bytes) {
hex.append(String.format("%02x", b));
}
return hex.toString();
}
}In this tutorial, you:
- ✅ Installed the BIP32/BIP39 library
- ✅ Generated a random mnemonic phrase
- ✅ Validated mnemonic phrases
- ✅ Converted mnemonics to seeds
- ✅ Derived master keys from seeds
- ✅ Derived child keys using BIP32 paths
Now that you understand the basics, explore:
- API Overview - See all available operations
- NUT-13 Protocol - Understand the Cashu derivation path
- Implement NUT-13 - Build wallet recovery flows
Solution: Ensure you've run mvn clean install to download dependencies.
Solution: Check that you're using the correct language wordlist. English is default.
Solution: Ensure you're passing the correct seed from mnemonicToSeed(), not the mnemonic string itself.