Master Key Export
Description
Section titled “Description”This example demonstrates how to export the master derivation key (MDK) for wallet backup using the KMD export_master_key() 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: Covered operations:
- export_master_key() - Export the master derivation key from a wallet
Prerequisites
Section titled “Prerequisites”- LocalNet running (via
algokit localnet start)
Run This Example
Section titled “Run This Example”From the repository’s examples directory:
cd examplesuv run python kmd_client/07_master_key_export.py# ruff: noqa: N999, C901, PLR0912, PLR0915"""Example: Master Key Export
This example demonstrates how to export the master derivation key (MDK)for wallet backup using the KMD export_master_key() 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:- export_master_key() - Export the master derivation key from a wallet"""
import sys
from shared import ( cleanup_test_wallet, create_kmd_client, create_test_wallet, print_error, print_header, print_info, print_step, print_success,)
from algokit_kmd_client.models import ExportMasterKeyRequest, GenerateKeyRequest, ListKeysRequest
def format_bytes_for_display(data: bytes, show_first: int = 4, show_last: int = 4) -> str: """Format a byte array for display, showing first and last few bytes for security.""" hex_str = data.hex() if len(data) <= show_first + show_last: return hex_str first_bytes = hex_str[: show_first * 2] last_bytes = hex_str[-(show_last * 2) :] return f"{first_bytes}...{last_bytes}"
def main() -> None: print_header("KMD Master Key Export Example")
kmd = create_kmd_client() wallet_handle_token = "" wallet_password = "test-password"
try: # ========================================================================= # Step 1: Create a Test Wallet # ========================================================================= print_step(1, "Creating a test wallet")
test_wallet = create_test_wallet(kmd, wallet_password) wallet_handle_token = test_wallet["wallet_handle_token"]
print_success(f"Test wallet created: {test_wallet['wallet_name']}") print_info(f"Wallet ID: {test_wallet['wallet_id']}")
# ========================================================================= # Step 2: Generate Several Keys in the Wallet # ========================================================================= print_step(2, "Generating several keys in the wallet")
generated_addresses: list[str] = [] num_keys = 3
for i in range(1, num_keys + 1): address = kmd.generate_key(GenerateKeyRequest(wallet_handle_token=wallet_handle_token)).address generated_addresses.append(address) print_info(f"Key {i}: {address}")
print_success(f"Generated {num_keys} keys in the wallet") print_info("") print_info("These keys are deterministically derived from the master derivation key.") print_info("They can be regenerated by creating a new wallet with the same MDK.")
# ========================================================================= # Step 3: Export the Master Derivation Key # ========================================================================= print_step(3, "Exporting the master derivation key with export_master_key()")
master_key = kmd.export_master_key( ExportMasterKeyRequest(wallet_handle_token=wallet_handle_token, wallet_password=wallet_password) ).master_derivation_key
print_success("Master derivation key exported successfully!") print_info("") print_info("export_master_key() response:") key_display = format_bytes_for_display(master_key) print_info(f" master_derivation_key ({len(master_key)} bytes): {key_display}") print_info("") print_info("Note: The wallet password is required to export the master key for security.")
# ========================================================================= # Step 4: Explain What the Master Key Is # ========================================================================= print_step(4, "Understanding the master derivation key")
print_info("") print_info("What is the Master Derivation Key (MDK)?") print_info("-" * 40) print_info("") print_info("The MDK is the cryptographic root of your wallet. It is used to:") print_info("") print_info(" 1. BACKUP/RECOVERY: Store this key to recover your wallet") print_info(" - Create a new wallet with the MDK to restore it") print_info(" - Call generate_key() the same number of times to recover keys") print_info(f" - In this example, calling generate_key() {num_keys} times would") print_info(" regenerate the exact same addresses") print_info("") print_info(" 2. DETERMINISTIC DERIVATION: Keys are derived in sequence") print_info(" - First generate_key() call always produces the same address") print_info(" - Second call produces the same second address, etc.") print_info(" - This sequence is reproducible with the same MDK")
# ========================================================================= # Step 5: Important Limitations # ========================================================================= print_step(5, "Important limitations - Imported keys")
print_info("") print_info("IMPORTANT: Imported keys CANNOT be recovered from the MDK!") print_info("-" * 40) print_info("") print_info("The MDK only protects keys generated with generate_key().") print_info("") print_info("Keys imported with import_key():") print_info(" - Are stored in the wallet database") print_info(" - Can be used for transactions while the wallet exists") print_info(" - CANNOT be regenerated from the MDK") print_info(" - Must be backed up separately using export_key()") print_info("") print_info("To fully backup a wallet with imported keys:") print_info(" 1. Export and store the MDK (for generated keys)") print_info(" 2. Export and store each imported key separately") print_info(" 3. Or backup the entire wallet database file")
# ========================================================================= # Step 6: Security Implications # ========================================================================= print_step(6, "Security implications")
print_info("") print_info("SECURITY WARNING: Handle the MDK with extreme care!") print_info("-" * 40) print_info("") print_info("Anyone with access to your MDK can:") print_info(" - Recreate your entire wallet") print_info(" - Generate all your derived keys") print_info(" - Sign transactions and move your funds") print_info("") print_info("Best practices for MDK storage:") print_info(" - Never store it in plain text on your computer") print_info(" - Use hardware security modules (HSM) for production") print_info(" - Consider splitting the key using Shamir Secret Sharing") print_info(" - Store backups in secure, offline locations") print_info(" - Never transmit the MDK over insecure channels") print_info("") print_info("The MDK in this example is for demonstration only.") print_info("In production, implement proper key management practices.")
# ========================================================================= # Step 7: Verify Keys Can Be Listed # ========================================================================= print_step(7, "Verifying wallet state")
list_result = kmd.list_keys_in_wallet(ListKeysRequest(wallet_handle_token=wallet_handle_token)).addresses
print_success(f"Wallet contains {len(list_result)} key(s)") print_info("") print_info("Generated addresses (would be recoverable from MDK):") for i, addr in enumerate(list_result): print_info(f" {i + 1}. {addr}")
# ========================================================================= # Cleanup # ========================================================================= print_step(8, "Cleaning up test wallet")
cleanup_test_wallet(kmd, wallet_handle_token) wallet_handle_token = "" # Mark as cleaned up
print_success("Test wallet handle released")
# ========================================================================= # Summary # ========================================================================= print_header("Summary") print_info("This example demonstrated master key export in KMD:") print_info("") print_info(" export_master_key()") print_info(" Parameters: wallet_handle_token, wallet_password") print_info(f" Returns: master_derivation_key ({len(master_key)}-byte bytes)") print_info("") print_info("Key takeaways:") print_info(" - The MDK is the root key for deterministic key derivation") print_info(f" - MDK is {len(master_key)} bytes (256 bits) for ed25519") print_info(" - Wallet password is required to export the MDK") print_info(" - Generated keys can be recovered with the MDK") print_info(" - Imported keys CANNOT be recovered with the MDK") print_info(" - The MDK must be stored securely - it controls all funds!") print_info("") print_info("Note: The test wallet remains in KMD (wallets cannot be deleted via API).") except Exception as e: print_error(f"Error: {e}") print_info("") print_info("Troubleshooting:") print_info(" - Ensure LocalNet is running: algokit localnet start") print_info(" - If LocalNet issues occur: algokit localnet reset") print_info(" - Check that KMD is accessible on port 4002")
# Cleanup on error if wallet_handle_token: cleanup_test_wallet(kmd, wallet_handle_token)
sys.exit(1)
if __name__ == "__main__": main()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