Master Key Export
Description
Section titled “Description”This example demonstrates how to export the master derivation key (MDK) for wallet backup using the KMD exportMasterKey() method.
Key concepts:
- The master derivation key (MDK) is the root key used to deterministically generate all keys in the wallet
- With the MDK, you can recreate a wallet and regenerate all derived keys
- Imported keys CANNOT be recovered from the MDK
- The MDK should be stored securely as it can regenerate all wallet keys
Prerequisites
Section titled “Prerequisites”- LocalNet running (via
algokit localnet start) - Covered operations:
- exportMasterKey() - Export the master derivation key from a wallet
Run This Example
Section titled “Run This Example”From the repository root:
cd examplesnpm run example kmd_client/07-master-key-export.ts/** * Example: Master Key Export * * This example demonstrates how to export the master derivation key (MDK) * for wallet backup using the KMD `exportMasterKey()` method. * * Key concepts: * - The master derivation key (MDK) is the root key used to deterministically * generate all keys in the wallet * - With the MDK, you can recreate a wallet and regenerate all derived keys * - Imported keys CANNOT be recovered from the MDK * - The MDK should be stored securely as it can regenerate all wallet keys * * Prerequisites: * - LocalNet running (via `algokit localnet start`) * * Covered operations: * - exportMasterKey() - Export the master derivation key from a wallet */
import { cleanupTestWallet, createKmdClient, createTestWallet, printError, printHeader, printInfo, printStep, printSuccess,} from '../shared/utils.js';
/** * Format a byte array for display, showing first and last few bytes for security */function formatBytesForDisplay(bytes: Uint8Array, showFirst = 4, showLast = 4): string { const hex = Buffer.from(bytes).toString('hex'); if (bytes.length <= showFirst + showLast) { return hex; } const firstBytes = hex.slice(0, showFirst * 2); const lastBytes = hex.slice(-(showLast * 2)); return `${firstBytes}...${lastBytes}`;}
async function main() { printHeader('KMD Master Key Export Example');
const kmd = createKmdClient(); let walletHandleToken = ''; const walletPassword = 'test-password';
try { // ========================================================================= // Step 1: Create a Test Wallet // ========================================================================= printStep(1, 'Creating a test wallet');
const testWallet = await createTestWallet(kmd, walletPassword); walletHandleToken = testWallet.walletHandleToken;
printSuccess(`Test wallet created: ${testWallet.walletName}`); printInfo(`Wallet ID: ${testWallet.walletId}`);
// ========================================================================= // Step 2: Generate Several Keys in the Wallet // ========================================================================= printStep(2, 'Generating several keys in the wallet');
const generatedAddresses: string[] = []; const numKeys = 3;
for (let i = 1; i <= numKeys; i++) { const result = await kmd.generateKey({ walletHandleToken }); generatedAddresses.push(result.address.toString()); printInfo(`Key ${i}: ${result.address}`); }
printSuccess(`Generated ${numKeys} keys in the wallet`); printInfo(''); printInfo('These keys are deterministically derived from the master derivation key.'); printInfo('They can be regenerated by creating a new wallet with the same MDK.');
// ========================================================================= // Step 3: Export the Master Derivation Key // ========================================================================= printStep(3, 'Exporting the master derivation key with exportMasterKey()');
const exportResult = await kmd.exportMasterKey({ walletHandleToken, walletPassword, });
const masterKey = exportResult.masterDerivationKey;
printSuccess('Master derivation key exported successfully!'); printInfo(''); printInfo('ExportMasterKeyResponse fields:'); printInfo( ` masterDerivationKey (${masterKey.length} bytes): ${formatBytesForDisplay(masterKey)}`, ); printInfo(''); printInfo('Note: The wallet password is required to export the master key for security.');
// ========================================================================= // Step 4: Explain What the Master Key Is // ========================================================================= printStep(4, 'Understanding the master derivation key');
printInfo(''); printInfo('What is the Master Derivation Key (MDK)?'); printInfo('-'.repeat(40)); printInfo(''); printInfo('The MDK is the cryptographic root of your wallet. It is used to:'); printInfo(''); printInfo(' 1. BACKUP/RECOVERY: Store this key to recover your wallet'); printInfo(' - Create a new wallet with the MDK to restore it'); printInfo(' - Call generateKey() the same number of times to recover keys'); printInfo(` - In this example, calling generateKey() ${numKeys} times would`); printInfo(' regenerate the exact same addresses'); printInfo(''); printInfo(' 2. DETERMINISTIC DERIVATION: Keys are derived in sequence'); printInfo(' - First generateKey() call always produces the same address'); printInfo(' - Second call produces the same second address, etc.'); printInfo(' - This sequence is reproducible with the same MDK');
// ========================================================================= // Step 5: Important Limitations // ========================================================================= printStep(5, 'Important limitations - Imported keys');
printInfo(''); printInfo('IMPORTANT: Imported keys CANNOT be recovered from the MDK!'); printInfo('-'.repeat(40)); printInfo(''); printInfo('The MDK only protects keys generated with generateKey().'); printInfo(''); printInfo('Keys imported with importKey():'); printInfo(' - Are stored in the wallet database'); printInfo(' - Can be used for transactions while the wallet exists'); printInfo(' - CANNOT be regenerated from the MDK'); printInfo(' - Must be backed up separately using exportKey()'); printInfo(''); printInfo('To fully backup a wallet with imported keys:'); printInfo(' 1. Export and store the MDK (for generated keys)'); printInfo(' 2. Export and store each imported key separately'); printInfo(' 3. Or backup the entire wallet database file');
// ========================================================================= // Step 6: Security Implications // ========================================================================= printStep(6, 'Security implications');
printInfo(''); printInfo('⚠️ SECURITY WARNING: Handle the MDK with extreme care!'); printInfo('-'.repeat(40)); printInfo(''); printInfo('Anyone with access to your MDK can:'); printInfo(' - Recreate your entire wallet'); printInfo(' - Generate all your derived keys'); printInfo(' - Sign transactions and move your funds'); printInfo(''); printInfo('Best practices for MDK storage:'); printInfo(' - Never store it in plain text on your computer'); printInfo(' - Use hardware security modules (HSM) for production'); printInfo(' - Consider splitting the key using Shamir Secret Sharing'); printInfo(' - Store backups in secure, offline locations'); printInfo(' - Never transmit the MDK over insecure channels'); printInfo(''); printInfo('The MDK in this example is for demonstration only.'); printInfo('In production, implement proper key management practices.');
// ========================================================================= // Step 7: Verify Keys Can Be Listed // ========================================================================= printStep(7, 'Verifying wallet state');
const listResult = await kmd.listKeysInWallet({ walletHandleToken });
printSuccess(`Wallet contains ${listResult.addresses.length} key(s)`); printInfo(''); printInfo('Generated addresses (would be recoverable from MDK):'); listResult.addresses.forEach((addr, i) => { printInfo(` ${i + 1}. ${addr}`); });
// ========================================================================= // Cleanup // ========================================================================= printStep(8, 'Cleaning up test wallet');
await cleanupTestWallet(kmd, walletHandleToken); walletHandleToken = ''; // Mark as cleaned up
printSuccess('Test wallet handle released');
// ========================================================================= // Summary // ========================================================================= printHeader('Summary'); printInfo('This example demonstrated master key export in KMD:'); printInfo(''); printInfo(' exportMasterKey()'); printInfo(' Parameters: walletHandleToken, walletPassword'); printInfo(` Returns: masterDerivationKey (${masterKey.length}-byte Uint8Array)`); printInfo(''); printInfo('Key takeaways:'); printInfo(' - The MDK is the root key for deterministic key derivation'); printInfo(` - MDK is ${masterKey.length} bytes (256 bits) for ed25519`); printInfo(' - Wallet password is required to export the MDK'); printInfo(' - Generated keys can be recovered with the MDK'); printInfo(' - Imported keys CANNOT be recovered with the MDK'); printInfo(' - The MDK must be stored securely - it controls all funds!'); printInfo(''); printInfo('Note: The test wallet remains in KMD (wallets cannot be deleted via API).'); } catch (error) { printError(`Error: ${error instanceof Error ? error.message : String(error)}`); printInfo(''); printInfo('Troubleshooting:'); printInfo(' - Ensure LocalNet is running: algokit localnet start'); printInfo(' - If LocalNet issues occur: algokit localnet reset'); printInfo(' - Check that KMD is accessible on port 4002');
// Cleanup on error if (walletHandleToken) { await cleanupTestWallet(kmd, walletHandleToken); }
process.exit(1); }}
main().catch(error => { console.error('Fatal error:', error); process.exit(1);});Other examples in KMD Client
Section titled “Other examples in KMD Client”- KMD Version Information
- Wallet Creation and Listing
- Wallet Session Management
- Key Generation
- Key Import and Export
- Key Listing and Deletion
- Master Key Export
- Multisig Account Setup
- Multisig Account Management
- Transaction Signing with KMD
- Multisig Transaction Signing with KMD
- Program Signing (Delegated Logic Signatures) with KMD
- Multisig Program Signing (Delegated Multisig Logic Signatures) with KMD