Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ However, production code will look more like this:
RECEIVE, CHANGE
async fromSeed(seedBytes, opts) // depth-0 hdkey (Wallet)
async fromXKey(xprv||xpub, opts) // depth-4 hdkey (XKey)
async toPublic(xKey)
async wipePrivateData(xKey)
async toWif(privBytes, opts)
async toAddr(pubBytes, opts)
async toXPrv(xprvKey, opts)
Expand Down Expand Up @@ -415,6 +417,22 @@ let xkey = await DashHd.fromXKey(xprvOrXPub, options);
}
```

### `toPublic(xkey)`

Creates a copy of the HD Key with `privateKey` set to `null`.

```js
let xpubKey = await DashHd.toPublic(xprvKey);
```

### `wipePrivateData(xkey)`

Performs an in-place secure erase of the private key memory.

```js
await DashHd.wipePrivateData(xprvKey);
```

### `toWif(privBytes, opts)`

Wrapper around `DashKeys.encodeKey(keyBytes, options)` to Base58Check-encode a
Expand Down
76 changes: 76 additions & 0 deletions dashhd.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* @prop {HDFingerprint} _fingerprint
* @prop {HDFromSeed} fromSeed
* @prop {HDFromXKey} fromXKey
* @prop {HDToId} toId
* @prop {HDToIdBytes} toIdBytes
* @prop {HDToAddr} toAddr
* @prop {HDToWif} toWif
* @prop {HDToXPrv} toXPrv
Expand All @@ -14,6 +16,7 @@
* @prop {HDToXKeyBytes} toXPubBytes
* @prop {HDUtils} utils
* @prop {HDWipePrivates} wipePrivateData - randomizes private key buffer in-place
* @prop {HDToPublic} toPublic - returns public key
* @prop {Number} HARDENED_OFFSET - 0x80000000
* @prop {HDVersions} MAINNET - 'xprv' & 'xpub'
* @prop {HDVersions} TESTNET - 'tprv' & 'tpub'
Expand All @@ -35,6 +38,7 @@
* @prop {HDHasher} ripemd160sum
* @prop {HDHasher} sha256sum
* @prop {HDHasher} sha512hmac
* @prop {HDBase64Url} bytesToBase64Url
* @prop {HDKeyToKey} toPublicKey
*/

Expand Down Expand Up @@ -218,6 +222,23 @@ var DashHd = ("object" === typeof module && exports) || {};
return new Uint8Array(sig);
};

/** @type {HDBase64Url} */
Utils.bytesToBase64Url = function (bytes) {
let bins = [];

for (let i = 0; i < bytes.length; i += 1) {
let b = bytes[i];
let s = String.fromCodePoint(b);
bins.push(s);
}

let str = bins.join("");
let b64 = btoa(str);
let b64url = b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");

return b64url;
};

/** @type {HDSecureErase} */
Utils.secureErase = function (buf) {
if (!Crypto.getRandomValues) {
Expand Down Expand Up @@ -248,6 +269,8 @@ var DashHd = ("object" === typeof module && exports) || {};
let XKEY_SIZE = 74;
let XKEY_DEPTH = 4; // m/44'/5'/0'/<0>[/0]

DashHd._utils = Utils;

// Bitcoin defaults hard-coded by default.
// Use package `coininfo` for others.
DashHd.MAINNET = { private: 0x0488ade4, public: 0x0488b21e };
Expand Down Expand Up @@ -651,6 +674,29 @@ var DashHd = ("object" === typeof module && exports) || {};
return hdkey;
};

DashHd.toId = async function (hdkey) {
let idBytes = await DashHd.toIdBytes(hdkey);
let id = Utils.bytesToBase64Url(idBytes);

return id;
};

DashHd.toIdBytes = async function (hdkey) {
let xpubBytes = await DashHd.toXPubBytes(hdkey);

let hashBuffer = await Crypto.subtle.digest("SHA-256", xpubBytes);
let idBuffer = hashBuffer.slice(0, 8);
let idBytes = new Uint8Array(idBuffer);

return idBytes;
};

DashHd.toPublic = function (_hdkey) {
let hdkey = Object.assign({}, _hdkey);
hdkey.privateKey = null;
return hdkey;
};

DashHd.wipePrivateData = function (hdkey) {
if (hdkey.privateKey) {
Utils.secureErase(hdkey.privateKey);
Expand All @@ -659,6 +705,12 @@ var DashHd = ("object" === typeof module && exports) || {};
return hdkey;
};

DashHd.toPublic = function (_hdkey) {
let hdkey = Object.assign({}, _hdkey);
hdkey.privateKey = null;
return hdkey;
};

/**
* @param {Boolean} assertion
* @param {String} message
Expand Down Expand Up @@ -828,6 +880,18 @@ if ("object" === typeof module) {
* @returns {Promise<String>}
*/

/**
* @callback HDToId
* @param {HDKey} hdkey
* @returns {Promise<String>}
*/

/**
* @callback HDToIdBytes
* @param {HDKey} hdkey
* @returns {Promise<Uint8Array>}
*/

/**
* @callback HDToXKeyBytes
* @param {HDKey} hdkey
Expand Down Expand Up @@ -871,6 +935,12 @@ if ("object" === typeof module) {
* @returns {Promise<String>}
*/

/**
* @callback HDBase64Url
* @param {Uint8Array} bytes
* @returns {String} - URL-Safe Base64 Encoding
*/

/**
* @callback HDHasher
* @param {Uint8Array} bytes
Expand Down Expand Up @@ -908,6 +978,12 @@ if ("object" === typeof module) {
* @param {Uint8Array} buf
*/

/**
* @callback HDToPublic
* @param {HDKey} hdkey
* @returns {HDKey}
*/

/**
* @callback HDWipePrivates
* @param {HDKey} hdkey
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dashhd",
"version": "3.1.0",
"version": "3.2.0",
"description": "Manage HD Keys from HD Wallet Seed and Extended (xprv, xpub) Key Paths. Part of $DASH Tools.",
"main": "dashhd.js",
"browser": {
Expand Down