Secure, audited & minimal implementation of BIP32 hierarchical deterministic (HD) wallets.
See the codeAudited & minimal implementation of BIP32 hierarchical deterministic (HD) wallets over secp256k1.
Check out scure-bip39 if you need mnemonic phrases. See key-producer if you need SLIP-0010/BIP32 ed25519 hdkey implementation. Notice Warnings about BIP32.
scure — audited micro-libraries.
npm install @scure/bip32
deno add jsr:@scure/bip32
This module exports a single class HDKey, which should be used like this:
import { HDKey } from '@scure/bip32';
import { sha256 } from '@noble/hashes/sha2.js';
import { randomBytes } from '@noble/hashes/utils.js';
const seed = randomBytes(32);
const root = HDKey.fromMasterSeed(seed);
const base58key = root.privateExtendedKey;
const restored = HDKey.fromExtendedKey(base58key);
const fromJson = HDKey.fromJSON({ xpriv: base58key });
const child = fromJson.derive("m/0/2147483647'/1");
const msgHash = sha256(new TextEncoder().encode('hello scure-bip32'));
// props
[root.depth, root.index, root.chainCode];
[restored.privateKey, restored.publicKey];
const sig = child.sign(msgHash);
child.verify(msgHash, sig);
Note: chainCode property is essentially a private part
of a secret "master" key, it should be guarded from unauthorized access. Byte-array
getters return copies so callers cannot mutate an HDKey's internal state. These
snapshots remain caller-owned and are not zeroed by wipePrivateData().
For backwards compatibility, JSON.stringify() currently serializes both the
private and public extended keys of an HDKey. Treat the result as secret key
material. A future v3 release will make automatic JSON serialization public-only.
The full API is:
class HDKey {
public static HARDENED_OFFSET: number;
public static fromMasterSeed(seed: Uint8Array, versions: Versions): HDKey;
public static fromExtendedKey(base58key: string, versions: Versions): HDKey;
public static fromJSON(json: { xpriv: string } | { xpub: string }): HDKey;
readonly versions: Versions;
readonly depth: number = 0;
readonly index: number = 0;
readonly parentFingerprint: number = 0;
get fingerprint(): number;
get identifier(): Uint8Array | undefined;
get pubKeyHash(): Uint8Array | undefined;
get privateKey(): Uint8Array | null;
get publicKey(): Uint8Array | null;
get chainCode(): Uint8Array | null;
get privateExtendedKey(): string;
get publicExtendedKey(): string;
derive(path: string): HDKey;
deriveChild(index: number): HDKey;
sign(hash: Uint8Array): Uint8Array;
verify(hash: Uint8Array, signature: Uint8Array): boolean;
wipePrivateData(): this;
// TODO(v3): Make automatic JSON serialization public-only.
toJSON(): { xpriv: string; xpub: string };
// Explicitly exports private key material. Treat the result as a secret.
toPrivateJSON(): { xpriv: string; xpub: string };
}
interface Versions {
private: number;
public: number;
}
The module implements bip32 standard: check it out for additional documentation.
The implementation is loosely based on cryptocoinjs/hdkey, which has MIT License.
BIP32 is a bad standard. It would be great if we've had something better.
The library has been audited:
The library was initially developed for js-ethereum-cryptography.
At commit ae00e6d7,
it was extracted to a separate package called micro-bip32.
After the audit we've decided to use @scure NPM namespace for security.
For this package, there are 3 dependencies; and a few dev dependencies:
Copyright (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com)
143 followers · starred Oct 2022
5 followers · starred Jul 2025
51 followers · starred Jan 2024
Secure, audited & minimal implementation of BIP32 hierarchical deterministic (HD) wallets.
See the codeAudited & minimal implementation of BIP32 hierarchical deterministic (HD) wallets over secp256k1.
Check out scure-bip39 if you need mnemonic phrases. See key-producer if you need SLIP-0010/BIP32 ed25519 hdkey implementation. Notice Warnings about BIP32.
scure — audited micro-libraries.
npm install @scure/bip32
deno add jsr:@scure/bip32
This module exports a single class HDKey, which should be used like this:
import { HDKey } from '@scure/bip32';
import { sha256 } from '@noble/hashes/sha2.js';
import { randomBytes } from '@noble/hashes/utils.js';
const seed = randomBytes(32);
const root = HDKey.fromMasterSeed(seed);
const base58key = root.privateExtendedKey;
const restored = HDKey.fromExtendedKey(base58key);
const fromJson = HDKey.fromJSON({ xpriv: base58key });
const child = fromJson.derive("m/0/2147483647'/1");
const msgHash = sha256(new TextEncoder().encode('hello scure-bip32'));
// props
[root.depth, root.index, root.chainCode];
[restored.privateKey, restored.publicKey];
const sig = child.sign(msgHash);
child.verify(msgHash, sig);
Note: chainCode property is essentially a private part
of a secret "master" key, it should be guarded from unauthorized access. Byte-array
getters return copies so callers cannot mutate an HDKey's internal state. These
snapshots remain caller-owned and are not zeroed by wipePrivateData().
For backwards compatibility, JSON.stringify() currently serializes both the
private and public extended keys of an HDKey. Treat the result as secret key
material. A future v3 release will make automatic JSON serialization public-only.
The full API is:
class HDKey {
public static HARDENED_OFFSET: number;
public static fromMasterSeed(seed: Uint8Array, versions: Versions): HDKey;
public static fromExtendedKey(base58key: string, versions: Versions): HDKey;
public static fromJSON(json: { xpriv: string } | { xpub: string }): HDKey;
readonly versions: Versions;
readonly depth: number = 0;
readonly index: number = 0;
readonly parentFingerprint: number = 0;
get fingerprint(): number;
get identifier(): Uint8Array | undefined;
get pubKeyHash(): Uint8Array | undefined;
get privateKey(): Uint8Array | null;
get publicKey(): Uint8Array | null;
get chainCode(): Uint8Array | null;
get privateExtendedKey(): string;
get publicExtendedKey(): string;
derive(path: string): HDKey;
deriveChild(index: number): HDKey;
sign(hash: Uint8Array): Uint8Array;
verify(hash: Uint8Array, signature: Uint8Array): boolean;
wipePrivateData(): this;
// TODO(v3): Make automatic JSON serialization public-only.
toJSON(): { xpriv: string; xpub: string };
// Explicitly exports private key material. Treat the result as a secret.
toPrivateJSON(): { xpriv: string; xpub: string };
}
interface Versions {
private: number;
public: number;
}
The module implements bip32 standard: check it out for additional documentation.
The implementation is loosely based on cryptocoinjs/hdkey, which has MIT License.
BIP32 is a bad standard. It would be great if we've had something better.
The library has been audited:
The library was initially developed for js-ethereum-cryptography.
At commit ae00e6d7,
it was extracted to a separate package called micro-bip32.
After the audit we've decided to use @scure NPM namespace for security.
For this package, there are 3 dependencies; and a few dev dependencies:
Copyright (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com)
143 followers · starred Oct 2022
5 followers · starred Jul 2025
51 followers · starred Jan 2024