A comprehensive hierarchical deterministic wallet implementation in pure C++, compiled to WebAssembly for cross-platform compatibility. BIP-32/39/44 compliant with multi-curve cryptography and multi-chain support.
Core WebAssembly library. BIP-32/39/44 HD key derivation, multi-curve cryptography (secp256k1, Ed25519, NIST P-256), address generation, signing, and encryption for 50+ blockchains.
npm install hd-wallet-wasm
import HDWalletWasm from 'hd-wallet-wasm';
const wallet = await HDWalletWasm();
const mnemonic = wallet.mnemonic.generate(24);
const seed = wallet.mnemonic.toSeed(mnemonic);
const master = wallet.hdkey.fromSeed(seed);
const btcKey = master.derivePath("m/84'/0'/0'/0/0");
const address = wallet.bitcoin.getAddress(btcKey.publicKey(), 2);
Drop-in modal UI for any web app. Provides login, key management, identity (vCard), trust map, and adversarial security bond modals. Attach to any button — fully styleable via CSS custom properties.
npm install hd-wallet-ui
import { createWalletUI } from 'hd-wallet-ui';
const wallet = await createWalletUI();
// Open login modal on any button click
document.getElementById('my-btn')
.addEventListener('click', () => wallet.openLogin());
// Open account/keys modal
wallet.openAccount();
// Remove all injected UI
wallet.destroy();
Headless utilities (address derivation, wallet storage) are also available via hd-wallet-ui/lib.
Full implementation of BIP-32 (HD keys), BIP-39 (mnemonic phrases), BIP-44/49/84 (account hierarchy), and SLIP-44 (coin types).
Support for secp256k1 (Bitcoin, Ethereum), Ed25519 (Solana, Polkadot), NIST P-256, P-384, and X25519 key exchange.
Bitcoin (all address types), Ethereum/EVM, Solana, Cosmos/Tendermint, Polkadot/Substrate, and 50+ coins via SLIP-44.
Compiled to WASM for browser, Node.js, and WASI runtimes. Works with Go, Rust, Python, and any WASI-compatible host.
Abstraction layer for Trezor, Ledger, and KeepKey devices with WASI bridge integration for USB/HID communication.
Secure memory wiping, optional FIPS-compliant mode, and comprehensive input validation for production use.
import HDWalletWasm from 'hd-wallet-wasm'; const wallet = await HDWalletWasm(); const mnemonic = wallet.mnemonic.generate(24); const seed = wallet.mnemonic.toSeed(mnemonic, 'optional passphrase'); const masterKey = wallet.hdkey.fromSeed(seed); const btcKey = masterKey.derivePath("m/84'/0'/0'/0/0"); const btcAddress = wallet.bitcoin.getAddress(btcKey.publicKey(), 2); const ethKey = masterKey.derivePath("m/44'/60'/0'/0/0"); const ethAddress = wallet.ethereum.getAddress(ethKey.publicKey()); console.log('Bitcoin:', btcAddress); console.log('Ethereum:', ethAddress);import HDWalletWasm from 'hd-wallet-wasm'; const wallet = await HDWalletWasm(); const seed = wallet.mnemonic.toSeed(mnemonic, 'passphrase'); const masterKey = wallet.hdkey.fromSeed(seed); // Sign a Bitcoin message (secp256k1) const btcKey = masterKey.derivePath("m/84'/0'/0'/0/0"); const btcSig = wallet.bitcoin.signMessage('Hello Bitcoin!', btcKey.privateKey()); // Sign an Ethereum message (EIP-191) const ethKey = masterKey.derivePath("m/44'/60'/0'/0/0"); const ethSig = wallet.ethereum.signMessage('Hello Ethereum!', ethKey.privateKey()); // Raw secp256k1 recoverable signature const msgHash = wallet.utils.sha256('my message'); const { signature, recoveryId } = wallet.curves.secp256k1.signRecoverable( msgHash, btcKey.privateKey() ); // Ed25519 signing (Solana) const solKey = masterKey.derivePath("m/44'/501'/0'/0/0"); const edSig = wallet.curves.ed25519.sign('payload', solKey.privateKey()); const valid = wallet.curves.ed25519.verify('payload', edSig, solKey.publicKey());import HDWalletWasm from 'hd-wallet-wasm'; const wallet = await HDWalletWasm(); // Generate a 256-bit AES key and 12-byte IV const aesKey = wallet.utils.generateAesKey(256); const iv = wallet.utils.generateIv(); // Encrypt with AES-256-GCM const plaintext = new TextEncoder().encode('Secret message'); const { ciphertext, tag } = wallet.utils.aesGcm.encrypt(aesKey, plaintext, iv); // Decrypt const decrypted = wallet.utils.aesGcm.decrypt(aesKey, ciphertext, tag, iv); console.log(new TextDecoder().decode(decrypted)); // 'Secret message' // With additional authenticated data (AAD) const aad = new TextEncoder().encode('metadata'); const encrypted = wallet.utils.aesGcm.encrypt(aesKey, plaintext, iv, aad); const result = wallet.utils.aesGcm.decrypt( aesKey, encrypted.ciphertext, encrypted.tag, iv, aad );
Rational actors drain compromised keys. Undrained value proves key integrity.
Cryptographic public keys can derive addresses on cryptocurrency networks. By depositing value at those derived addresses, you create a game-theoretic security bond. A rational actor who compromises the private key will drain the funds — the payout is immediate, anonymous, and risk-free. This makes the balance a real-time indicator of key integrity: undrained value implies an uncompromised key.
A public key used for signing data can mathematically derive addresses on multiple blockchain networks (BIP-32/44). One key pair serves both authentication and value custody.
Derived addresses are permissionless — anyone can deposit funds to signal trust in a key. The aggregate balance quantifies the economic cost of compromise.
Draining funds is the dominant strategy: it's immediate, irreversible, and carries zero marginal risk. Undrained value therefore implies no compromise.
Blockchain state is publicly auditable and updates every block. This provides continuous, permissionless proof of key integrity — not a certificate, but a live signal.
Login to derive addresses from your keys and check live balances across multiple blockchain networks.