Socket
Socket
Sign inDemoInstall

dashkeys

Package Overview
Dependencies
Maintainers
2
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dashkeys - npm Package Compare versions

Comparing version 0.3.1 to 0.9.0

base-x.types.js

1411

dashkeys.js

@@ -1,184 +0,1321 @@

(function (exports) {
/** @typedef {import('./base-x.types.js').BaseX} BaseX */
/** @typedef {import('./base-x.types.js').Create} BaseXCreate */
/** @typedef {import('./base-x.types.js').Decode} BaseXDecode */
/** @typedef {import('./base-x.types.js').DecodeUnsafe} BaseXDecodeUnsafe */
/** @typedef {import('./base-x.types.js').Encode} BaseXEncode */
/** @typedef {import('./base58check.types.js').Base58Check} Base58Check */
/** @typedef {import('./base58check.types.js').Checksum} Base58CheckChecksum */
/** @typedef {import('./base58check.types.js').Create} Base58CheckCreate */
/** @typedef {import('./base58check.types.js').Decode} Base58CheckDecode */
/** @typedef {import('./base58check.types.js').DecodeHex} Base58CheckDecodeHex */
/** @typedef {import('./base58check.types.js').Encode} Base58CheckEncode */
/** @typedef {import('./base58check.types.js').EncodeHex} Base58CheckEncodeHex */
/** @typedef {import('./base58check.types.js').EncodeParts} Base58CheckEncodeParts */
/** @typedef {import('./base58check.types.js').Parts} Base58CheckParts */
/** @typedef {import('./base58check.types.js').PrivateParts} Base58CheckPrivateParts */
/** @typedef {import('./base58check.types.js').PubKeyHashParts} Base58CheckPubKeyHashParts */
/** @typedef {import('./base58check.types.js').XPrvParts} Base58CheckXPrvParts */
/** @typedef {import('./base58check.types.js').XPubParts} Base58CheckXPubParts */
/** @typedef {import('./base58check.types.js').Verify} Base58CheckVerify */
/** @typedef {import('./base58check.types.js').VerifyHex} Base58CheckVerifyHex */
/** @typedef {import('./ripemd160.types.js').RIPEMD160} RIPEMD160 */
/** @typedef {import('./ripemd160.types.js').Create} RIPEMD160Create */
/** @typedef {import('./ripemd160.types.js').Digest} RIPEMD160Digest */
/** @typedef {import('./ripemd160.types.js').Hash} RIPEMD160Hash */
/** @typedef {import('./ripemd160.types.js').Update} RIPEMD160Update */
/**
* @typedef {DashKeys}
* @prop {Decode} decode
* @prop {EncodeKeyUint8Array} encodeKey
*/
/**
* @typedef DashKeysUtils
* @prop {Uint8ArrayToHex} bytesToHex
* @prop {GenerateWif} generateWifNonHd
* @prop {HexToUint8Array} hexToBytes
* @prop {Hasher} ripemd160sum
* @prop {Hasher} sha256sum
* @prop {ToPublicKey} toPublicKey
*/
/** @type {BaseX} */
//@ts-ignore
var BaseX = {};
/** @type {Base58Check} */
//@ts-ignore
var Base58Check = {};
/** @type {RIPEMD160} */
//@ts-ignore
var RIPEMD160 = {};
/** @typedef {"4c"} DASH_PKH */
/** @typedef {"8c"} DASH_PKH_TESTNET */
/** @typedef {"cc"} DASH_PRIV_KEY */
/** @typedef {"ef"} DASH_PRIV_KEY_TESTNET */
/** @typedef {"0488ade4"} XPRV */
/** @typedef {"0488b21e"} XPUB */
/** @typedef {"04358394"} TPRV */
/** @typedef {"043587cf"} TPUB */
/** @typedef {"mainnet"|"testnet"|DASH_PKH|DASH_PRIV_KEY|DASH_PKH_TESTNET|DASH_PRIV_KEY_TESTNET|"xprv"|"tprv"|"xpub"|"tpub"|XPRV|XPUB|TPRV|TPUB} VERSION */
/** @typedef {"mainnet"|"cc"|"testnet"|"ef"} VERSION_PRIVATE */
/** @type {DashKeys} */
//@ts-ignore
var DashKeys = ("object" === typeof module && exports) || {};
(function (Window, /** @type {DashKeys} */ _DashKeys) {
"use strict";
let DashKeys = {};
//@ts-ignore
exports.DashKeys = DashKeys;
// generally the same across cryptocurrencies
const BASE58 = `123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz`;
// specific to DASH mainnet and testnet
const DASH_PKH = "4c";
const DASH_PKH_TESTNET = "8c";
const DASH_PRIV_KEY = "cc";
const DASH_PRIV_KEY_TESTNET = "ef";
// generally the same across coins for mainnet
const XPRV = "0488ade4";
const XPUB = "0488b21e";
// sometimes different for various coins on testnet
const TPRV = "04358394";
const TPUB = "043587cf";
/** @type {import('node:crypto')} */
//@ts-ignore
let Crypto = exports.crypto || require("node:crypto");
/** @type {typeof window.crypto} */
let Crypto = Window.crypto || require("node:crypto");
let Utils = {};
/**
* @callback Sha256Sum
* @param {Uint8Array|Buffer} u8
* @returns {Promise<Uint8Array|Buffer>}
*/
/** @type {Uint8ArrayToHex} */
Utils.bytesToHex = function (bytes) {
/** @type {Array<String>} */
let hex = [];
/** @type {Sha256Sum} */
let sha256sum = async function (u8) {
let arrayBuffer = await Crypto.subtle.digest("SHA-256", u8);
let buf = new Uint8Array(arrayBuffer);
return buf;
bytes.forEach(function (b) {
let h = b.toString(16);
h = h.padStart(2, "0");
hex.push(h);
});
return hex.join("");
};
/** @type {import('@dashincubator/base58check').Base58Check} */
let Base58Check =
//@ts-ignore
exports.Base58Check || require("@dashincubator/base58check").Base58Check;
/** @type {GenerateWif} */
Utils.generateWifNonHd = async function (opts) {
/** @type {import('@dashincubator/secp256k1')} */
let Secp256k1 =
//@ts-ignore
Window.nobleSecp256k1 || require("@dashincubator/secp256k1");
/** @type {import('@dashincubator/ripemd160')} */
//@ts-ignore
let RIPEMD160 = exports.RIPEMD160 || require("@dashincubator/ripemd160");
let privBytes = Secp256k1.utils.randomPrivateKey();
let privateKey = Utils.bytesToHex(privBytes);
let version = opts?.version ?? "";
switch (version) {
case "mainnet":
version = DASH_PRIV_KEY;
break;
case "testnet":
version = DASH_PRIV_KEY_TESTNET;
break;
default:
// no change
}
/** @type {import('@dashincubator/secp256k1')} */
let wif = await _DashKeys._dash58check.encode({ privateKey, version });
return wif;
};
/** @type {HexToUint8Array} */
Utils.hexToBytes = function (hex) {
let len = hex.length / 2;
let bytes = new Uint8Array(len);
let index = 0;
for (let i = 0; i < hex.length; i += 2) {
let c = hex.slice(i, i + 2);
let b = parseInt(c, 16);
bytes[index] = b;
index += 1;
}
return bytes;
};
/** @type {Hasher} */
Utils.ripemd160sum = async function (bytes) {
let hashBytes = await RIPEMD160.hash(bytes);
return hashBytes;
};
/** @type {Hasher} */
Utils.sha256sum = async function (bytes) {
let arrayBuffer = await Crypto.subtle.digest("SHA-256", bytes);
let hashBytes = new Uint8Array(arrayBuffer);
return hashBytes;
};
/** @type {ToPublicKey} */
Utils.toPublicKey = async function (privBytes) {
/** @type {import('@dashincubator/secp256k1')} */
let Secp256k1 =
//@ts-ignore
Window.nobleSecp256k1 || require("@dashincubator/secp256k1");
let isCompressed = true;
return Secp256k1.getPublicKey(privBytes, isCompressed);
};
(function () {
// BaseX
// base58 (base-x) encoding / decoding
// Copyright (c) 2022 Dash Incubator (base58)
// Copyright (c) 2021-2022 AJ ONeal (base62)
// Copyright (c) 2018 base-x contributors
// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)
// Distributed under the MIT software license, see the accompanying
// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
//
// Taken from https://github.com/therootcompany/base62.js
// which is a fork of https://github.com/cryptocoinjs/base-x
/** @type {BaseXCreate} */
BaseX.create = function (ALPHABET) {
let baseX = {};
if (!ALPHABET) {
ALPHABET = BASE58;
}
if (ALPHABET.length >= 255) {
throw new TypeError("Alphabet too long");
}
var BASE_MAP = new Uint8Array(256);
for (var j = 0; j < BASE_MAP.length; j += 1) {
BASE_MAP[j] = 255;
}
for (var i = 0; i < ALPHABET.length; i += 1) {
var x = ALPHABET.charAt(i);
var xc = x.charCodeAt(0);
if (BASE_MAP[xc] !== 255) {
throw new TypeError(x + " is ambiguous");
}
BASE_MAP[xc] = i;
}
var BASE = ALPHABET.length;
var LEADER = ALPHABET.charAt(0);
var FACTOR = Math.log(BASE) / Math.log(256); // log(BASE) / log(256), rounded up
var iFACTOR = Math.log(256) / Math.log(BASE); // log(256) / log(BASE), rounded up
/** @type {BaseXDecode} */
baseX.decode = function (string) {
var buffer = decodeUnsafe(string);
if (buffer) {
return buffer;
}
throw new Error("Non-base" + BASE + " character");
};
/** @type {BaseXDecodeUnsafe} */
function decodeUnsafe(source) {
if (typeof source !== "string") {
throw new TypeError("Expected String");
}
if (source.length === 0) {
return new Uint8Array(0);
}
var psz = 0;
// Skip and count leading '1's.
var zeroes = 0;
var length = 0;
while (source[psz] === LEADER) {
zeroes += 1;
psz += 1;
}
// Allocate enough space in big-endian base256 representation.
var size = ((source.length - psz) * FACTOR + 1) >>> 0; // log(58) / log(256), rounded up.
var b256 = new Uint8Array(size);
// Process the characters.
while (source[psz]) {
// Decode character
var carry = BASE_MAP[source.charCodeAt(psz)];
// Invalid character
if (carry === 255) {
return null;
}
var i = 0;
for (
var it3 = size - 1;
(carry !== 0 || i < length) && it3 !== -1;
it3 -= 1, i += 1
) {
carry += (BASE * b256[it3]) >>> 0;
b256[it3] = carry % 256 >>> 0;
carry = (carry / 256) >>> 0;
}
if (carry !== 0) {
throw new Error("Non-zero carry");
}
length = i;
psz += 1;
}
// Skip leading zeroes in b256.
var it4 = size - length;
while (it4 !== size && b256[it4] === 0) {
it4 += 1;
}
var vch = new Uint8Array(zeroes + (size - it4));
var j = zeroes;
while (it4 !== size) {
vch[j] = b256[it4];
j += 1;
it4 += 1;
}
return vch;
}
/** @type {BaseXEncode} */
baseX.encode = function (source) {
if (Array.isArray(source) || !(source instanceof Uint8Array)) {
source = Uint8Array.from(source);
}
if (!(source instanceof Uint8Array)) {
throw new TypeError("Expected Uint8Array");
}
if (source.length === 0) {
return "";
}
// Skip & count leading zeroes.
var zeroes = 0;
var length = 0;
var pbegin = 0;
var pend = source.length;
while (pbegin !== pend && source[pbegin] === 0) {
pbegin += 1;
zeroes += 1;
}
// Allocate enough space in big-endian base58 representation.
var size = ((pend - pbegin) * iFACTOR + 1) >>> 0;
var b58 = new Uint8Array(size);
// Process the bytes.
while (pbegin !== pend) {
var carry = source[pbegin];
// Apply "b58 = b58 * 256 + ch".
var i = 0;
for (
var it1 = size - 1;
(carry !== 0 || i < length) && it1 !== -1;
it1 -= 1, i += 1
) {
carry += (256 * b58[it1]) >>> 0;
b58[it1] = carry % BASE >>> 0;
carry = (carry / BASE) >>> 0;
}
if (carry !== 0) {
throw new Error("Non-zero carry");
}
length = i;
pbegin += 1;
}
// Skip leading zeroes in base58 result.
var it2 = size - length;
while (it2 !== size && b58[it2] === 0) {
it2 += 1;
}
// Translate the result into a string.
var str = LEADER.repeat(zeroes);
for (; it2 < size; it2 += 1) {
str += ALPHABET.charAt(b58[it2]);
}
return str;
};
return baseX;
};
})();
(function () {
// Base58Check
// See also:
// - https://en.bitcoin.it/wiki/Base58Check_encoding
// - https://appdevtools.com/base58-encoder-decoder
// - https://dashcore.readme.io/docs/core-ref-transactions-address-conversion
// - https://docs.dash.org/en/stable/developers/testnet.html
/** @type {Base58CheckCreate} */
Base58Check.create = function (opts) {
let dictionary = opts?.dictionary || BASE58;
// See https://github.com/dashhive/dashkeys.js/blob/1f0f4e0d0aabf9e68d94925d660f00666f502391/dashkeys.js#L38
let privateKeyVersion = opts?.privateKeyVersion || DASH_PRIV_KEY;
let pubKeyHashVersion = opts?.pubKeyHashVersion || DASH_PKH;
// From https://bitcoin.stackexchange.com/questions/38878/how-does-the-bip32-version-bytes-convert-to-base58
let xprvVersion = opts?.xprvVersion || XPRV; // base58-encoded "xprv..."
let xpubVersion = opts?.xpubVersion || XPUB; // base58-encoded "xpub..."
let bs58 = BaseX.create(dictionary);
let b58c = {};
/** @type {Base58CheckChecksum} */
b58c.checksum = async function (parts) {
b58c._setVersion(parts);
//@ts-ignore
parts.compressed = true; // parts.compressed ?? true;
//@ts-ignore
let key = parts.pubKeyHash || parts.privateKey;
let compression = "";
//@ts-ignore
if (parts.compressed && 64 === key.length) {
compression = "01";
}
let hex = `${parts.version}${key}${compression}`;
let check = await b58c._checksumHexRaw(hex);
return check;
};
/**
* @private
* @param {String} hex
*/
b58c._checksumHexRaw = async function (hex) {
let buf = Utils.hexToBytes(hex);
let hash1 = await Utils.sha256sum(buf);
let hash2 = await Utils.sha256sum(hash1);
let last4 = hash2.slice(0, 4);
let check = Utils.bytesToHex(last4);
return check;
};
/**
* @private
* @param {Base58CheckEncodeParts} parts
*/
b58c._setVersion = function (parts) {
//@ts-ignore
if (parts.pubKeyHash) {
//@ts-ignore
if (parts.privateKey) {
throw new Error(
`[@dashincubator/base58check] either 'privateKey' or 'pubKeyHash' must exist, but not both`,
);
}
}
if (!parts.version) {
//@ts-ignore
if (parts.privateKey) {
parts.version = privateKeyVersion;
}
//@ts-ignore
else if (parts.pubKeyHash) {
parts.version = pubKeyHashVersion;
}
return;
}
//@ts-ignore
if (parts.privateKey) {
if (parts.version === pubKeyHashVersion) {
throw new Error(
`[@dashincubator/base58check] '${parts.version}' is a public version, but the given key is private`,
);
}
return;
}
//@ts-ignore
if (parts.pubKeyHash) {
if (parts.version === privateKeyVersion) {
throw new Error(
`[@dashincubator/base58check] '${parts.version}' is a private version, but the given key is a pubKeyHash`,
);
}
}
};
/** @type {Base58CheckVerify} */
b58c.verify = async function (b58Addr, opts) {
let bytes = bs58.decode(b58Addr);
let hex = Utils.bytesToHex(bytes);
return await b58c.verifyHex(hex, opts);
};
/** @type {Base58CheckVerifyHex} */
b58c.verifyHex = async function (base58check, opts) {
let parts = b58c.decodeHex(base58check);
let check = await b58c.checksum(parts);
let valid = parts.check === check;
if (!valid) {
if (false !== opts?.verify) {
throw new Error(`expected '${parts.check}', but got '${check}'`);
}
parts.valid = valid;
}
return parts;
};
/** @type {Base58CheckDecode} */
b58c.decode = function (b58Addr) {
let bytes = bs58.decode(b58Addr);
let hex = Utils.bytesToHex(bytes);
return b58c.decodeHex(hex);
};
/** @type {Base58CheckDecodeHex} */
b58c.decodeHex = function (addr) {
let version = addr.slice(0, privateKeyVersion.length);
let versions = [pubKeyHashVersion, privateKeyVersion];
let xversions = [xpubVersion, xprvVersion];
let isXKey = false;
if (!versions.includes(version)) {
let xversion = addr.slice(0, xprvVersion.length);
isXKey = xversions.includes(xversion);
if (!isXKey) {
// TODO xkeys
throw new Error(
`[@dashincubator/base58check] expected pubKeyHash (or privateKey) to start with 0x${pubKeyHashVersion} (or 0x${privateKeyVersion}), not '0x${version}'`,
);
}
version = xversion;
}
// Public Key Hash: 1 + 20 + 4 // 50 hex
// Private Key: 1 + 32 + 1 + 4 // 74 or 76 hex
if (![50, 74, 76].includes(addr.length)) {
if (!isXKey) {
throw new Error(
`pubKeyHash (or privateKey) isn't as long as expected (should be 50, 74, or 76 hex chars, not ${addr.length})`,
);
}
}
let rawAddr = addr.slice(version.length, -8);
if (50 === addr.length) {
return {
version: version,
pubKeyHash: rawAddr,
check: addr.slice(-8),
};
}
if (isXKey) {
if (version === xprvVersion) {
return {
version: version,
xprv: rawAddr,
check: addr.slice(-8),
};
}
return {
version: version,
xpub: rawAddr,
check: addr.slice(-8),
};
}
return {
version: version,
privateKey: rawAddr.slice(0, 64),
compressed: true, // "01" === rawAddr.slice(64),
check: addr.slice(-8),
};
};
/** @type {Base58CheckEncode} */
b58c.encode = async function (parts) {
//@ts-ignore
if (parts.xprv) {
let version = parts.version || xprvVersion;
//@ts-ignore
return await b58c._encodeXKey(`${version}${parts.xprv}`);
}
//@ts-ignore
if (parts.xpub) {
let version = parts.version || xpubVersion;
//@ts-ignore
return await b58c._encodeXKey(`${version}${parts.xpub}`);
}
let hex = await b58c.encodeHex(parts);
let bytes = Utils.hexToBytes(hex);
return bs58.encode(bytes);
};
/** @type {Base58CheckEncodeHex} */
b58c.encodeHex = async function (parts) {
//@ts-ignore
if (parts.pubKeyHash) {
return await b58c._encodePubKeyHashHex(parts);
}
//@ts-ignore
if (parts.privateKey) {
return await b58c._encodePrivateKeyHex(parts);
}
throw new Error(
`[@dashincubator/base58check] either 'privateKey' or 'pubKeyHash' must exist to encode`,
);
};
/**
* @private
* @param {String} versionAndKeyHex
*/
b58c._encodeXKey = async function (versionAndKeyHex) {
let checkHex = await b58c._checksumHexRaw(versionAndKeyHex);
let bytes = Utils.hexToBytes(`${versionAndKeyHex}${checkHex}`);
return bs58.encode(bytes);
};
/**
* @private
* @param {Base58CheckEncodeParts} parts
*/
b58c._encodePrivateKeyHex = async function (parts) {
parts.compressed = true; // parts.compressed ?? true;
//@ts-ignore
let key = parts.privateKey;
if (66 === key.length && "01" === key.slice(-2)) {
//key.slice(0, 64);
parts.compressed = true;
} else if (64 === key.length && parts.compressed) {
key += "01";
} else {
throw new Error(
`[@dashincubator/dashkeys/base58check] ${key.length} is not a valid length for a private key - it should be 32 bytes (64 hex chars), or 33 bytes with compressed marker byte`,
);
}
b58c._setVersion(parts);
// after version and compression are set
let check = await b58c.checksum(parts);
return `${parts.version}${key}${check}`;
};
/**
* @private
* @param {Base58CheckEncodeParts} parts
*/
b58c._encodePubKeyHashHex = async function (parts) {
//@ts-ignore
let key = parts.pubKeyHash;
if (40 !== key.length) {
throw new Error(
`[@dashincubator/base58check] ${key.length} is not a valid pub key hash length, should be 20 bytes (40 hex chars)`,
);
}
b58c._setVersion(parts);
// after version is set
let check = await b58c.checksum(parts);
return `${parts.version}${key}${check}`;
};
return b58c;
};
})();
(function () {
// RIPEMD160
const ARRAY16 = new Array(16);
const zl = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6,
15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6,
13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0,
5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13,
];
const zr = [
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13,
5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2,
10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12,
15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11,
];
const sl = [
11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11,
9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8,
13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5,
12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6,
];
const sr = [
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12,
8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13,
5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15,
8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11,
];
const hl = [0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e];
const hr = [0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000];
const blockSize = 64;
class _RIPEMD160 {
constructor() {
// state
/** @private */
this._a = 0x67452301;
/** @private */
this._b = 0xefcdab89;
/** @private */
this._c = 0x98badcfe;
/** @private */
this._d = 0x10325476;
/** @private */
this._e = 0xc3d2e1f0;
/** @private */
this._block = new Uint8Array(blockSize);
/** @private */
this._blockSize = blockSize;
/** @private */
this._blockOffset = 0;
/** @private */
this._length = [0, 0, 0, 0];
/** @private */
this._finalized = false;
}
/** @type {RIPEMD160Update} */
update(data) {
if (this._finalized) {
throw new Error("Digest already called");
}
if (!(data instanceof Uint8Array)) {
throw new Error("update() requires a Uint8Array");
}
// consume data
const block = this._block;
let offset = 0;
while (this._blockOffset + data.length - offset >= this._blockSize) {
for (let i = this._blockOffset; i < this._blockSize; ) {
block[i++] = data[offset++];
}
this._update();
this._blockOffset = 0;
}
while (offset < data.length) {
block[this._blockOffset++] = data[offset++];
}
// update length
for (let j = 0, carry = data.length * 8; carry > 0; ++j) {
this._length[j] += carry;
carry = (this._length[j] / 0x0100000000) | 0;
if (carry > 0) {
this._length[j] -= 0x0100000000 * carry;
}
}
return this;
}
/** @private */
_update() {
const words = ARRAY16;
const dv = new DataView(
this._block.buffer,
this._block.byteOffset,
blockSize,
);
for (let j = 0; j < 16; ++j) {
words[j] = dv.getInt32(j * 4, true);
}
let al = this._a | 0;
let bl = this._b | 0;
let cl = this._c | 0;
let dl = this._d | 0;
let el = this._e | 0;
let ar = this._a | 0;
let br = this._b | 0;
let cr = this._c | 0;
let dr = this._d | 0;
let er = this._e | 0;
// computation
for (let i = 0; i < 80; i += 1) {
let tl;
let tr;
if (i < 16) {
tl = fn1(al, bl, cl, dl, el, words[zl[i]], hl[0], sl[i]);
tr = fn5(ar, br, cr, dr, er, words[zr[i]], hr[0], sr[i]);
} else if (i < 32) {
tl = fn2(al, bl, cl, dl, el, words[zl[i]], hl[1], sl[i]);
tr = fn4(ar, br, cr, dr, er, words[zr[i]], hr[1], sr[i]);
} else if (i < 48) {
tl = fn3(al, bl, cl, dl, el, words[zl[i]], hl[2], sl[i]);
tr = fn3(ar, br, cr, dr, er, words[zr[i]], hr[2], sr[i]);
} else if (i < 64) {
tl = fn4(al, bl, cl, dl, el, words[zl[i]], hl[3], sl[i]);
tr = fn2(ar, br, cr, dr, er, words[zr[i]], hr[3], sr[i]);
} else {
// if (i<80) {
tl = fn5(al, bl, cl, dl, el, words[zl[i]], hl[4], sl[i]);
tr = fn1(ar, br, cr, dr, er, words[zr[i]], hr[4], sr[i]);
}
al = el;
el = dl;
dl = rotl(cl, 10);
cl = bl;
bl = tl;
ar = er;
er = dr;
dr = rotl(cr, 10);
cr = br;
br = tr;
}
// update state
const t = (this._b + cl + dr) | 0;
this._b = (this._c + dl + er) | 0;
this._c = (this._d + el + ar) | 0;
this._d = (this._e + al + br) | 0;
this._e = (this._a + bl + cr) | 0;
this._a = t;
}
/** @type {RIPEMD160Digest} */
digest() {
if (this._finalized) {
throw new Error("Digest already called");
}
this._finalized = true;
const dig = this._digest();
return dig;
}
/**
* @returns {Uint8Array}
*/
_digest() {
// create padding and handle blocks
this._block[this._blockOffset++] = 0x80;
if (this._blockOffset > 56) {
for (let i = this._blockOffset; i < 64; i++) {
this._block[i] = 0;
}
this._update();
this._blockOffset = 0;
}
for (let i = this._blockOffset; i < 56; i++) {
this._block[i] = 0;
}
let dv = new DataView(
this._block.buffer,
this._block.byteOffset,
blockSize,
);
dv.setUint32(56, this._length[0], true);
dv.setUint32(60, this._length[1], true);
this._update();
// produce result
const buffer = new Uint8Array(20);
dv = new DataView(buffer.buffer, buffer.byteOffset, 20);
dv.setInt32(0, this._a, true);
dv.setInt32(4, this._b, true);
dv.setInt32(8, this._c, true);
dv.setInt32(12, this._d, true);
dv.setInt32(16, this._e, true);
return buffer;
}
}
/** @type {RIPEMD160Create} */
RIPEMD160.create = function () {
return new _RIPEMD160();
};
/** @type {RIPEMD160Hash} */
RIPEMD160.hash = function (bytes) {
let hasher = new _RIPEMD160();
hasher.update(bytes);
return hasher.digest();
};
/**
* @param {number} x
* @param {number} n
* @returns {number}
*/
function rotl(x, n) {
return (x << n) | (x >>> (32 - n));
}
/**
* @param {number} a
* @param {number} b
* @param {number} c
* @param {number} d
* @param {number} e
* @param {number} m
* @param {number} k
* @param {number} s
* @returns {number}
*/
function fn1(a, b, c, d, e, m, k, s) {
return (rotl((a + (b ^ c ^ d) + m + k) | 0, s) + e) | 0;
}
/**
* @param {number} a
* @param {number} b
* @param {number} c
* @param {number} d
* @param {number} e
* @param {number} m
* @param {number} k
* @param {number} s
* @returns {number}
*/
function fn2(a, b, c, d, e, m, k, s) {
return (rotl((a + ((b & c) | (~b & d)) + m + k) | 0, s) + e) | 0;
}
/**
* @param {number} a
* @param {number} b
* @param {number} c
* @param {number} d
* @param {number} e
* @param {number} m
* @param {number} k
* @param {number} s
* @returns
*/
function fn3(a, b, c, d, e, m, k, s) {
return (rotl((a + ((b | ~c) ^ d) + m + k) | 0, s) + e) | 0;
}
/**
* @param {number} a
* @param {number} b
* @param {number} c
* @param {number} d
* @param {number} e
* @param {number} m
* @param {number} k
* @param {number} s
* @returns {number}
*/
function fn4(a, b, c, d, e, m, k, s) {
return (rotl((a + ((b & d) | (c & ~d)) + m + k) | 0, s) + e) | 0;
}
/**
* @param {number} a
* @param {number} b
* @param {number} c
* @param {number} d
* @param {number} e
* @param {number} m
* @param {number} k
* @param {number} s
* @returns {number}
*/
function fn5(a, b, c, d, e, m, k, s) {
return (rotl((a + (b ^ (c | ~d)) + m + k) | 0, s) + e) | 0;
}
})();
let dash58check = Base58Check.create();
//@ts-ignore
let Secp256k1 = exports.nobleSecp256k1 || require("@dashincubator/secp256k1");
_DashKeys._dash58check = dash58check;
/**
* Gets crypto-random bytes that may or may not be a valid private key
* (and that's okay - expected even)
* @param {Number} len
* @returns {Uint8Array}
*/
//@ts-ignore
Secp256k1.utils.randomBytes = function (len) {
let buf = new Uint8Array(len);
Crypto.getRandomValues(buf);
return buf;
/** @type {AddressToPubKeyHash} */
_DashKeys.addrToPkh = async function (address) {
let addrParts = await _DashKeys.decode(address);
let shaRipeBytes = Utils.hexToBytes(addrParts.pubKeyHash);
return shaRipeBytes;
};
// https://dashcore.readme.io/docs/core-ref-transactions-address-conversion
// https://docs.dash.org/en/stable/developers/testnet.html
// "48" for mainnet, "8c" for testnet, '00' for bitcoin
//DashKeys.pubKeyHashVersion = "4c";
// TODO type
/** @type {Decode} */
_DashKeys.decode = async function (keyB58c, opts) {
let parts = await dash58check.decode(keyB58c);
let check = await dash58check.checksum(parts);
let valid = parts.check === check;
if (!valid) {
if (false !== opts.validate) {
// to throw the inner error
await dash58check.verify(keyB58c);
}
}
parts.valid = valid;
// "cc" for mainnet, "ef" for testnet, '80' for bitcoin
//DashKeys.privateKeyVersion = "cc";
switch (parts.version) {
case DASH_PKH:
/* fallsthrough */
case DASH_PKH_TESTNET:
parts.type = "pkh";
break;
case DASH_PRIV_KEY:
/* fallsthrough */
case DASH_PRIV_KEY_TESTNET:
parts.type = "private";
break;
case XPRV:
/* fallsthrough */
case TPRV:
parts.type = "xprv";
break;
case XPUB:
/* fallsthrough */
case TPUB:
parts.type = "xpub";
break;
default:
throw new Error(`unknown version ${parts.version}`);
}
// https://dashcore.readme.io/docs/core-ref-transactions-address-conversion
// https://docs.dash.org/en/stable/developers/testnet.html
let b58c = Base58Check.create();
return parts;
};
/**
* @param {Object} [opts]
* @param {String} [opts.version] - '8c' for testnet addrs, 'ef' for testnet wifs,
* @returns {Promise<String>}
*/
DashKeys.generate = async function (opts) {
let privKey = Secp256k1.utils.randomPrivateKey();
// TODO parity with decode
/** @type {EncodeKeyUint8Array} */
_DashKeys.encodeKey = async function (keyBytes, opts) {
if (20 === keyBytes.length) {
return await _DashKeys._encodePkh(keyBytes, opts);
}
let wif = await DashKeys.privateKeyToWif(privKey, opts);
return wif;
if (32 === keyBytes.length) {
return await _DashKeys._encodePrivKey(keyBytes, opts);
}
if (78 === keyBytes.length) {
return await _DashKeys._encodeXKey(keyBytes, opts);
}
throw new Error(
"key bytes length must be 20 (PubKeyHash), 32 (PrivateKey), or 78 (Extended Key)",
);
};
/**
* @param {Uint8Array} privKey
* @param {Object} [opts]
* @param {String} [opts.version] - '8c' for testnet addrs, 'ef' for testnet wifs,
* @returns {Promise<String>}
*/
DashKeys.privateKeyToWif = async function (privKey, opts) {
let privKeyHex = DashKeys._uint8ArrayToHex(privKey);
let decoded = {
version: opts?.version,
privateKey: privKeyHex,
};
/** @type {EncodeKeyUint8Array} */
_DashKeys._encodePkh = async function (shaRipeBytes, opts) {
let pubKeyHash = Utils.bytesToHex(shaRipeBytes);
let version = opts?.version;
let wif = await b58c.encode(decoded);
switch (version) {
case "mainnet":
version = DASH_PKH;
break;
case "testnet":
version = DASH_PKH_TESTNET;
break;
case DASH_PKH:
// keep as is
break;
case DASH_PKH_TESTNET:
// keep as is
break;
default:
throw new Error(
`Address (PubKey Hash) version must be "mainnet" ("${DASH_PKH}") or "testnet" ("${DASH_PKH_TESTNET}"), not '${version}'`,
);
}
let addr = await dash58check.encode({
pubKeyHash,
version,
});
return addr;
};
/** @type {EncodeKeyUint8Array} */
_DashKeys._encodePrivKey = async function (privBytes, opts) {
let privateKey = Utils.bytesToHex(privBytes);
let version = opts?.version;
switch (version) {
case "mainnet":
version = DASH_PRIV_KEY;
break;
case "testnet":
version = DASH_PRIV_KEY_TESTNET;
break;
case DASH_PRIV_KEY:
// keep as is
break;
case DASH_PRIV_KEY_TESTNET:
// keep as is
break;
default:
throw new Error(
`WIF (Private Key) version must be "mainnet" ("${DASH_PRIV_KEY}") or "testnet" ("${DASH_PRIV_KEY_TESTNET}"), not '${version}'`,
);
}
let wif = await dash58check.encode({
privateKey,
version,
});
return wif;
};
//
// Base58Check / Uint8Array Conversions
//
/** @type {EncodeKeyUint8Array} */
_DashKeys._encodeXKey = async function (xkeyBytes, opts) {
let xkey = Utils.bytesToHex(xkeyBytes);
let version = opts?.version;
/**
* @param {String} wif - private key
* @param {Object} [opts]
* @param {String} [opts.version]
* @returns {Promise<String>}
*/
DashKeys.wifToAddr = async function (wif, opts) {
let privBuf = await DashKeys._wifToPrivateKey(wif);
let xprv;
let xpub;
switch (version) {
case "xprv":
version = XPRV;
xprv = xkey;
break;
case "tprv":
version = TPRV;
xprv = xkey;
break;
case "xpub":
version = XPUB;
xpub = xkey;
break;
case "tpub":
version = TPUB;
xpub = xkey;
break;
default:
throw new Error(
`cannot determine Extended Key (xkey) type from bytes length: please supply 'version' as 'xprv', 'xpub', 'tprv', or 'tpub'`,
);
}
let isCompressed = true;
let pubBuf = Secp256k1.getPublicKey(privBuf, isCompressed);
let pubKeyHash = await DashKeys.publicKeyToPubKeyHash(pubBuf);
let pubKeyHashHex = DashKeys._uint8ArrayToHex(pubKeyHash);
let xkeyB58c = await dash58check.encode({
version,
xprv,
xpub,
});
return xkeyB58c;
};
let addr = await b58c.encode({
version: opts?.version,
pubKeyHash: pubKeyHashHex,
/** @type {PubKeyHashToAddress} */
_DashKeys.pkhToAddr = async function (shaRipeBytes, opts) {
let pubKeyHash = Utils.bytesToHex(shaRipeBytes);
let version = opts?.version;
let addr = await dash58check.encode({
pubKeyHash,
version,
});
return addr;
};
/** @type {PrivateKeyToWif} */
_DashKeys.privKeyToWif = async function (privBytes, opts) {
let privateKey = Utils.bytesToHex(privBytes);
let version = opts?.version;
let wif = await dash58check.encode({
privateKey,
version,
});
return wif;
};
/** @type {PublicKeyToAddress} */
_DashKeys.pubKeyToAddr = async function (pubBytes, opts) {
let shaRipeBytes = await _DashKeys.pubKeyToPkh(pubBytes);
let addr = await _DashKeys.pkhToAddr(shaRipeBytes, opts);
return addr;
};
/**
* @param {String} wif - private key
* @returns {Promise<Uint8Array>}
*/
DashKeys._wifToPrivateKey = async function (wif) {
let b58cWif = b58c.decode(wif);
let privateKey = DashKeys._hexToUint8Array(b58cWif.privateKey);
return privateKey;
/** @type {PublicKeyToPubKeyHash} */
_DashKeys.pubKeyToPkh = async function (pubBytes) {
let shaBytes = await Utils.sha256sum(pubBytes);
let shaRipeBytes = await Utils.ripemd160sum(shaBytes);
return shaRipeBytes;
};
/**
* @param {Uint8Array|Buffer} buf
* @returns {Promise<Uint8Array>} - pubKeyHash buffer (no magic byte or checksum)
*/
DashKeys.publicKeyToPubKeyHash = async function (buf) {
let shaBuf = await sha256sum(buf);
/** @type {WifToAddress} */
_DashKeys.wifToAddr = async function (wif) {
let privBytes = await _DashKeys.wifToPrivKey(wif);
let ripemd = RIPEMD160.create();
ripemd.update(shaBuf);
let hash = ripemd.digest();
let pubBytes = await Utils.toPublicKey(privBytes);
let pubKeyHash = await _DashKeys.pubKeyToPkh(pubBytes);
let pubKeyHashHex = Utils.bytesToHex(pubKeyHash);
return hash;
let addr = await dash58check.encode({
pubKeyHash: pubKeyHashHex,
});
return addr;
};
/**
* JS Buffer to Hex that works for Little-Endian CPUs (ARM, x64, x86, WASM)
* @param {Buffer|Uint8Array} buf
* @returns {String} - hex
* @param {String} wif - Base58Check-encoded Private Key
* @returns {Promise<Uint8Array>} - private key (no magic byte or checksum)
*/
DashKeys._uint8ArrayToHex = function (buf) {
/** @type {Array<String>} */
let hex = [];
_DashKeys.wifToPrivKey = async function (wif) {
let wifParts = await dash58check.decode(wif);
let privBytes = Utils.hexToBytes(wifParts.privateKey);
buf.forEach(function (b) {
let h = b.toString(16);
h = h.padStart(2, "0");
hex.push(h);
});
return hex.join("");
return privBytes;
};
/**
* Hex to JS Buffer that works in browsers and Little-Endian CPUs
* (which is most of the - ARM, x64, x86, WASM, etc)
* @param {String} hex
* @returns {Uint8Array} - JS Buffer (Node and Browsers)
* @callback PrivateKeyToWif
* @param {Uint8Array} privBytes
* @returns {Promise<String>} - wif
*/
DashKeys._hexToUint8Array = function (hex) {
let len = hex.length / 2;
let buf = new Uint8Array(len);
let index = 0;
for (let i = 0; i < hex.length; i += 2) {
let c = hex.slice(i, i + 2);
let b = parseInt(c, 16);
buf[index] = b;
index += 1;
}
_DashKeys.utils = Utils;
return buf;
};
//@ts-ignore
Window.BaseX = _DashKeys.BaseX = BaseX;
//@ts-ignore
Window.Base58 = _DashKeys.Base58 = BaseX;
//@ts-ignore
Window.Base58Check = _DashKeys.Base58Check = Base58Check;
//@ts-ignore
Window.RIPEMD160 = _DashKeys.RIPEMD160 = RIPEMD160;
})(globalThis.window || /** @type {window} */ {}, DashKeys);
if ("object" === typeof module) {
module.exports = DashKeys;
}
if ("undefined" !== typeof module) {
module.exports = DashKeys;
}
})(("undefined" !== typeof module && module.exports) || window);
// Type Aliases
/** @typedef {String} HexString */
// Type Definitions
/**
* @callback AddressToPubKeyHash
* @param {String} addr - Base58Check encoded version + pkh + check
* @returns {Promise<Uint8Array>} - pkh bytes (no version or check, NOT Base58Check)
*/
/**
* @callback Decode
* @param {String} keyB58c - addr, wif, or xkey (xprv, xpub)
* @param {DecodeOpts} opts
* @returns {Promise<Base58CheckParts>}
*/
/**
* @typedef DecodeOpts
* @prop {Boolean} validate - throw if check fails, true by default
*/
/**
* @callback EncodeKeyUint8Array
* @param {Uint8Array} keyBytes - privKey, pkh, or xkey (xprv or xpub) bytes
* @param {EncodeKeyUint8ArrayOpts} opts
* @returns {Promise<String>} - Address or WIF (or Extended Key - xPrv or xPub)
* @throws {Error}
*/
/**
* @typedef EncodeKeyUint8ArrayOpts
* @prop {VERSION} version - needed for xprv and xpub, or testnet
*/
/**
* Developer Convenience function for Generating Non-HD (NON-RECOVERABLE) WIFs
* @callback GenerateWif
* @param {GenerateWifOpts} opts
* @returns {Promise<String>} - JS Bytes Buffer (Uint8Array, Node & Browsers)
*/
/**
* @typedef GenerateWifOpts
* @prop {VERSION_PRIVATE} version - "mainnet" ("cc") by default
*/
/**
* @callback Hasher
* @param {Uint8Array|Buffer} bytes
* @returns {Promise<Uint8Array>} - hash Uint8Array
*/
/**
* Hex to JS Bytes Buffer (Uint8Array)
* @callback HexToUint8Array
* @param {String} hex - hex
* @returns {Uint8Array} - JS Bytes Buffer (Uint8Array, Node & Browsers)
*/
/**
* @callback PrivateKeyToWif
* @param {Uint8Array} privBytes
* @param {PrivateKeyToWifOpts} [opts]
* @returns {Promise<String>}
*/
/**
* @typedef PrivateKeyToWifOpts
* @prop {VERSION_PRIVATE} version - "mainnet" ("cc") by default
*/
/**
* @callback PubKeyHashToAddress
* @param {Uint8Array} shaRipeBytes - PubKey Hash (no magic byte or checksum)
* @param {EncodeKeyUint8ArrayOpts} opts - for version
* @returns {Promise<String>} - Address
*/
/**
* @callback PublicKeyToAddress
* @param {Uint8Array} pubBytes - Public Key Uint8Array
* @param {EncodeKeyUint8ArrayOpts} opts - for coin version
* @returns {Promise<String>} - Address
*/
/**
* @callback PublicKeyToPubKeyHash
* @param {Uint8Array|Buffer} pubBytes - Public Key Uint8Array
* @returns {Promise<Uint8Array>} - pubKeyHash Uint8Array (no magic byte or checksum)
*/
/**
* @callback ToPublicKey
* @param {Uint8Array} privBytes - Private Key Uint8Array
* @returns {Promise<Uint8Array>} - Public Key Uint8Array
*/
/**
* JS Bytes Buffer (Uint8Array) to Hex
* @callback Uint8ArrayToHex
* @param {Uint8Array} bytes
* @returns {String} - hex
*/
/**
* Converts a WIF-encoded PrivateKey to a PubKey Hash
* (of the same coin type, of course)
* @callback WifToAddress
* @param {String} wif - private key
* @returns {Promise<String>} - address
*/

23

package.json
{
"name": "dashkeys",
"version": "0.3.1",
"version": "0.9.0",
"description": "Generate, validate, create, and convert WIFs and PayAddress.",
"main": "index.js",
"bin": {
"dashkeys": "bin/dashkeys.js"
},
"main": "dashkeys.js",
"bin": {},
"files": [
"dashkeys.js",
"index.js",
"*.js",
"lib/"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"doc": "npx jsdoc@3.x --configure ./jsdoc.conf.json --destination ./docs --package ./package.json --readme ./README.md --access all --private --recurse ./lib/",
"bump": "npm version -m \"chore(release): bump to v%s\"",
"fmt": "npx -p prettier@2.x -- prettier -w '**/*.{html,js,md}'",
"lint": "npx -p typescript@4.x -- tsc -p ./jsconfig.json",
"prepublish": "npx -p jswt@1.x -- reexport",
"version": "npm version -m \"chore(release): bump to v%s\""
"test": "echo \"Error: no test specified\" && exit 1"
},

@@ -45,7 +40,5 @@ "repository": {

"homepage": "https://github.com/dashhive/dashkeys.js#readme",
"dependencies": {
"@dashincubator/base58check": "^1.2.0",
"@dashincubator/ripemd160": "^2.3.0",
"@dashincubator/secp256k1": "^1.7.1-0"
"devDependencies": {
"@dashincubator/secp256k1": "^1.7.1-2"
}
}

@@ -1,38 +0,58 @@

# dashkeys.js
# [DashKeys.js][dashkeys-js]
Generate, validate, create, and convert WIFs and PayAddress.
Generate, validate, and convert DASH WIFs and Pay Addresses. \
(Base58Check encoding/decoding for Private Keys and Public Key Hashes)
- CLI
- Node & Bundlers
- Browser
- API
- Fixtures (for developing and testing)
```text
WIF: XCGKuZcKDjNhx8DaNKK4xwMMNzspaoToT6CafJAbBfQTi57buhLK
Address: XrZJJfEKRNobcuwWKTD3bDu8ou7XSWPbc9
```
## CLI
> A fully-functional, production-ready **reference implementation** of Dash
> Keys - suitable for learning DASH specs and protocols, and porting to other
> languages.
Saves a private key to a file with the name of the public key hash (pay addr)
## Table of Contents
**Install**
- 🚀 [Install](#install)
- Terminal (CLI)
- Node & Bundlers
- Browser
- 💪 [Usage](#usage)
- ⚙️ [API](#api)
- 🧰 Developer Resources
- 👩‍🏫 [Glossary of Terms](#glossary)
- Address, Check, Compressed, Private Key,
- PubKey Hash, Public Key, Version, WIF, etc ...
- 🦓 [Fixtures](#fixtures) (for testing)
- The Canonical Dash "Zoomonic"
- Anatomy of Addrs & WIFs
- Troubleshooting Uncompressed Keys
- Implementation Details
- 📄 [License](#license)
```sh
npm install --location=global dashkeys
```
[base58check-js]: https://github.com/dashhive/base58check.js
[dashkeys-js]: https://github.com/dashhive/dashkeys.js
[dashhd-js]: https://github.com/dashhive/dashhd.js
[dashwallet-js]: https://github.com/dashhive/dashwallet.js
[dash-hd-cli]: https://github.com/dashhive/dashhd-cli.js
[dash-keys-cli]: https://github.com/dashhive/dashkeys-cli.js
[dash-wallet-cli]: https://github.com/dashhive/dashwallet-cli.js
**Usage**
## Install
Works in Command Line, Node, Bun, Bundlers, and Browsers
### Terminal
```sh
dashkeys generate
npm install --location=global dashkeys-cli
dashkeys help
```
```txt
Saved new private key to './Xjn9fksLacciynroVhMLKGXMqMJtzJNLvQ.wif'
```
See DashKey's CLI README at
[github.com/dashhive/dashkeys-cli.js][dash-keys-cli].
The name of the file is the Pay Addr (public key hash) and the contents are the
WIF (private key).
## Node & Bundlers
The leading `X` for each is because they are base58check-encoded.
## Node
**Install**

@@ -42,27 +62,11 @@

npm install --save dashkeys
npm install --save @dashincubator/secp256k1@1
```
**Usage**
```js
let DashKeys = require("dashkeys");
let wif = await DashKeys.generate();
// ex: "XEez2HcUhEomZoxzgH7H3LxnRAkqF4kRCVE8mW9q4YSUV4yuADec"
let addr = await DashKeys.wifToAddr(wif);
// ex: "Xjn9fksLacciynroVhMLKGXMqMJtzJNLvQ"
let toHex = DashKeys.utils.bytesToHex;
let toBytes = DashKeys.utils.hexToBytes;
```
You can use `DashKeys.privateKeyToWif(privateKey)` to generate non-random WIFs:
```js
let privateKey = Buffer.from(
"647f06cbd6569feaa4b6a1e400284057a95d27f4206ce38300ae88d44418160d",
"hex",
);
let wif = await DashKeys.privateKeyToWif(privateKey);
let addr = await DashKeys.wifToAddr(wif);
```
## Browser

@@ -73,10 +77,6 @@

```html
<script src="https://unpkg.com/@dashincubator/base58check/base58check.js"></script>
<script src="https://unpkg.com/@dashincubator/secp256k1/secp256k1.js"></script>
<script src="https://unpkg.com/@dashincubator/ripemd160/ripemd160.js"></script>
<script src="https://unpkg.com/dashkeys/dashkeys.js"></script>
```
**Usage**
```js

@@ -87,8 +87,6 @@ async function main() {

let DashKeys = window.DashKeys;
let toHex = DashKeys.utils.bytesToHex;
let toBytes = DashKeys.utils.hexToBytes;
let wif = await DashKeys.generate();
// ex: "XEez2HcUhEomZoxzgH7H3LxnRAkqF4kRCVE8mW9q4YSUV4yuADec"
let addr = await DashKeys.wifToAddr(wif);
// ex: "Xjn9fksLacciynroVhMLKGXMqMJtzJNLvQ"
// ...
}

@@ -102,44 +100,524 @@

## API
## Usage
DashKeys has a small API wrapping Secp256k1 and Base58Check.
```js
let wif = await DashKeys.generateWifNonHd();
// ex: "XCGKuZcKDjNhx8DaNKK4xwMMNzspaoToT6CafJAbBfQTi57buhLK"
Most of what you need to do can be done with those directly.
let addr = await DashKeys.wifToAddr(wif);
// ex: "XrZJJfEKRNobcuwWKTD3bDu8ou7XSWPbc9"
```
You can use `DashKeys.privateKeyToWif(privateKey)` to encode Private Keys to
WIFs:
```js
let wif = await DashKeys.generate();
let privBuf = toBytes(
"1d2a6b22fcb5a29a5357eaf27b1444c623e5e580b66ac5f1109e2778a0ffb950",
);
let wif = await DashKeys.privateKeyToWif(privateKey);
let addr = await DashKeys.wifToAddr(wif);
```
let pkh = await DashKeys.publicKeyToPubKeyHash(publicKey);
let wif = await DashKeys.privateKeyToWif(privateKey);
## API
Dash Keys doesn't do anything that other Base58Check libraries don't do.
The purpose of this rewrite has been to provide, a simpler, **lightweight**,
more streamlined production-ready **reference implementation** that takes
advantage of modern, cross-platform _JS-native APIs_, such as WebCrypto.
**However**, it does (we think) do a better job at exposing a functions for how
the Base58Check codec is **used in practice** (rather than _everything_ it can
theoretically be used for).
### Common Conversions
```js
// Bi-Directional Conversions
await DashKeys.addrToPkh(address); // PubKey Hash Uint8Array (ShaRipeBytes)
await DashKeys.pkhToAddr(hashBytes, { version }); // Address (Base58Check-encoded)
await DashKeys.pubKeyToAddr(pubBytes); // Address (Base58Check-encoded)
await DashKeys.privKeyToWif(privBytes, { version }); // WIF (Base58Check-encoded)
await DashKeys.wifToPrivKey(wif); // Private Key Uint8Array
// One-Way Conversions
await DashKeys.wifToAddr(wif); // Address (Base58Check-encoded)
await DashKeys.pubKeyToPkh(pubBytes); // shaRipeBytes Uint8Array
```
## Helpful Helper Functions
**Note**: these all output either Base58Check Strings, or Byte Arrays
(Uint8Array).
These aren't included as part of the DashKeys API because they're things that
[@dashincubator/base58check](https://github.com/dashhive/base58check.js) already
does, 95% or so.
### Common Encode / Decode Options
```js
await addrToPubKeyHash(addr); // buffer
await pubKeyHashToAddr(pubKeyHash); // Pay Addr
{
// (default) throw if check(sum) fails
validate: true,
await wifToPrivateKey(wif); // buffer
await privateKeyToWif(privKey); // WIF
// which encoding to use
// (not all are valid all the time - it depends on the use)
version: "mainnet|testnet|private|pkh|xprv|xpub|cc|4c|ef|8c",
}
```
await decode(addrOrWif); // { version, pubKeyHash, privateKey, check, valid }
await encode(pkhOrPkBuf); // Pay Addr or WIF
### Debugging Encoder / Decoder
uint8ArrayToHex(buf); // hex
hexToUint8Array(hex); // buffer
```js
// Base58Check Codec for all of Private Key and PubKey Hash (and X Keys)
await DashKeys.decode(b58cString, { validate }); // { version, type, check, etc }
await DashKeys.encodeKey(keyBytes, { version }); // Base58Check-encoded key
```
However, you are welcome, of course, to copy and paste these to your heart's
content. 😉
**Decode Output**:
```json5
{
check: "<hex>",
compressed: true,
type: "private|pkh|xprv|xpub",
version: "cc|4c|ef|8c",
valid: true, // check matches
// possible key types
privateKey: "<hex>",
pubKeyHash: "<hex>",
xprv: "<hex>",
xpub: "<hex>",
}
```
**note**: `compressed` only applies to Private Keys and is _always_ `true`. \
Remains in for compatibility, but not used.
### Helpful Helper Utils
```js
// Byte Utils (NOT async)
let toHex = DashKeys.utils.bytesToHex;
toHex(uint8Array); // hex String
let toBytes = DashKeys.utils.hexToBytes;
toBytes(hexString); // bytes Uint8Array
// Hash Utils
await DashKeys.utils.ripemd160sum(bytes); // hash bytes Uint8Array
await DashKeys.utils.sha256sum(bytes); // hash bytes Uint8Array
```
### Swappable Secp256k1 Utils
We felt it was important to **not strictly depend** on _our_ chosen
**secp256k1** implementation. \
(that's why you have to manually install it as a dependency yourself)
Use these functions **as-is**, or overwrite them with your own implementation.
```js
// Key Utils (over
await DashKeys.utils.generateWifNonHd({ version }); // WIF string (non-hd, dev tool)
await DashKeys.utils.toPublicKey(privBytes); // Public Key Bytes
```
**Example Overwrite**
You **DO NOT** need to do this, but you _may_ if you wish:
```js
let Secp256k1 = require("@noble/secp256k1");
DashKeys.utils.generateWifNonHd = async function (opts) {
let privBytes = Secp256k1.utils.randomPrivateKey();
let privateKey = toHex(privBytes);
let version = opts.version ?? "cc";
let wif = await DashKeys.encode(privBytes, { version });
return wif;
};
DashKeys.utils.toPublicKey = async function (privBytes) {
let isCompressed = true;
let pubBytes = Secp256k1.getPublicKey(privBytes, isCompressed);
return pubBytes;
};
```
## Glossary
Here are bunches of terms by their canonical name, as well as a terse
description.
- [Address](#address)
- [Check](#check)
- [Base X](#base-x)
- [Base58](#base58)
- [Base58Check](#base58check)
- [Compressed Byte](#compressed-byte)
- [HD Key](#hd-key)
- [Private Key](#private-key)
- [PubKey Hash](#pubkey-hash)
- [Public Key](#public-key)
- [RIPEMD160](#ripemd160)
- [Version](#version)
- [WIF](#wif)
- [Zoomonic](#zoomonic)
### Address
Also: Payment Address, Pay Addr, Addr
A Base58Check-encoded PubKey Hash. \
(can **NOT** be reversed into the Public Key) \
The encoding is like this:
- Coin Version Public byte(s), which is 4c for DASH
- Public Key Hash (20 bytes)
- Check(sum) is 4 bytes of SHA-256(concat(coin, comp, pkh))
- Base58Check is Base85(concat(coin, comp, pkh, check))
```text
Version: cc
PubKey Hash: ae14c8728915b492d9d77813bd8fddd91ce70948
Check: ce08541e
Decoded: ccae14c8728915b492d9d77813bd8fddd91ce70948ce08541e
Encoded: XrZJJfEKRNobcuwWKTD3bDu8ou7XSWPbc9
```
### Base X
A bespoke algorithm for arbitrary-width bit encoding. \
Similar to (but **not _at all_ compatible** with) Base64. \
Bit-width is based on the given alphabet's number of characters.
### Base58
A specific 58-character _Base X_ alphabet. \
The same is used for DASH as most cryptocurrencies.
```text
123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
```
Chosen to eliminate confusion between similar characters. \
(`0` and `O`, `1` and `l` and `I`, etc)
### Base58Check
A Base58 encoding schema with prefixes and suffixes. \
`verisonBytes` is added as a prefix (before encoding). \
Some _metadata_ may come before the data. \
`checkBytes` are added as a suffix (before encoding). \
```js
Base58(`${versionBytes}${metaBytes}${dataBytes}${checkBytes}`);
```
See also [Address](#address), [Check](#check) and [WIF](#wif)
### Check
Also: Base58 Checksum, Base58 Hash, Base58 SHA-256
The _last_ 4 bytes of a decoded WIF or Addr. \
These are the _first_ 4 bytes of the SHA-256 Hash of the same.
See [Address](#address) and [WIF](#wif).
### Compressed Byte
Also: Compression Flag, Recovery Bit, Y is Even / Odd Byte, Quadrant
A private key always starts with `0x01`, the compression flag. \
This indicates that Pub Key Hashes must not include the Y value.
See also: [Public Key](#public-key).
### HD Key
Also: HD Wallet WIF
An HD Key is a Private Key or WIF generated from an HD Wallet. \
These are recoverable from a Passphrase "Mnemonic". \
(HD means _Hierarchical-Deterministic_, as in "generated from seed")
HD keys are almost always preferrable over non-HD keys.
See [Dash HD][dashhd-js], [Dash Wallet][dashwallet-js].
### Private Key
Also: PrivKey
Any 32 random bytes (256-bits) that can produce a valid Public Key. \
The public key is produced by creating a point on a known curve.
In essence:
```js
let privBuf = genRandom(32);
let pirvHex = toHex(privBuf);
let privNum = BigInt(`0x${privHex}`);
// magic secp256k1 curve values
let curveN =
0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n;
let Gx =
55066263022277343669578718895168534326250603453777594175500187360389116729240n;
let Gy =
32670510020758816978083085130507043184471273380659243275938904335757337482424n;
let windowSize = 8;
let isWithinCurveOrder = 0n < privNum && privNum < curveN;
if (!isWithinCurveOrder) {
throw new Error("not in curve order");
}
let BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, 1n);
let jPoint = BASE.multiply(privNum, { Gx, Gy, windowSize }); // fancy math
let pubPoint = jPoint.toAffine(); // fancy math
let isOdd = pubPoint.y % 2n;
let prefix = "02";
if (isOdd) {
prefix = "03";
}
let x = pubPoint.x.toString(16).padStart(32, "0");
let pubHex = `${prefix}${x}`;
```
See <https://github.com/dashhive/secp256k1.js>.
### PubKey Hash
Also: Public Key Hash, PKH, PubKeyHash
The public key is hashed with SHA-256. \
That result is hashed with RIPEMD-160.
```text
RIPEMD160(SHA256(PublicKey))
```
### Public Key
Also: PubKey
An 32-byte `X` value, prefixed with a byte describing the `Y` value. \
The indicator is `0x02`, if `Y` is ever, or `0x03` if `Y` is odd. \
In essence:
```js
let expectOdd = 0x03 === pubKey[0];
let xBuf = pubKey.subarray(1);
let xHex = toHex(xBuf);
let x = BigInt(xHex);
// magic secp256k1 curve values
let a = 0n;
let b = 7n;
let P = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
function mod(a, b = P) {
let result = a % b;
if (result >= 0n) {
return result;
}
return b + result;
}
let x2 = mod(x * x);
let x3 = mod(x2 * x);
let y2 = mod(x3 + a * x + b);
let y = curveSqrtMod(y2); // very complicated
let isYOdd = (y & 1n) === 1n;
if (expectOdd && !isYOdd) {
y = mod(-y);
}
let pubPoint = { x: x, y: y };
```
See <https://github.com/dashhive/secp256k1.js>.
### RIPEMD160
An old, deprecated hash 20-byte algorithm - similar to MD5. \
We're stuck with it for the foreseeable future. Oh, well.
### Version
Also: Base58Check Version, Coin Version, Privacy Byte
`0xcc` is used for DASH mainnet WIFs (Private Key). \
`0x4c` is the prefix for Payment Addresses (PubKey Hash) . \
These bytes Base58Encode to `X`, (for mystery, i.e. "DarkCoin").
`0xef` (Priv) and `0x8c` (PKH) are used for DASH testnet. \
These Base58Encode to `Y`.
For use with HD tools, this Base58Check codec also supports: \
`0x0488ade4`, which Base58-encodes to the `xprv` prefix. \
`0x0488b21e`, which Base58-encodes to the `xpub` prefix. \
`0x04358394` and `0x043587cf`, which encode to `tprv` and `tpub`.
See [Dash HD][dashhd-js] for more info about Extended Private Keys (`xprv`,
`xpriv`) and Extended Public Keys (`xpub`).
### WIF
Also: Wallet Import Format, Paper Wallet, Swipe Key, Private Key QR
A Base58Check-encoded Private Key. \
(**CAN** be reversed into the Private Key) \
The encoding is like this:
- Coin Version Private byte(s), which is cc for DASH
- Compression byte (always 0x01)
- Private Key (32 bytes)
- Checksum is 4 bytes of SHA-256(concat(coin, compression, pubkey))
- Base58Check is Base85(concat(coin, compression, pubkey, checksum))
```text
Version: cc
Comp Byte: 01 (always)
Private Key: 1d2a6b22fcb5a29a5357eaf27b1444c623e5e580b66ac5f1109e2778a0ffb950
Checksum: ec533f80
Decoded: cc011d2a6b22fcb5a29a5357eaf27b1444c623e5e580b66ac5f1109e2778a0ffb950ec533f80
Encoded: XCGKuZcKDjNhx8DaNKK4xwMMNzspaoToT6CafJAbBfQTi57buhLK
```
### Zoomonic
The HD Wallet used for all testing fixtures in this ecosystem of code. \
(chosen from the original Trezor / BIP-39 test fixtures)
See [The Canonical Dash "Zoomonic"](#the-canonical-dash-zoomonic).
## Fixtures
For troubleshooting, debugging, etc.
### The Canonical Dash "Zoomonic":
All keys used in this example - and across this ecosystem of DASH tools - are HD
keys derived from the "Zoomonic":
```txt
Passphrase (Mnemonic) : zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong
Secret (Salt Password) : TREZOR
HD Path : m/44'/5'/0'/0/0
WIF : XCGKuZcKDjNhx8DaNKK4xwMMNzspaoToT6CafJAbBfQTi57buhLK
Addr : XrZJJfEKRNobcuwWKTD3bDu8ou7XSWPbc9
```
### Anatomy of Addrs & WIFs
```sh
dashkeys inspect --unsafe ./examples/m44_5_0_0-0.wif
```
```txt
Version: cc
Private Key: 1d2a6b22fcb5a29a5357eaf27b1444c623e5e580b66ac5f1109e2778a0ffb950
Compressed: 01
Pay Addr: XrZJJfEKRNobcuwWKTD3bDu8ou7XSWPbc9
Check: ec533f80
Valid: true
```
**Correct Private Key**
```txt
PrivateKey: cc011d2a6b22fcb5a29a5357eaf27b1444c623e5e580b66ac5f1109e2778a0ffb950
--------
Version: cc
Comp Flag: 01 (Compressed)
Priv Key: 1d2a6b22fcb5a29a5357eaf27b1444c623e5e580b66ac5f1109e2778a0ffb950
--------
WIF: XCGKuZcKDjNhx8DaNKK4xwMMNzspaoToT6CafJAbBfQTi57buhLK
```
**Correct Pub Key Hash**
```txt
PubKey: 0245ddd5edaa25313bb88ee0abd359f6f58ac38ed597d33a981f1799903633d902
--------
Comp Flag: 02 (Quadrant 2)
X: 45ddd5edaa25313bb88ee0abd359f6f58ac38ed597d33a981f1799903633d902
SHA256: 8e5abfc42a6d7529b860ce2b4b8889380db893438dc96430f597ddb455e85fdd
*RMD160: 54408a877b83cb9706373918a430728f72f3d001 (*not used)
PubKeyHash: ae14c8728915b492d9d77813bd8fddd91ce70948
Check: ce08541e
Version: 4c
--------
Pay Address: XrZJJfEKRNobcuwWKTD3bDu8ou7XSWPbc9
```
### Troubleshooting Uncompressed Keys
If you see these values, then you've mistakenly used uncompressed keys.
**Incorrect Private Key** (Uncompressed)
```txt
PrivateKey: cc1d2a6b22fcb5a29a5357eaf27b1444c623e5e580b66ac5f1109e2778a0ffb950
--------
Version: cc
Comp Flag: missing, or 00 (Uncompressed)
Priv Key: 1d2a6b22fcb5a29a5357eaf27b1444c623e5e580b66ac5f1109e2778a0ffb950
--------
WIF: XCGKuZcKDjNhx8DaNKK4xwMMNzspaoToT6CafJAbBfQTi4vf57Ka (00 comp flag)
7qmhzDpsoPHhYXBZ2f8igQeEgRSZXmWdoh9Wq6hgvAcDrD3Arhr (no comp flag)
```
**Incorrect Pub Key Hash** (Uncompressed)
```txt
PubKey (X+Y): 04
45ddd5edaa25313bb88ee0abd359f6f58ac38ed597d33a981f1799903633d902
607c88b97231d7f1419c772a6c55d2ad6a7c478a66fdd28ac88c622383073d12
--------
Comp Flag: 04, or 'false' (uncompressed)
X: 45ddd5edaa25313bb88ee0abd359f6f58ac38ed597d33a981f1799903633d902
Y: 607c88b97231d7f1419c772a6c55d2ad6a7c478a66fdd28ac88c622383073d12
SHA256: 85c03bf3ba5042d2e7a84f0fcc969a7753a91e9c5c299062e1fdf7e0506b5f66
*RMD160: b9d17c4c4fb6307ba78c8d4853ed07bd7e4c9f5a (*not used)
PubKeyHash: 9eee08ab54036069e5aaa15dcb204baa0fae622d
Check: d38b9fd2
Version: 4c
--------
Pay Address: XqBBkSnvWMcLyyRRvH1S4mWH4f2zugr7Cd
```
## Implementation Details
It also serves as a **reference implementation** for porting to **other
platforms** such as modern **mobile** and **desktop** programming languages.
As a reference implementation, it's valuable to **_understand_ that tedium**,
here's a peek behind the curtain:
- _Address_ ↔️ _PubKey Hash_
- _WIF_ ↔️ _Private Key_
- _Private Key_ ➡️ _Public Key_
- _Public Key_ ➡️ _PubKey Hash_
These are _simplified_ version of what's in the actual code: \
(removed error checking, etc, for clarity)
```js
let Base58Check = require("@dashincubator/base58check").Base58Check;
// "dash58check" because we're using the Dash magic version bytes.
let dash58check = Base58Check.create({
privateKeyVersion: "cc", // "ef" for dash testnet, "80" for bitcoin main
pubKeyHashVersion: "4c", // "8c" for dash testnet, "00" for bitcoin main
privateKeyVersion: "cc", // "ef" for dash testnet, "80" for bitcoin main
});

@@ -153,3 +631,3 @@

let b58cAddr = dash58check.decode(addr);
let pubKeyHash = hexToUint8Array(b58cAddr.pubKeyHash);
let pubKeyHash = toBytes(b58cAddr.pubKeyHash);
return pubKeyHash;

@@ -163,3 +641,3 @@ }

async function pubKeyHashToAddr(pubKeyHash) {
let hex = uint8ArrayToHex(pubKeyHash);
let hex = toHex(pubKeyHash);
let addr = await dash58check.encode({ pubkeyHash: hex });

@@ -175,3 +653,3 @@ return addr;

let b58cWif = dash58check.decode(wif);
let privateKey = hexToUint8Array(b58cWif.privateKey);
let privateKey = toBytes(b58cWif.privateKey);
return privateKey;

@@ -185,3 +663,3 @@ }

async function privateKeyToWif(privKey) {
let privateKey = uint8ArrayToHex(privKey);
let privateKey = toHex(privKey);

@@ -201,4 +679,4 @@ let wif = await dash58check.encode({ privateKey: privateKey });

parts.valid = valid;
//parts.privateKeyBuffer = hexToUint8Array(parts.privateKey);
//parts.pubKeyHashBuffer = hexToUint8Array(parts.pubKeyHash);
//parts.privBytes = toBytes(parts.privateKey);
//parts.shaRipeBytes = toBytes(parts.pubKeyHash);

@@ -214,3 +692,3 @@ return parts;

async function encode(buf) {
let hex = uint8ArrayToHex(buf);
let hex = toHex(buf);

@@ -231,105 +709,29 @@ if (32 === buf.length) {

}
/**
* JS Buffer to Hex that works in browsers and Little-Endian
* (which is most of the - ARM, x64, x86, WASM, etc)
* @param {Uint8Array} buf
* @returns {String} - hex
*/
function uint8ArrayToHex(buf) {
/** @type {Array<String>} */
let hex = [];
buf.forEach(function (b) {
let c = b.toString(16).padStart(2, "0");
hex.push(c);
});
return hex.join("");
}
/**
* Hex to JS Buffer that works in browsers and Little-Endian CPUs
* (which is most of the - ARM, x64, x86, WASM, etc)
* @param {String} hex
* @returns {Uint8Array} - JS Buffer (Node and Browsers)
*/
function hexToUint8Array(hex) {
let buf = new Uint8Array(hex.length / 2);
for (let i = 0; i < hex.length; i += 2) {
let c = hex.slice(i, i + 2);
let b = parseInt(c, 16);
let index = i / 2;
buf[index] = b;
}
return buf;
}
```
## Fixtures
# LICENSE
For troubleshooting, debugging, etc:
To keep the dependency tree slim, this includes `BaseX` and `Base58Check`, which
are derivatives of `base58.cpp`, as well as RIPEMD160.
**Correct Values**
These have all been _complete_ for several years. They do not need updates.
- WIF: XEez2HcUhEomZoxzgH7H3LxnRAkqF4kRCVE8mW9q4YSUV4yuADec
- Pay Addr: Xjn9fksLacciynroVhMLKGXMqMJtzJNLvQ
## DashKeys.js
```txt
WIF: XEez2HcUhEomZoxzgH7H3LxnRAkqF4kRCVE8mW9q4YSUV4yuADec (Base58Check)
Copyright (c) 2022-2023 Dash Incubator \
Copyright (c) 2021-2023 AJ ONeal
Private Parts: cc647f06cbd6569feaa4b6a1e400284057a95d27f4206ce38300ae88d44418160d012dc0e59d
--------
Version: cc
PrivKey: 647f06cbd6569feaa4b6a1e400284057a95d27f4206ce38300ae88d44418160d
Compressed: 01
Checksum: 2dc0e59d
MIT License
## BaseX, Base58, Base58Check
Compressed Pub: 0290940e7a082049ccfbf7999260ab9a6d88bcb34d57f6c6075e52dd7395ed7058
--------
Quadrant: 02
PubKey: 90940e7a082049ccfbf7999260ab9a6d88bcb34d57f6c6075e52dd7395ed7058
Sha256: 836eaaeef70089f38cbf878f6987a322260ad661f3c0fcaf9715834b5a5224c7
RipeMD: 63ba19d01e6cf812c01ca6a4041c3c04f2a4dfe9 (Pub Key Hash)
Copyright (c) 2018 base-x contributors \
Copyright (c) 2014-2018 The Bitcoin Core developers
MIT License
Pub Key Hash: 4c63ba19d01e6cf812c01ca6a4041c3c04f2a4dfe99ec9cefd (Hex)
--------
Version: 4c
Hash: 63ba19d01e6cf812c01ca6a4041c3c04f2a4dfe9
Checksum: 9ec9cefd
## RIPEMD160
Copyright (c) 2016 crypto-browserify
Pay Addr: Xjn9fksLacciynroVhMLKGXMqMJtzJNLvQ (Base58Check)
```
**Incorrect Values**
These are the values you get for `{ compressed: false }`:
```txt
Private Parts: cc647f06cbd6569feaa4b6a1e400284057a95d27f4206ce38300ae88d44418160d012dc0e59d
--------
Version: cc
PrivKey: 647f06cbd6569feaa4b6a1e400284057a95d27f4206ce38300ae88d44418160d
Compressed: (MISSING!)
Checksum: (WRONG!)
Uncompressed: 0490940e7a082049ccfbf7999260ab9a6d88bcb34d57f6c6075e52dd7395ed70581480b848f5a1e2fd61dd87a2815d90d2d118a46d666a7a559adab68b00e0dc1e
--------
Quadrant: 04 (WRONG!)
X: 90940e7a082049ccfbf7999260ab9a6d88bcb34d57f6c6075e52dd7395ed7058
Y: 1480b848f5a1e2fd61dd87a2815d90d2d118a46d666a7a559adab68b00e0dc1e
Sha256: e1d11902550f530b33e4321f4f9044a67c3b9c38b6ed98accfaf0571067871d2
RipeMD: 30ad71f52c005b5444f94032dda84466ddaf87a0 (WRONG Pub Key Hash)
Pay Addr: Xf8E3eA1Sh8vC29fxQVbET8cqfCRcmiQeA (WRONG)
4c30ad71f52c005b5444f94032dda84466ddaf87a0dae0ce2f (WRONG)
--------
Version: 4c
Hash: 30ad71f52c005b5444f94032dda84466ddaf87a0 (WRONG)
Checksum: dae0ce2f (WRONG)
```
MIT License

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc