@hdwallet/core
Version:
A complete Hierarchical Deterministic (HD) Wallet generator for 200+ cryptocurrencies, built with TypeScript.
1,378 lines (1,366 loc) • 1.86 MB
JavaScript
const __$G = (typeof globalThis !== 'undefined' ? globalThis: typeof window !== 'undefined' ? window: typeof global !== 'undefined' ? global: typeof self !== 'undefined' ? self: {});
// SPDX-License-Identifier: MIT
const __name__ = 'hdwallet';
const __version__ = '1.0.0-beta.10';
const __license__ = 'MIT';
const __author__ = 'Meheret Tesfaye Batu';
const __email__ = 'meherett.batu@gmail.com';
// export const __documentation__: string = '...';
const __description__ = 'A complete Hierarchical Deterministic (HD) Wallet generator for 200+ cryptocurrencies, built with TypeScript.';
const __url__ = 'https://hdwallet.io';
const __source__ = 'https://github.com/hdwallet-io/hdwallet.js';
const __changelog__ = `${__source__}/blob/master/CHANGELOG.md`;
const __tracker__ = `${__source__}/issues`;
const __keywords__ = [
'ecc', 'kholaw', 'slip10', 'ed25519', 'nist256p1', 'secp256k1',
'hd', 'bip32', 'bip44', 'bip49', 'bip84', 'bip86', 'bip141', 'monero', 'cardano',
'entropy', 'mnemonic', 'seed', 'bip39', 'algorand', 'electrum',
'cryptocurrencies', 'bitcoin', 'ethereum', 'cryptography', 'cli', 'cip1852'
];
const __websites__ = [
'https://talonlab.org',
'https://talonlab.gitbook.io/hdwallet',
// __documentation__,
'https://hdwallet.online',
'https://hd.wallet',
__url__
];
var info = /*#__PURE__*/Object.freeze({
__proto__: null,
__name__: __name__,
__version__: __version__,
__license__: __license__,
__author__: __author__,
__email__: __email__,
__description__: __description__,
__url__: __url__,
__source__: __source__,
__changelog__: __changelog__,
__tracker__: __tracker__,
__keywords__: __keywords__,
__websites__: __websites__
});
// SPDX-License-Identifier: MIT
class BaseError extends Error {
constructor(message, options) {
if ((options?.expected || options?.got) && options?.detail) {
super(`${message}, (expected: ${options?.expected} | got: ${options?.got}) ${options?.detail}`);
}
else if (options?.expected || options?.got) {
super(`${message}, (expected: ${options?.expected} | got: ${options?.got})`);
}
else if (options?.detail) {
super(`${message} ${options?.detail}`);
}
else {
super(`${message}`);
}
}
}
class TypeError$1 extends BaseError {
}
class EntropyError extends BaseError {
}
class MnemonicError extends BaseError {
}
class SeedError extends BaseError {
}
class ECCError extends BaseError {
}
class ExtendedKeyError extends BaseError {
}
class XPrivateKeyError extends BaseError {
}
class XPublicKeyError extends BaseError {
}
class PrivateKeyError extends BaseError {
}
class WIFError extends BaseError {
}
class PublicKeyError extends BaseError {
}
class ChecksumError extends BaseError {
}
class SemanticError extends BaseError {
}
class NetworkError extends BaseError {
}
class AddressError extends BaseError {
}
class CryptocurrencyError extends BaseError {
}
class SymbolError extends BaseError {
}
class HDError extends BaseError {
}
class DerivationError extends BaseError {
}
const crypto$2 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
/**
* Utilities for hex, bytes, CSPRNG.
* @module
*/
/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
function isBytes(a) {
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
}
/** Asserts something is positive integer. */
function anumber(n) {
if (!Number.isSafeInteger(n) || n < 0)
throw new Error('positive integer expected, got ' + n);
}
/** Asserts something is Uint8Array. */
function abytes(b, ...lengths) {
if (!isBytes(b))
throw new Error('Uint8Array expected');
if (lengths.length > 0 && !lengths.includes(b.length))
throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
}
/** Asserts something is hash */
function ahash(h) {
if (typeof h !== 'function' || typeof h.create !== 'function')
throw new Error('Hash should be wrapped by utils.createHasher');
anumber(h.outputLen);
anumber(h.blockLen);
}
/** Asserts a hash instance has not been destroyed / finished */
function aexists(instance, checkFinished = true) {
if (instance.destroyed)
throw new Error('Hash instance has been destroyed');
if (checkFinished && instance.finished)
throw new Error('Hash#digest() has already been called');
}
/** Asserts output is properly-sized byte array */
function aoutput(out, instance) {
abytes(out);
const min = instance.outputLen;
if (out.length < min) {
throw new Error('digestInto() expects output buffer of length at least ' + min);
}
}
/** Cast u8 / u16 / u32 to u32. */
function u32(arr) {
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
}
/** Zeroize a byte array. Warning: JS provides no guarantees. */
function clean(...arrays) {
for (let i = 0; i < arrays.length; i++) {
arrays[i].fill(0);
}
}
/** Create DataView of an array for easy byte-level manipulation. */
function createView(arr) {
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
}
/** The rotate right (circular right shift) operation for uint32 */
function rotr(word, shift) {
return (word << (32 - shift)) | (word >>> shift);
}
/** The rotate left (circular left shift) operation for uint32 */
function rotl(word, shift) {
return (word << shift) | ((word >>> (32 - shift)) >>> 0);
}
/** Is current platform little-endian? Most are. Big-Endian platform: IBM */
const isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();
/** The byte swap operation for uint32 */
function byteSwap(word) {
return (((word << 24) & 0xff000000) |
((word << 8) & 0xff0000) |
((word >>> 8) & 0xff00) |
((word >>> 24) & 0xff));
}
/** Conditionally byte swap if on a big-endian platform */
const swap8IfBE = isLE
? (n) => n
: (n) => byteSwap(n);
/** In place byte swap for Uint32Array */
function byteSwap32(arr) {
for (let i = 0; i < arr.length; i++) {
arr[i] = byteSwap(arr[i]);
}
return arr;
}
const swap32IfBE = isLE
? (u) => u
: byteSwap32;
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
const hasHexBuiltin = /* @__PURE__ */ (() =>
// @ts-ignore
typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();
// Array where index 0xf0 (240) is mapped to string 'f0'
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
/**
* Convert byte array to hex string. Uses built-in function, when available.
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
*/
function bytesToHex$1(bytes) {
abytes(bytes);
// @ts-ignore
if (hasHexBuiltin)
return bytes.toHex();
// pre-caching improves the speed 6x
let hex = '';
for (let i = 0; i < bytes.length; i++) {
hex += hexes[bytes[i]];
}
return hex;
}
// We use optimized technique to convert hex string to byte array
const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
function asciiToBase16(ch) {
if (ch >= asciis._0 && ch <= asciis._9)
return ch - asciis._0; // '2' => 50-48
if (ch >= asciis.A && ch <= asciis.F)
return ch - (asciis.A - 10); // 'B' => 66-(65-10)
if (ch >= asciis.a && ch <= asciis.f)
return ch - (asciis.a - 10); // 'b' => 98-(97-10)
return;
}
/**
* Convert hex string to byte array. Uses built-in function, when available.
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
*/
function hexToBytes$1(hex) {
if (typeof hex !== 'string')
throw new Error('hex string expected, got ' + typeof hex);
// @ts-ignore
if (hasHexBuiltin)
return Uint8Array.fromHex(hex);
const hl = hex.length;
const al = hl / 2;
if (hl % 2)
throw new Error('hex string expected, got unpadded hex of length ' + hl);
const array = new Uint8Array(al);
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
const n1 = asciiToBase16(hex.charCodeAt(hi));
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
if (n1 === undefined || n2 === undefined) {
const char = hex[hi] + hex[hi + 1];
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
}
array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
}
return array;
}
/**
* Converts string to bytes using UTF8 encoding.
* @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
*/
function utf8ToBytes(str) {
if (typeof str !== 'string')
throw new Error('string expected');
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
}
/**
* Normalizes (non-hex) string or Uint8Array to Uint8Array.
* Warning: when Uint8Array is passed, it would NOT get copied.
* Keep in mind for future mutable operations.
*/
function toBytes(data) {
if (typeof data === 'string')
data = utf8ToBytes(data);
abytes(data);
return data;
}
/**
* Helper for KDFs: consumes uint8array or string.
* When string is passed, does utf8 decoding, using TextDecoder.
*/
function kdfInputToBytes(data) {
if (typeof data === 'string')
data = utf8ToBytes(data);
abytes(data);
return data;
}
/** Copies several Uint8Arrays into one. */
function concatBytes$1(...arrays) {
let sum = 0;
for (let i = 0; i < arrays.length; i++) {
const a = arrays[i];
abytes(a);
sum += a.length;
}
const res = new Uint8Array(sum);
for (let i = 0, pad = 0; i < arrays.length; i++) {
const a = arrays[i];
res.set(a, pad);
pad += a.length;
}
return res;
}
function checkOpts(defaults, opts) {
if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')
throw new Error('options should be object or undefined');
const merged = Object.assign(defaults, opts);
return merged;
}
/** For runtime check if class implements interface */
class Hash {
}
/** Wraps hash function, creating an interface on top of it */
function createHasher(hashCons) {
const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
const tmp = hashCons();
hashC.outputLen = tmp.outputLen;
hashC.blockLen = tmp.blockLen;
hashC.create = () => hashCons();
return hashC;
}
function createOptHasher(hashCons) {
const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();
const tmp = hashCons({});
hashC.outputLen = tmp.outputLen;
hashC.blockLen = tmp.blockLen;
hashC.create = (opts) => hashCons(opts);
return hashC;
}
/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
function randomBytes$1(bytesLength = 32) {
if (crypto$2 && typeof crypto$2.getRandomValues === 'function') {
return crypto$2.getRandomValues(new Uint8Array(bytesLength));
}
// Legacy Node.js compatibility
if (crypto$2 && typeof crypto$2.randomBytes === 'function') {
return Uint8Array.from(crypto$2.randomBytes(bytesLength));
}
throw new Error('crypto.getRandomValues must be defined');
}
// SPDX-License-Identifier: MIT
function getBytes(data, encoding = 'hex') {
if (data == null) {
return new Uint8Array();
}
// Already a Uint8Array?
if (data instanceof Uint8Array) {
return data;
}
// Array of numbers?
if (Array.isArray(data)) {
return new Uint8Array(data);
}
// From here on: data is a string
const str = data;
switch (encoding) {
case 'hex': {
// Strip optional 0x/0X
let s = str.startsWith('0x') || str.startsWith('0X') ? str.slice(2) : str;
// Pad odd length
if (s.length % 2 === 1)
s = '0' + s;
// Split into byte-pairs and parse
return Uint8Array.from(s.match(/.{1,2}/g).map(b => parseInt(b, 16)));
}
case 'utf8':
return new TextEncoder().encode(str);
case 'base64':
// atob → binary-string → map char codes
return Uint8Array.from(atob(str), c => c.charCodeAt(0));
default:
throw new Error(`Unsupported encoding: ${encoding}`);
}
}
function toBuffer(input, encoding = 'utf8') {
if (typeof input === 'string') {
switch (encoding) {
case 'utf8':
// UTF-8 encode a string
return new TextEncoder().encode(input);
case 'base64':
// atob gives a binary‐string; map char→byte
return Uint8Array.from(atob(input), c => c.charCodeAt(0));
case 'hex':
// split every two hex digits → parse → byte
return Uint8Array.from(input.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
default:
throw new Error(`Unsupported encoding: ${encoding}`);
}
}
// If it's already an ArrayBuffer or TypedArray
if (input instanceof ArrayBuffer) {
return new Uint8Array(input);
}
if (ArrayBuffer.isView(input)) {
return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
}
// Fallback: try Array-like (e.g. number[])
return Uint8Array.from(input);
}
function hexToBytes(hex) {
const normalized = hex.startsWith('0x') ? hex.slice(2) : hex;
if (normalized.length % 2 !== 0) {
throw new Error(`Invalid hex string length: ${normalized.length}`);
}
const bytes = new Uint8Array(normalized.length / 2);
for (let i = 0; i < bytes.length; i++) {
bytes[i] = parseInt(normalized.substr(i * 2, 2), 16);
}
return bytes;
}
function bytesToHex(bytes, prefix = false) {
const hex = Array.from(bytes)
.map(b => b.toString(16).padStart(2, '0'))
.join('');
return prefix ? `0x${hex}` : hex;
}
function bytesToString(data) {
if (data == null ||
(typeof data === 'string' && data.length === 0) ||
(data instanceof Uint8Array && data.length === 0)) {
return '';
}
if (typeof data === 'string') {
// If it’s a valid even-length hex string (0–9, A–F, a–f), return it lowercased:
if (data.length % 2 === 0 && /^[0-9A-Fa-f]+$/.test(data)) {
return data.toLowerCase();
}
// Otherwise treat `data` as UTF-8 text: encode to Uint8Array then to hex
const encoder = new TextEncoder();
const bytes = encoder.encode(data);
return bytesToHex(bytes);
}
// Uint8Array case: just convert those bytes to hex
return bytesToHex(data);
}
function randomBytes(len) {
if (!Number.isInteger(len) || len <= 0) {
throw new Error('randomBytes: length must be a positive integer');
}
return randomBytes$1(len);
}
function bytesToInteger(bytes, littleEndian = false) {
// if little-endian, reverse into a new array
const data = littleEndian
? bytes.slice().reverse()
: bytes;
return data.reduce((acc, b) => (acc << BigInt(8)) + BigInt(b), BigInt(0));
}
function ensureString(data) {
if (data instanceof Uint8Array) {
return new TextDecoder().decode(data);
}
if (typeof data === 'string') {
return data;
}
throw new TypeError$1('Invalid value for string');
}
function stringToInteger(data) {
let buf;
if (typeof data === 'string') {
// treat string as hex (even-length hex string)
buf = hexToBytes(data);
}
else {
buf = data;
}
let val = BigInt(0);
for (let i = 0; i < buf.length; i++) {
val = (val << BigInt(8)) + BigInt(buf[i]);
}
return val;
}
function equalBytes(a, b) {
if (a.length !== b.length)
return false;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i])
return false;
}
return true;
}
function integerToBytes(value, length, endianness = 'big') {
// coerce to BigInt without using 0n
let val = typeof value === 'number' ? BigInt(value) : value;
if (val < BigInt(0)) {
throw new Error(`Cannot convert negative integers: ${val}`);
}
// build big-endian array
const bytes = [];
const ZERO = BigInt(0);
const SHIFT = BigInt(8);
const MASK = BigInt(0xff);
while (val > ZERO) {
// val & 0xffn → val & MASK
bytes.unshift(Number(val & MASK));
// val >>= 8n → val = val >> SHIFT
val = val >> SHIFT;
}
if (bytes.length === 0) {
bytes.push(0);
}
// pad/truncate
if (length !== undefined) {
if (bytes.length > length) {
throw new Error(`Integer too large to fit in ${length} bytes`);
}
while (bytes.length < length) {
bytes.unshift(0);
}
}
const result = new Uint8Array(bytes);
return endianness === 'little' ? result.reverse() : result;
}
function concatBytes(...chunks) {
const totalLength = chunks.reduce((sum, arr) => sum + arr.length, 0);
const result = new Uint8Array(totalLength);
let offset = 0;
for (const chunk of chunks) {
result.set(chunk, offset);
offset += chunk.length;
}
return result;
}
function bytesToBinaryString(data, zeroPadBits = 0) {
const bits = Array.from(data)
.map((b) => b.toString(2).padStart(8, '0'))
.join('');
return bits.length < zeroPadBits ? bits.padStart(zeroPadBits, '0') : bits;
}
function binaryStringToInteger(data) {
const bin = typeof data === 'string'
? data
: bytesToBinaryString(data);
const clean = bin.trim();
return BigInt('0b' + clean);
}
function integerToBinaryString(data, zeroPadBits = 0) {
const big = typeof data === 'bigint' ? data : BigInt(data);
const bits = big.toString(2);
return bits.length < zeroPadBits
? bits.padStart(zeroPadBits, '0')
: bits;
}
function binaryStringToBytes(data, zeroPadByteLen = 0) {
const bits = typeof data === 'string'
? data.trim()
: bytesToBinaryString(data);
const bitLen = bits.length;
const val = BigInt('0b' + bits);
let hex = val.toString(16);
if (hex.length % 2 === 1) {
hex = '0' + hex;
}
const byteLen = zeroPadByteLen > 0
? zeroPadByteLen
: Math.ceil(bitLen / 8);
const expectedHexLen = byteLen * 2;
if (hex.length < expectedHexLen) {
hex = hex.padStart(expectedHexLen, '0');
}
return hexToBytes(hex);
}
function isAllEqual(...inputs) {
if (inputs.length < 2)
return true;
const getTag = (v) => {
if (typeof v === 'string')
return 'string';
if (typeof v === 'number')
return 'number';
if (typeof v === 'boolean')
return 'boolean';
if (Array.isArray(v)) {
if (v.every(i => typeof i === 'number'))
return 'array:number';
if (v.every(i => typeof i === 'string'))
return 'array:string';
if (v.every(i => typeof i === 'boolean'))
return 'array:boolean';
return 'array:unknown';
}
if (v instanceof Uint8Array)
return 'uint8array';
if (v instanceof ArrayBuffer)
return 'arraybuffer';
if (ArrayBuffer.isView(v))
return 'view';
return 'unknown';
};
const firstTag = getTag(inputs[0]);
if (firstTag === 'unknown' || firstTag === 'array:unknown')
return false;
for (const v of inputs.slice(1)) {
if (getTag(v) !== firstTag)
return false;
}
if (firstTag === 'string' || firstTag === 'number' || firstTag === 'boolean') {
const first = inputs[0];
return inputs.every(v => v === first);
}
if (firstTag.startsWith('array:')) {
const firstArr = inputs[0];
const len = firstArr.length;
return inputs.slice(1).every(item => {
const arr = item;
if (arr.length !== len)
return false;
for (let i = 0; i < len; i++) {
if (arr[i] !== firstArr[i])
return false;
}
return true;
});
}
const normalize = (v) => {
if (v instanceof Uint8Array)
return v;
if (v instanceof ArrayBuffer)
return new Uint8Array(v);
return new Uint8Array(v.buffer, v.byteOffset, v.byteLength);
};
const firstArr = normalize(inputs[0]);
const len = firstArr.byteLength;
return inputs.slice(1).every(item => {
const arr = normalize(item);
if (arr.byteLength !== len)
return false;
for (let i = 0; i < len; i++) {
if (arr[i] !== firstArr[i])
return false;
}
return true;
});
}
function generatePassphrase(length = 32, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
const bytes = randomBytes(length);
let result = '';
for (let i = 0; i < length; i++) {
result += chars[bytes[i] % chars.length];
}
return result;
}
function getHmac(eccName) {
const encoder = new TextEncoder();
if ([
'Kholaw-Ed25519', 'SLIP10-Ed25519', 'SLIP10-Ed25519-Blake2b', 'SLIP10-Ed25519-Monero',
].includes(eccName)) {
return encoder.encode('ed25519 seed');
}
else if (eccName === 'SLIP10-Nist256p1') {
return encoder.encode('Nist256p1 seed');
}
else if (eccName === 'SLIP10-Secp256k1') {
return encoder.encode('Bitcoin seed');
}
throw new DerivationError('Unknown ECC name');
}
function excludeKeys(nested, keys) {
const out = {};
const keySet = new Set(keys); // optional optimization
for (const [k, v] of Object.entries(nested)) {
const normKey = k.replace(/-/g, '_');
if (keySet.has(normKey))
continue;
if (v &&
typeof v === 'object' &&
!Array.isArray(v) &&
!(v instanceof Uint8Array) &&
!(v instanceof Uint8Array)) {
out[k] = excludeKeys(v, keys);
}
else {
out[k] = v;
}
}
return out;
}
function pathToIndexes(path) {
if (path === 'm' || path === 'm/')
return [];
if (!path.startsWith('m/')) {
throw new DerivationError(`Bad path format, expected 'm/0'/0', got '${path}'`);
}
return path
.slice(2)
.split('/')
.map(i => i.endsWith("'")
? parseInt(i.slice(0, -1), 10) + 0x80000000
: parseInt(i, 10));
}
function indexesToPath(indexes) {
return ('m' +
indexes
.map(i => i & 0x80000000
? `/${(i & ~0x80000000).toString()}'`
: `/${i.toString()}`)
.join(''));
}
function normalizeIndex(index, hardened = false) {
if (typeof index === 'number') {
if (index < 0)
throw new DerivationError(`Bad index: ${index}`);
return [index, hardened];
}
if (typeof index === 'string') {
const m = index.match(/^(\d+)(?:-(\d+))?$/);
if (!m) {
throw new DerivationError(`Bad index format, got '${index}'`);
}
const from = parseInt(m[1], 10);
const to = m[2] ? parseInt(m[2], 10) : undefined;
if (to === undefined)
return [from, hardened];
if (from > to) {
throw new DerivationError(`Range start ${from} > end ${to}`);
}
return [from, to, hardened];
}
if (Array.isArray(index)) {
const [a, b] = index;
if (index.length !== 2 || typeof a !== 'number' || typeof b !== 'number') {
throw new DerivationError(`Bad index tuple: ${JSON.stringify(index)}`);
}
if (a < 0 || b < 0) {
throw new DerivationError(`Negative in tuple: ${index}`);
}
if (a > b) {
throw new DerivationError(`Range start ${a} > end ${b}`);
}
return [a, b, hardened];
}
throw new DerivationError(`Invalid index instance, got ${typeof index}`);
}
function normalizeDerivation(path, indexes) {
let _path = 'm';
const _indexes = [];
const _deriv = [];
if (indexes && path) {
throw new DerivationError('Provide either path or indexes, not both');
}
if (indexes) {
path = indexesToPath(indexes);
}
if (!path || path === 'm' || path === 'm/') {
return [`${_path}/`, _indexes, _deriv];
}
if (!path.startsWith('m/')) {
throw new DerivationError(`Bad path format, got '${path}'`);
}
for (const seg of path.slice(2).split('/')) {
const hardened = seg.endsWith("'");
const core = hardened ? seg.slice(0, -1) : seg;
const parts = core.split('-').map(x => parseInt(x, 10));
if (parts.length === 2) {
const [from, to] = parts;
if (from > to) {
throw new DerivationError(`Range start ${from} > end ${to}`);
}
_deriv.push([from, to, hardened]);
_indexes.push(to + (hardened ? 0x80000000 : 0));
_path += hardened ? `/${to}'` : `/${to}`;
}
else {
const idx = parts[0];
_deriv.push([idx, hardened]);
_indexes.push(idx + (hardened ? 0x80000000 : 0));
_path += hardened ? `/${idx}'` : `/${idx}`;
}
}
return [_path, _indexes, _deriv];
}
function indexTupleToInteger(idx) {
if (idx.length === 2) {
const [i, h] = idx;
return i + (h ? 0x80000000 : 0);
}
else {
const [from, to, h] = idx;
return to + (h ? 0x80000000 : 0);
}
}
function indexTupleToString(idx) {
if (idx.length === 2) {
const [i, h] = idx;
return `${i}${h ? "'" : ''}`;
}
else {
const [from, to, h] = idx;
return `${from}-${to}${h ? "'" : ''}`;
}
}
function indexStringToTuple(i) {
const hardened = i.endsWith("'");
const num = parseInt(hardened ? i.slice(0, -1) : i, 10);
return [num, hardened];
}
function xor(a, b) {
if (a.length !== b.length)
throw new DerivationError('Uint8Arrays must match length for XOR');
return getBytes(a.map((x, i) => x ^ b[i]));
}
function addNoCarry(a, b) {
if (a.length !== b.length)
throw new DerivationError('Uint8Arrays must match length for addNoCarry');
return getBytes(a.map((x, i) => (x + b[i]) & 0xff));
}
function multiplyScalarNoCarry(data, scalar) {
return getBytes(data.map(x => (x * scalar) & 0xff));
}
function isBitsSet(value, bitNum) {
return (value & (1 << bitNum)) !== 0;
}
function areBitsSet(value, mask) {
return (value & mask) !== 0;
}
function setBit(value, bitNum) {
return value | (1 << bitNum);
}
function setBits(value, mask) {
return value | mask;
}
function resetBit(value, bitNum) {
return value & ~(1 << bitNum);
}
function resetBits(value, mask) {
return value & ~mask;
}
function bytesReverse(data) {
return getBytes(data).reverse();
}
function convertBits$2(data, fromBits, toBits) {
const input = Array.isArray(data) ? data : Array.from(data);
const maxVal = (1 << toBits) - 1;
let acc = 0;
let bits = 0;
const out = [];
for (const val of input) {
if (val < 0 || val >> fromBits) {
return null;
}
acc |= val << bits;
bits += fromBits;
while (bits >= toBits) {
out.push(acc & maxVal);
acc >>= toBits;
bits -= toBits;
}
}
if (bits > 0) {
out.push(acc & maxVal);
}
return out;
}
function bytesChunkToWords(bytesChunk, wordsList, endianness) {
const len = BigInt(wordsList.length);
let chunkNum = bytesToInteger(new Uint8Array(bytesChunk), endianness !== 'big');
const i1 = Number(chunkNum % len);
const i2 = Number(((chunkNum / len) + BigInt(i1)) % len);
const i3 = Number(((chunkNum / len / len) + BigInt(i2)) % len);
return [wordsList[i1], wordsList[i2], wordsList[i3]];
}
function wordsToBytesChunk(w1, w2, w3, wordsList, endianness) {
const len = BigInt(wordsList.length);
const idxMap = new Map(wordsList.map((w, i) => [w, BigInt(i)]));
const i1 = idxMap.get(w1);
const i2 = idxMap.get(w2);
const i3 = idxMap.get(w3);
const chunk = i1 + len * ((i2 - i1 + len) % len) + len * len * ((i3 - i2 + len) % len);
const u8 = integerToBytes(chunk, 4, endianness);
return getBytes(u8);
}
function toCamelCase(input) {
return input.toLowerCase().replace(/-([a-z])/g, (_, char) => char.toUpperCase());
}
function ensureTypeMatch(instanceOrClass, expectedType, options = {}) {
const tryMatch = (type) => {
if (type === 'any')
return true;
if (type === 'null')
return instanceOrClass === null;
if (type === 'array')
return Array.isArray(instanceOrClass);
if (typeof type === 'string')
return typeof instanceOrClass === type;
if (typeof type === 'function') {
if (typeof instanceOrClass === 'function') {
let proto = instanceOrClass;
while (proto && proto !== Function.prototype) {
if (proto === type)
return true;
proto = Object.getPrototypeOf(proto);
}
return false;
}
return options.strict
? instanceOrClass?.constructor === type
: instanceOrClass instanceof type;
}
return false;
};
const allExpectedTypes = [expectedType, ...(options.otherTypes || [])];
const matched = allExpectedTypes.find(tryMatch);
if (!matched && (options.errorClass || options.otherTypes)) {
const expectedNames = allExpectedTypes.map((type) => typeof type === 'function' ? type.name : String(type));
const gotName = typeof instanceOrClass === 'function'
? instanceOrClass.name
: instanceOrClass?.constructor?.name ?? typeof instanceOrClass;
if (options.errorClass) {
throw new options.errorClass(`Invalid type`, {
expected: expectedNames, got: gotName
});
}
else {
throw new TypeError$1(`Invalid type`, {
expected: expectedNames, got: gotName
});
}
}
return matched && options.errorClass ? instanceOrClass : {
value: instanceOrClass, isValid: tryMatch(expectedType)
};
}
var utils = /*#__PURE__*/Object.freeze({
__proto__: null,
getBytes: getBytes,
toBuffer: toBuffer,
hexToBytes: hexToBytes,
bytesToHex: bytesToHex,
bytesToString: bytesToString,
randomBytes: randomBytes,
bytesToInteger: bytesToInteger,
ensureString: ensureString,
stringToInteger: stringToInteger,
equalBytes: equalBytes,
integerToBytes: integerToBytes,
concatBytes: concatBytes,
bytesToBinaryString: bytesToBinaryString,
binaryStringToInteger: binaryStringToInteger,
integerToBinaryString: integerToBinaryString,
binaryStringToBytes: binaryStringToBytes,
isAllEqual: isAllEqual,
generatePassphrase: generatePassphrase,
getHmac: getHmac,
excludeKeys: excludeKeys,
pathToIndexes: pathToIndexes,
indexesToPath: indexesToPath,
normalizeIndex: normalizeIndex,
normalizeDerivation: normalizeDerivation,
indexTupleToInteger: indexTupleToInteger,
indexTupleToString: indexTupleToString,
indexStringToTuple: indexStringToTuple,
xor: xor,
addNoCarry: addNoCarry,
multiplyScalarNoCarry: multiplyScalarNoCarry,
isBitsSet: isBitsSet,
areBitsSet: areBitsSet,
setBit: setBit,
setBits: setBits,
resetBit: resetBit,
resetBits: resetBits,
bytesReverse: bytesReverse,
convertBits: convertBits$2,
bytesChunkToWords: bytesChunkToWords,
wordsToBytesChunk: wordsToBytesChunk,
toCamelCase: toCamelCase,
ensureTypeMatch: ensureTypeMatch
});
// SPDX-License-Identifier: MIT
class NestedNamespace {
constructor(data) {
if (data instanceof Set) {
data.forEach(item => {
this[item] = item;
});
}
else if (Array.isArray(data)) {
data.forEach(item => {
if (item != null && typeof item === 'object' && !Array.isArray(item)) {
Object.entries(item).forEach(([key, value]) => {
this[key] = (value != null && typeof value === 'object')
? new NestedNamespace(value)
: value;
});
}
else {
this[item] = item;
}
});
}
else {
Object.entries(data).forEach(([key, value]) => {
this[key] = (value != null && typeof value === 'object')
? new NestedNamespace(value)
: value;
});
}
}
}
const SLIP10_ED25519_CONST = {
PRIVATE_KEY_BYTE_LENGTH: 32,
PUBLIC_KEY_PREFIX: integerToBytes(0x00),
PUBLIC_KEY_BYTE_LENGTH: 32
};
const KHOLAW_ED25519_CONST = {
...SLIP10_ED25519_CONST,
PRIVATE_KEY_BYTE_LENGTH: 64
};
const SLIP10_SECP256K1_CONST = {
POINT_COORDINATE_BYTE_LENGTH: 32,
PRIVATE_KEY_BYTE_LENGTH: 32,
PRIVATE_KEY_UNCOMPRESSED_PREFIX: 0x00,
PRIVATE_KEY_COMPRESSED_PREFIX: 0x01,
PUBLIC_KEY_UNCOMPRESSED_PREFIX: integerToBytes(0x04),
PUBLIC_KEY_COMPRESSED_BYTE_LENGTH: 33,
PUBLIC_KEY_UNCOMPRESSED_BYTE_LENGTH: 65,
CHECKSUM_BYTE_LENGTH: 4
};
class Info extends NestedNamespace {
SOURCE_CODE;
WHITEPAPER;
WEBSITES;
constructor(data) {
super(data);
}
}
class WitnessVersions extends NestedNamespace {
getWitnessVersion(address) {
return this[address.toUpperCase()];
}
}
class Entropies extends NestedNamespace {
isEntropy(entropy) {
return this.getEntropies().includes(entropy);
}
getEntropies() {
return Object.values(this);
}
}
class Mnemonics extends NestedNamespace {
isMnemonic(mnemonic) {
return this.getMnemonics().includes(mnemonic);
}
getMnemonics() {
return Object.values(this);
}
}
class Seeds extends NestedNamespace {
isSeed(seed) {
return this.getSeeds().includes(seed);
}
getSeeds() {
return Object.values(this);
}
}
class HDs extends NestedNamespace {
isHD(hd) {
return this.getHDS().includes(hd);
}
getHDS() {
return Object.values(this);
}
}
class Addresses extends NestedNamespace {
isAddress(address) {
return this.getAddresses().includes(address);
}
getAddresses() {
return Object.values(this);
}
length() {
return this.getAddresses().length;
}
}
class AddressTypes extends NestedNamespace {
isAddressType(addressType) {
return this.getAddressTypes().includes(addressType);
}
getAddressTypes() {
return Object.values(this);
}
}
class AddressPrefixes extends NestedNamespace {
isAddressPrefix(addressPrefix) {
return this.getAddressPrefixes().includes(addressPrefix);
}
getAddressPrefixes() {
return Object.values(this);
}
}
class Networks extends NestedNamespace {
isNetwork(network) {
return this.getNetworks().includes(network.toLowerCase());
}
getNetworks() {
return Object.keys(this).map(k => k.toLowerCase());
}
getNetwork(network) {
if (!this.isNetwork(network)) {
throw new NetworkError(`${network} network is not available`);
}
return this[network.toUpperCase()];
}
}
class Params extends NestedNamespace {
}
class ExtendedKeyVersions extends NestedNamespace {
isVersion(version) {
return Object.values(this).includes(Number(bytesToInteger(version)));
}
getVersions() {
return Object.keys(this).map(k => k.toLowerCase().replace(/_/g, '-'));
}
getVersion(name) {
return this[name.toUpperCase().replace(/-/g, '_')];
}
getName(version) {
const intVer = bytesToInteger(version);
return Object.entries(this).find(([, v]) => v === intVer)?.[0];
}
}
class XPrivateKeyVersions extends ExtendedKeyVersions {
}
class XPublicKeyVersions extends ExtendedKeyVersions {
}
class PUBLIC_KEY_TYPES {
static UNCOMPRESSED = 'uncompressed';
static COMPRESSED = 'compressed';
static getTypes() {
return [this.UNCOMPRESSED, this.COMPRESSED];
}
}
class WIF_TYPES {
static WIF = 'wif';
static WIF_COMPRESSED = 'wif-compressed';
static getTypes() {
return [this.WIF, this.WIF_COMPRESSED];
}
}
class SEMANTICS {
static P2WPKH = 'p2wpkh';
static P2WPKH_IN_P2SH = 'p2wpkh-in-p2sh';
static P2WSH = 'p2wsh';
static P2WSH_IN_P2SH = 'p2wsh-in-p2sh';
static getTypes() {
return [this.P2WPKH, this.P2WPKH_IN_P2SH, this.P2WSH, this.P2WSH_IN_P2SH];
}
}
class MODES {
static STANDARD = 'standard';
static SEGWIT = 'segwit';
static getTypes() {
return [this.STANDARD, this.SEGWIT];
}
}
var consts = /*#__PURE__*/Object.freeze({
__proto__: null,
NestedNamespace: NestedNamespace,
SLIP10_ED25519_CONST: SLIP10_ED25519_CONST,
KHOLAW_ED25519_CONST: KHOLAW_ED25519_CONST,
SLIP10_SECP256K1_CONST: SLIP10_SECP256K1_CONST,
Info: Info,
WitnessVersions: WitnessVersions,
Entropies: Entropies,
Mnemonics: Mnemonics,
Seeds: Seeds,
HDs: HDs,
Addresses: Addresses,
AddressTypes: AddressTypes,
AddressPrefixes: AddressPrefixes,
Networks: Networks,
Params: Params,
ExtendedKeyVersions: ExtendedKeyVersions,
XPrivateKeyVersions: XPrivateKeyVersions,
XPublicKeyVersions: XPublicKeyVersions,
PUBLIC_KEY_TYPES: PUBLIC_KEY_TYPES,
WIF_TYPES: WIF_TYPES,
SEMANTICS: SEMANTICS,
MODES: MODES
});
/**
* HMAC: RFC2104 message authentication code.
* @module
*/
class HMAC extends Hash {
constructor(hash, _key) {
super();
this.finished = false;
this.destroyed = false;
ahash(hash);
const key = toBytes(_key);
this.iHash = hash.create();
if (typeof this.iHash.update !== 'function')
throw new Error('Expected instance of class which extends utils.Hash');
this.blockLen = this.iHash.blockLen;
this.outputLen = this.iHash.outputLen;
const blockLen = this.blockLen;
const pad = new Uint8Array(blockLen);
// blockLen can be bigger than outputLen
pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
for (let i = 0; i < pad.length; i++)
pad[i] ^= 0x36;
this.iHash.update(pad);
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
this.oHash = hash.create();
// Undo internal XOR && apply outer XOR
for (let i = 0; i < pad.length; i++)
pad[i] ^= 0x36 ^ 0x5c;
this.oHash.update(pad);
clean(pad);
}
update(buf) {
aexists(this);
this.iHash.update(buf);
return this;
}
digestInto(out) {
aexists(this);
abytes(out, this.outputLen);
this.finished = true;
this.iHash.digestInto(out);
this.oHash.update(out);
this.oHash.digestInto(out);
this.destroy();
}
digest() {
const out = new Uint8Array(this.oHash.outputLen);
this.digestInto(out);
return out;
}
_cloneInto(to) {
// Create new instance without calling constructor since key already in state and we don't know it.
to || (to = Object.create(Object.getPrototypeOf(this), {}));
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
to = to;
to.finished = finished;
to.destroyed = destroyed;
to.blockLen = blockLen;
to.outputLen = outputLen;
to.oHash = oHash._cloneInto(to.oHash);
to.iHash = iHash._cloneInto(to.iHash);
return to;
}
clone() {
return this._cloneInto();
}
destroy() {
this.destroyed = true;
this.oHash.destroy();
this.iHash.destroy();
}
}
/**
* HMAC: RFC2104 message authentication code.
* @param hash - function that would be used e.g. sha256
* @param key - message key
* @param message - message data
* @example
* import { hmac } from '@noble/hashes/hmac';
* import { sha256 } from '@noble/hashes/sha2';
* const mac1 = hmac(sha256, 'key', 'message');
*/
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
hmac.create = (hash, key) => new HMAC(hash, key);
var D$1=new Uint32Array(1);var n$1=new Uint32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]);function t$2(x=new Uint8Array,B=0){D$1[0]=B^4294967295;for(let A of x)D$1[0]=n$1[(D$1[0]^A)&255]^D$1[0]>>>8;return (D$1[0]^4294967295)>>>0}
var B$1=new Uint16Array(1);var n=new Uint16Array([0,4129,8258,12387,16516,20645,24774,28903,33032,37161,41290,45419,49548,53677,57806,61935,4657,528,12915,8786,21173,17044,29431,25302,37689,33560,45947,41818,54205,50076,62463,58334,9314,13379,1056,5121,25830,29895,17572,21637,42346,46411,34088,38153,58862,62927,50604,54669,13907,9842,5649,1584,30423,26358,22165,18100,46939,42874,38681,34616,63455,59390,55197,51132,18628,22757,26758,30887,2112,6241,10242,14371,51660,55789,59790,63919,35144,39273,43274,47403,23285,19156,31415,27286,6769,2640,14899,10770,56317,52188,64447,60318,39801,35672,47931,43802,27814,31879,19684,23749,11298,15363,3168,7233,60846,64911,52716,56781,44330,48395,36200,40265,32407,28342,24277,20212,15891,11826,7761,3696,65439,61374,57309,53244,48923,44858,40793,36728,37256,33193,45514,41451,53516,49453,61774,57711,4224,161,12482,8419,20484,16421,28742,24679,33721,37784,41979,46042,49981,54044,58239,62302,689,4752,8947,13010,16949,21012,25207,29270,46570,42443,38312,34185,62830,58703,54572,50445,13538,9411,5280,1153,29798,25671,21540,17413,42971,47098,34713,38840,59231,63358,50973,55100,9939,14066,1681,5808,26199,30326,17941,22068,55628,51565,63758,59695,39368,35305,47498,43435,22596,18533,30726,26663,6336,2273,14466,10403,52093,56156,60223,64286,35833,39896,43963,48026,19061,23124,27191,31254,2801,6864,10931,14994,64814,60687,56684,52557,48554,44427,40424,36297,31782,27655,23652,19525,15522,11395,7392,3265,61215,65342,53085,57212,44955,49082,36825,40952,28183,32310,20053,24180,11923,16050,3793,7920]);function t$1(x=new Uint8Array,A=0){B$1[0]=A;for(let C of x)B$1[0]=n[B$1[0]>>>8^C]^B$1[0]<<8;return B$1[0]}
/**
* Internal Merkle-Damgard hash utils.
* @module
*/
/** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
function setBigUint64(view, byteOffset, value, isLE) {
if (typeof view.setBigUint64 === 'function')
return view.setBigUint64(byteOffset, value, isLE);
const _32n = BigInt(32);
const _u32_max = BigInt(0xffffffff);
const wh = Number((value >> _32n) & _u32_max);
const wl = Number(value & _u32_max);
const h = isLE ? 4 : 0;
const l = isLE ? 0 : 4;
view.setUint32(byteOffset + h, wh, isLE);
view.setUint32(byteOffset + l, wl, isLE);
}
/** Choice: a ? b : c */
function Chi(a, b, c) {
return (a & b) ^ (~a & c);
}
/** Majority function, true if any two inputs is true. */
function Maj(a, b, c) {
return (a & b) ^ (a & c) ^ (b & c);
}
/**
* Merkle-Damgard hash construction base class.
* Could be used to create MD5, RIPEMD, SHA1, SHA2.
*/
class HashMD extends Hash {
constructor(blockLen, outputLen, padOffset, isLE) {
super();
this.finished = false;
this.length = 0;
this.pos = 0;
this.destroyed = false;
this.blockLen = blockLen;
this.outputLen = outputLen;
this.padOffset = padOffset;
this.isLE = isLE;
this.buffer = new Uint8Array(blockLen);
this.view = createView(this.buffer);
}
update(data) {
aexists(this);
data = toBytes(data);
abytes(data);
const { view, buffer, blockLen } = this;
const len = data.length;
for (let pos = 0; pos < len;) {
const take = Math.min(blockLen - this.pos, len - pos);
// Fast path: we have at least one block in input, cast it to view and process
if (take === blockLen) {
const dataView = createView(data);
for (; blockLen <= len - pos; pos += blockLen)
this.process(dataView, pos);
continue;
}
buffer.set(data.subarray(pos, pos + take), this.pos);
this.pos += take;
pos += take;
if (this.pos === blockLen) {
this.process(view, 0);
this.pos = 0;
}
}
this.length += data.length;
this.roundClean();
return this;
}
digestInto(out) {
aexists(this);
aoutput(out, this);
this.finished = true;
// Padding
// We can avoid allocation of buffer for padding completely if it
// was previously not allocated here. But it won't change performance.
const { buffer, view, blockLen, isLE } = this;
let { pos } = this;
// append the bit '1' to the message
buffer[pos++] = 0b10000000;
clean(this.buffer.subarray(pos));
// we have less than padOffset left in buffer, so we cannot put length in
// current block, need process it and pad again
if (this.padOffset > blockLen - pos) {
this.process(view, 0);
pos = 0;
}
// Pad until full block byte with zeros
for (let i = pos; i < blockLen; i++)
buffer[i] = 0;
// Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
// You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
// So we just write lowest 64 bits of that value.
setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
this.process(view, 0);
const oview = createView(out);
const len = this.outputLen;
// NOTE: we do division by 4 later, which should be fused in single op with modulo by JIT
if (len % 4)
throw new Error('_sha2: outputLen should be aligned to 32bit');
const outLen = len / 4;
const state = this.get();
if (outLen > state.length)
throw new Error('_sha2: outputLen bigger than state');
for (let i = 0; i < outLen; i++)
oview.setUint32(4 * i, state[i], isLE);
}
digest() {
const { buffer, outputLen } = this;
this.digestInto(buffer);
const res = buffer.slice(0, outputLen);
this.de