Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

dashhd

Package Overview
Dependencies
Maintainers
2
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dashhd - npm Package Compare versions

Comparing version 0.3.1 to 3.0.0

dashhd.js

92

package.json
{
"name": "dashhd",
"version": "0.3.1",
"description": "Browser, Node, Bundler, and CLI compatible Dash HD Wallet tools",
"main": "index.js",
"bin": {
"dash-mnemonic-generate": "./bin/mnemonic-generate.js",
"dash-mnemonic-to-addrs": "./bin/mnemonic-to-addrs.js",
"dash-mnemonic-to-seed": "./bin/mnemonic-to-seed.js",
"dash-mnemonic-to-wifs": "./bin/mnemonic-to-wifs.js",
"dash-mnemonic-to-xprv": "./bin/mnemonic-to-xprv.js",
"dash-mnemonic-to-xpub": "./bin/mnemonic-to-xpub.js",
"dash-seed-to-wif": "./bin/seed-to-wif.js",
"dash-seed-to-wifs": "./bin/seed-to-wifs.js",
"dash-seed-to-xkeys": "./bin/seed-to-xkeys.js",
"dash-qr": "./bin/qr.js",
"dash-wif-to-qr": "./bin/wif-to-qr.js",
"dash-xprv-to-wif": "./bin/xprv-to-wif.js",
"dash-xprv-to-wifs": "./bin/xprv-to-wifs.js",
"dash-xpub-to-addr": "./bin/xpub-to-addr.js",
"dash-xpub-to-addrs": "./bin/xpub-to-addrs.js"
"version": "3.0.0",
"description": "Manage HD Keys from HD Wallet Seed and Extended (xprv, xpub) Key Paths. Part of $DASH Tools.",
"main": "dashhd.js",
"browser": {
"crypto": false
},
"files": [
"bin/",
"dashd.js",
"index.js",
"lib/"
],
"scripts": {
"test": "node test.js",
"doc": "npx jsdoc@3.x --configure ./jsdoc.conf.json --destination ./docs --package ./package.json --readme ./README.md --access all --private --recurse ./lib/",
"fmt": "npx -p prettier@2.x -- prettier -w '**/*.{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\""
},
"repository": {
"type": "git",
"url": "git+https://github.com/dashhive/dashhd.js.git"
"url": "git://github.com/dashive/dashhd.js"
},
"license": "SEE LICENSE IN LICENSE",
"keywords": [
"bip39",
"DASH",
"hd",
"wallet",
"key",
"keys",
"path",
"bip32",
"bip44",
"mnemonic",
"seed",
"passphrase",
"wallet",
"hd",
"dash"
"hierarchical",
"deterministic",
"crypto",
"$DASH",
"Tools"
],
"author": "AJ ONeal <aj@therootcompany.com> (https://throotcompany.com/)",
"license": "SEE LICENSE IN LICENSE",
"bugs": {
"url": "https://github.com/dashhive/dashhd.js/issues"
"url": "https://github.com/dashive/dashhd.js/issues"
},
"homepage": "https://github.com/dashhive/dashhd.js#readme",
"homepage": "https://github.com/dashive/dashhd.js",
"files": [
"dashhd.js",
"jsconfig.json"
],
"devDependencies": {
"@dashincubator/secp256k1": "^1.7.1-4",
"dashphrase": "^1.3.1",
"mocha": "^10.2.0",
"mocha-lcov-reporter": "0.0.1"
},
"dependencies": {
"@dashincubator/base58check": "^1.3.1",
"@dashincubator/ripemd160": "^2.3.0",
"bip39": "^3.0.4",
"hdkey": "github:dashhive/hdkey",
"qrcode-svg": "^1.1.0"
"dashkeys": "^1.0.0"
},
"scripts": {
"lint": "npx -p typescript@4.x -- tsc -p ./jsconfig.json",
"browser-test": "npx mochify@6 --wd -R spec",
"test": "mocha",
"unit": "mocha",
"coverage": "npx istanbul@0.4 cover ./node_modules/.bin/_mocha -- --reporter list test/*.js",
"coveralls": "npm run-script coverage && npx coveralls@3 < coverage/lcov.info",
"bump": "npm version -m \"chore(release): bump to v%s\"",
"fmt": "npx -p prettier@2.x -- prettier -w '**/*.{js,md}'"
}
}

@@ -1,259 +0,1298 @@

# dashhd.js
# [DashHD.js](https://github.com/dashhive/dashhd.js)
Browser, Node, Bundler, and CLI compatible Dash HD Wallet tools
Manage HD Keys from HD Wallet Seed and Extended (xprv, xpub) Key Paths. \
(compatible with the [Hierarchical Deterministic Keys (BIP-44)][bip-44] and [BIP-32][bip-32]
specs)
> A fully-functional, production-ready reference implementation of Dash HD -
> suitable for learning DASH specs and protocols, and porting to other
> languages.
```text
HD Wallet Seed: ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a13332572917f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069
(the canonical _Zeed_ seed, from the canonical _Zoomonic_)
```
```text
HD XKey Path: m/44'/5'/0'/0
XPrv: xprvA2L7qar7dyJNhxnE47gK5J6cc1oEHQuAk8WrZLnLeHTtnkeyP4w6
Eo6Tt65trtdkTRtx8opazGnLbpWrkhzNaL6ZsgG3sQmc2yS8AxoMjfZ
XPub: xpub6FKUF6P1ULrfvSrhA9DKSS3MA3digsd27MSTMjBxCczsfYz7vcFL
nbQwjP9CsAfEJsnD4UwtbU43iZaibv4vnzQNZmQAVcufN4r3pva8kTz
HD Key Path: m/44'/5'/0'/0/0
WIF: XCGKuZcKDjNhx8DaNKK4xwMMNzspaoToT6CafJAbBfQTi57buhLK
Address: XrZJJfEKRNobcuwWKTD3bDu8ou7XSWPbc9
```
```text
HD XKey Path: m/44'/5'/1'/1
XPrv: xprvA2ACWaqwADRtbkLsM6oQHzeWtqZVviBmKMKNRBFcwKGGRBgWHNeo
ZSKzduFMFkqvNsV5LaqRT9XRibzgSAweAAsfMF35PWy6beK3aL1BwTU
XPub: xpub6F9Yv6NpzazBpERLT8LQf8bFSsPzLAucgaEyDZfEVeoFHz1epuy4
7EeUVCRTNVToM1zgFZMxiGs2AFc9cNqZE2UVwJod2zPkG7W4ZGRuwJJ
HD Key Path: m/44'/5'/1'/1/1
WIF: XF9murLtNpJaZXbwMxqJ6BhigEtu9NxfBCJDBokCJcqFkYkz3itz
Address: XueHW2ELMxoXzXcaHMxmwVWhcADE1W5s8c
```
[bip-32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
[bip-39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
[bip-43]: https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki
[bip-44]: https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
[dash-phrase]: https://github.com/dashhive/DashPhrase.js
[dash-keys]: https://github.com/dashhive/DashKeys.js
# Table of Contents
- CLI utils
- dash-mnemonic-generate
- dash-mnemonic-to-addrs (salted or plain)
- dash-mnemonic-to-seed
- dash-mnemonic-to-wifs
- dash-mnemonic-to-xprv
- dash-mnemonic-to-xpub
- dash-seed-to-xkeys (extended public / private keys)
- dash-seed-to-wif
- dash-seed-to-wifs
- dash-qr (converts XPubs and PayAddrs, and XPrvs and WIFs to QR Codes)
- dash-xprv-to-wif
- dash-xprv-to-wifs
- dash-xpub-to-addr
- dash-xpub-to-addrs
- Test Fixtures
- Mnemonic
- Salted Seed (password)
- Plain Seed
- [Install](#install)
- Node, Bun, & Bundlers
- Browser
- [Usage Overview](#usage-overwiew)
- [**Production-Ready** QuickStart](#production-quickstart)
- [API](#api)
- Note on derivation exceptions
- DashHd derivations & encodings
- HD Key Types
- [Tutorial Walkthrough](#walkthrough)
- Passphrase, Secret, Seed
- Wallet Derivation
- HD Path Derivation
- _Wallet_, _Account_, and _X Key_ Derivation
- XPrv and XPub Encoding
- _Address Key_ Derivation
- WIF and Address Encoding
- [Glossary](#glossary)
# CLI
# Install
## Install
Notes:
- **`secp256k1`** is **not a listed dependency** in `package.json` for this - \
because there are many decent implementations to choose from. \
HOWEVER, [DashKeys][dash-keys] will use `@dashincubator/secp256k1@1.x` \
by default, it if is installed. \
See [DashKeys][dash-keys] if you prefer to use another implementation.
- [DashPhrase][dash-phrase] is recommended, but not strictly required. \
(you can work with bare `seed`s without a word list)
## Node, Bun, & Bundlers
```sh
npm install --location=global dashhd
npm install --save @dashincubator/secp256k1@1.x
npm install --save dashhd@3.x
npm install --save dashphrase
```
Or, use without installing:
```js
let DashHd = require("dashd");
let DashPhrase = require("dashphrase");
```
```sh
npx -p dashd dash-mnemonic-generate
## Browser
```html
<script src="https://unpkg.com/@dashincubator/secp256k1.js"></script>
<script src="https://unpkg.com/dashkeys@0.9/dashkeys.js"></script>
<script src="https://unpkg.com/dashhd@3.x/dashhd.js"></script>
```
## Usages
```js
let DashHd = window.DashHd;
let DashPhrase = window.DashPhrase;
```
```sh
./bin/mnemonic-generate.js
# Usage Overview
# again cable air agree veteran march surface dragon behind isolate just wreck
1. Generate a _Wallet_
```js
let wallet = await DashHd.fromSeed(seedBytes);
```
- As a one-off, you can **directly** generate an _Address Key_ by _HD Path_
```js
let hdpath = `m/44'/5'/0'/0/0`;
let key = await DashHd.derivePath(hdpath);
let wif = await DashHd.toWif(key.privateKey);
let address = await DashHd.toAddr(key.publicKey);
```
2. Generate an _Account_
```js
let accountIndex = 0;
let account = await wallet.deriveAccount(accountIndex);
```
3. Generate an _X Key_ (Extended Private or Public Key)
```js
let use = DashHd.RECEIVE;
let xkey = await account.deriveXKey(use);
```
4. (Optional) Generate _XPrv_ and _XPubs_
```js
let xprv = DashHd.toXPrv(xkey);
let xpub = DashHd.toXPub(xkey);
```
5. Generate an _Address Key_
```js
let key = await xkey.deriveAddress(use);
```
6. Generate _WIF_ & _Address_
```js
let wif = await DashHd.toWif(key.privateKey);
let address = await DashHd.toAddr(key.publicKey);
```
# Production QuickStart
However, production code will look more like this:
1. Get a _Seed_ from the user's _Passphrase Mnemonic_ and _Secret Salt_
```js
let wordList = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong";
let secretSalt = "TREZOR";
// Derive a Wallet Seed
let seedBytes = await DashPhrase.toSeed(wordList, secretSalt);
```
2. Derive a _Wallet_, _Account_, and _X Key_, if possible. \
(reject the _Passphrase_ or _Seed_ if _Account_ index 0 is not valid)
```js
let accountIndex = 0;
let xkey;
try {
let wallet = await DashHd.fromSeed(seedBytes); // seed from step 1
let account = await wallet.deriveAccount(accountIndex);
void (await account.deriveXKey(DashHd.CHANGE));
xkey = await account.deriveXKey(DashHd.RECEIVE);
} catch (e) {
window.alert("Error: The passphrase can't generate a valid 1st account!");
}
```
**Note**: For multi-*Account*s apps, just mark failed indexes as invalid.
3. Derive a batch of _Address_ keys (20 is the typical number)
```js
let keys = [];
let previousIndex = 0;
let use = DashHd.RECEIVE;
let last = previousIndex + 20;
for (let i = previousIndex; i < last; i += 1) {
let key;
try {
key = await xkey.deriveAddress(i); // xkey from step 2
} catch (e) {
last += 1;
continue;
}
let wif = await DashHd.toWif(key.privateKey);
let address = await DashHd.toAddr(key.publicKey);
let hdpath = `m/44'/5'/${accountIndex}'/${use}/${i}`;
keys.push({
index: i,
hdpath: hdpath, // useful for multi-account indexing
address: address, // XrZJJfEKRNobcuwWKTD3bDu8ou7XSWPbc9
wif: wif, // XCGKuZcKDjNhx8DaNKK4xwMMNzspaoToT6CafJAbBfQTi57buhLK
});
}
```
Note: it may be useful to indicate the path of the
# API
- IMPORTANT
- _all_ derivations _can_ fail
- DashHd
```js
Constants
MAINNET, TESTNET
HARDENED, PUBLIC
RECEIVE, CHANGE
async fromSeed(seedBytes, opts) // depth-0 hdkey (Wallet)
async fromXKey(xprv||xpub, opts) // depth-4 hdkey (XKey)
async toWif(privBytes, opts)
async toAddr(pubBytes, opts)
async toXPrv(xkey, opts)
async toXPub(xkey, opts)
```
- DashHd (BIP-32)
```js
create(hdkey) // depth-n HDKey (any)
async derivePath(
hdkey,
hdpath,
)
async deriveChild(
hdkey,
index,
isHardened,
)
```
- HD Key Types
```js
Wallet
async deriveAccount(accountIndex)
Account
async deriveXKey(use = 0)
XKey
async deriveAddress(keyIndex)
Key
{ privateKey, publicKey }
HDKey
{ versions, depth, parentFingerprint,
index, chainCode, privateKey, publicKey }
```
## IMPORTANT
All _derive_ methods can fail (throw an error).
This is _highly-unlikely_, but _normal_ (because maths).
It's recommended that:
1. **Before accepting a seed as valid**, derive these HD Paths:
```
m/44'/5'/0'/0/0
m/44'/5'/0'/0/1
m/44'/5'/0'/1/0
m/44'/5'/0'/1/1
```
If derivation fails, **reject the seed**.
2. When creating a **new Account Index**, always **derive both *Use Index*es**:
```
m/44'/5'/n'/0
m/44'/5'/n'/1
```
If either the _Account Index_ or _Use Index_ derivation fails, \
**mark the whole Account Index as invalid**.
3. If a key derivation ever fails, simply **mark that key as invalid**.
```
m/44'/5'/0'/0/n
```
Most likely you will never personally encounter this failure.
However, when your software is generating millions and billions of keys across
thousands and millions of accounts, eventually one of the key expansion hashes
will _just so happen_ to hit _Infinity_ or _Zero_ on the curve.
Some libraries abstract this away by automatically incrementing to the next
index on failure, but since the occurrence is so rare, and therefore will
inevitably lead to highly confusing and difficult to track bugs (including
address re-use, a privacy concern), we do not.
## `DashHd`
This is the top-level export, and these methods are specific for the BIP-44 use
case of HD Keys for:
- Wallet
- Account
- XKey (XPrv or XPub)
- Key (WIF or Address)
### Constants
**`MAINNET`**, **`TESTNET`**
The `version` byte that gets base58check encoded to a human-friendly prefix.
```js
// "xprv" "xpub"
DashHd.MAINNET = { private: 0x0488ade4, public: 0x0488b21e };
```
```sh
./bin/mnemonic-to-addrs.js
# Usage: mnemonic-to-addrs <./mnemonic.txt> [./passphrase.txt] [startPath] [endPath]
```js
// "tprv" "tpub"
DashHd.TESTNET = { private: 0x0488ade4, public: 0x0488b21e };
```
# m/44'/5'/0'/0/0:
# XjxyR1gve94LuKqkMLEeqJbEVM5B5q1ZSx
**`HARDENED`**, **`PUBLIC`**
Whether the HD Key should be derived as _Hardened_ or _Public_ (sharable).
```js
DashHd.HARDENED = true;
DashHd.PUBLIC = false;
```
```sh
./bin/mnemonic-to-seed.js
# Usage: mnemonic-to-seed <./mnemonic.txt> [./passphrase.txt]
**`RECEIVE`**, **`CHANGE`**
# f3f1ff73a93aa5b2fa5db7bdabc184e26bd5120fac3345d89133b3e027982f3d5a7b02704b7f03142873bb264498676798dbefa86ff63f18f14d12e61d114be4
The intended use of the key - as a receiving address for external funds, or an
internal change address.
```js
DashHd.RECEIVE = 0;
DashHd.CHANGE = 1;
```
```sh
./bin/mnemonic-to-wifs.js
# Usage: mnemonic-to-wifs <./mnemonic.txt> [./passphrase.txt] [startPath] [endPath]
### `fromSeed(seedBytes, opts)`
# m/44'/5'/0'/0/0: XKHiWYkmDkNnWGP756UCGcuZ21mHGeYdWeCBBHCBGZaf3NYw1SAz
# XjxyR1gve94LuKqkMLEeqJbEVM5B5q1ZSx
Generate a [Wallet](#wallet) (depth-0 HD Key) \
with a default HD Path prefix of `m/44'/5'`.
```js
let words = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong";
let secret = "TREZOR";
let seed = await DashPhrase.toSeed(words, secret);
```
```sh
./bin/mnemonic-to-xprv.js
# Usage: mnemonic-to-xprv <./mnemonic.txt> [./passphrase.txt] [hdpath]
```js
let wallet = await DashHd.fromSeed(seedBytes, options);
// { deriveAccount,
// versions,
// depth: 0, parentFingerprint: 0, index: 0,
// chainCode, privateKey, publicKey }
```
# xprvA1WUDWFxdE5UGW1XNTnkZnd3K6bdidZBTtzvtEQziBpS3N8tajC4QKyRLmas7DK4HXK76wSXgMV1uV6RbKyM5f4uu1VmguEhAqvzQwr2mrC
# xpub6EVpd1nrTbdmUz5zUVKkvvZms8S886H2q7vXgcpcGXMQvAU38GWJx8HuC28Bm8Cizq7dHJvL6armkvL7vvxRpxUxAmpVQF6s8aq5BRBCMrD
**Options**
```json5
{
purpose: 44, // BIP-44 (default)
coinType: 5, // DASH (default)
versions: DashHd.MAINNET, // default
}
```
```sh
./bin/mnemonic-to-xpub.js
# Usage: mnemonic-to-xpub <./mnemonic.txt> [./passphrase.txt] [hdpath]
### `fromXKey(xprv || xpub, opts)`
# xpub6EVpd1nrTbdmUz5zUVKkvvZms8S886H2q7vXgcpcGXMQvAU38GWJx8HuC28Bm8Cizq7dHJvL6armkvL7vvxRpxUxAmpVQF6s8aq5BRBCMrD
Parses a Base58Check-encoded `xprv` or `xpub` (Extended Private or Public Key)
into an _X Key_ (depth-4 HD Key).
Only the _depth_ is known. The prefix is **_not_** recoverable, but can be
assumed to be something like `m/44'/5'/0'/0`.
```js
let xprv =
"xprvA2L7qar7dyJNhxnE47gK5J6cc1oEHQuAk8WrZLnLeHTtnkeyP4w6Eo6Tt65trtdkTRtx8opazGnLbpWrkhzNaL6ZsgG3sQmc2yS8AxoMjfZ";
```
```sh
./bin/seed-to-xkeys.js
# Usage: seed-to-wif <./seed.hex> [account] [direction]
```js
let xkey = await DashHd.fromXKey(xkeyString, options);
// { deriveAddress,
// versions: v, depth: n, parentFingerprint: p, index: 0,
// chainCode: c, privateKey: privOrNull, publicKey: pubBytes }
```
# xprvA1uHCfBAez3GCjbyU8UWQitSaZ3RUUy8eft7mf8rnH5z6WCQJ6ehHTNAPRes6k6cwimXjhEHoxka79uoQ2Kdyx7BxbGYKGSnkdjfdjXfvjr
# xpub6EtdcAi4VMbZRDgSaA1WmrqB8asuswgz1toia3YULccxyJXYqdxwqFgeEexVxr8ytJPHZYTrhbYJjqaFumih45awabyaHwUmCvXbGf7sujG
**Options**
```json5
{
bip32: false, // allow arbitrary depth (Wallet, Purpose, Coin, Account, etc)
normalizePublicKey: false, // validate pubkey by re-ploting X,Y on curve
versions: DashHd.MAINNET, // must match the given version
}
```
```sh
./bin/seed-to-wif.js
# Usage: seed-to-wif <./seed.hex> [account] [direction] [index]
### `toWif(privBytes, opts)`
Wrapper around `DashKeys.encodeKey(keyBytes, options)` to Base58Check-encode a
Private Key as in _Wallet Import Format_.
```js
let addressIndex = 0;
let key = await xkey.deriveAddress(addressIndex);
```
```sh
./bin/xprv-to-wif.js
# Usage: xprv-to-wif <./xprv.txt> [index]
```js
let wif = await DashHd.toWif(key.privateKey);
// "XCGKuZcKDjNhx8DaNKK4xwMMNzspaoToT6CafJAbBfQTi57buhLK"
```
```txt
XD3sNsdXjXvsnGtcbiqj3SCVdGHyHCRWFDaCAhWotxVfudSN4iRt
**Options**
```json5
{
version: "cc",
}
```
```sh
./bin/xpub-to-addr.js
# Usage: xpub-to-addr <./xpub.txt> [index]
### `toAddr(pubBytes, opts)`
Wrapper around `DashKeys.encodeKey(keyBytes, options)` to Base58Check-encode a
Public Key as an _Address_.
```js
let addressIndex = 0;
let key = await xkey.deriveAddress(addressIndex);
```
```txt
XnRtALP7ns8stH6o79RQTiWGeW2SQeetxL
```js
let wif = await DashHd.toAddr(key.publicKey);
// "XrZJJfEKRNobcuwWKTD3bDu8ou7XSWPbc9"
```
```sh
./bin/seed-to-wifs.js
# Usage: seed-to-wif <./seed.hex> [fromPath] [toPath]
# Example: seed-to-wif ./seed.hex "0'/0/0" "1'/0/1"
**Options**
```json5
{
version: "4c", // (default) DASH PubKeyHash
}
```
```sh
./bin/xprv-to-wifs.js
# Usage: xprv-to-wif <./xprv.txt> [fromPath] [toPath]
# Example: xprv-to-wif ./xprv.txt "0'/0/0" "1'/0/1"
### `toXPrv(hdkey)`
Wrapper around `DashKeys.encodeKey(keyBytes, options)` to Base58Check-encode an
_X Key_ as an _XPrv_.
```js
let use = DashHd.RECEIVE;
let xkey = await account.deriveXKey(use);
// Or...
let xkey = await DashHd.fromXKey(xprv);
```
```txt
m/44'/5'/0'/0/0: XKHiWYkmDkNnWGP756UCGcuZ21mHGeYdWeCBBHCBGZaf3NYw1SAz
XjxyR1gve94LuKqkMLEeqJbEVM5B5q1ZSx
m/44'/5'/0'/0/1: XCsy8Qw1fLH7C1UxLjBfTfLpn8DMRK1TMNNE2a5J1F4TyE5UApcK
XxRrwh1xBWig9rfLyiy494u2vj6YXQMsH7
```js
let xprv = await DashHd.toXPrv(xkey);
// "xprvA2L7qar7dyJNhxnE47gK5J6cc1oEHQuAk8WrZLnLeHTtnkeyP4w6Eo6Tt65trtdkTRtx8opazGnLbpWrkhzNaL6ZsgG3sQmc2yS8AxoMjfZ"
```
m/44'/5'/1'/0/0: XEWDJiCKuSaNHUoYFaGiTv1QG3p49xc4vx6cbS19CHZFe1TpwvJF
XrX7Ph3rXV9kyzQfcDteCf14xvm8nM5Mmg
m/44'/5'/1'/0/1: XHTyj295ekRT4UqDnYd5zdHwLZ5iJdQnN8DjH9CQqPxFVipJqYns
XxTRzgDwnED8cPmrnCRRwpnnT3v5VL3KcE
### `toXPrv(hdkey)`
Wrapper around `DashKeys.encodeKey(keyBytes, options)` to Base58Check-encode an
_X Key_ as an _XPub_.
```js
let use = DashHd.RECEIVE;
let xkey = await account.deriveXKey(use);
// Or...
let xkey = await DashHd.fromXKey(xpub);
```
```sh
./bin/xpub-to-addrs.js
# Usage: xpub-to-addrs <./xpub.txt> [startIndex] [endIndex]
# Example: xpub-to-addrs ./xpub.txt 0 1
```js
let xpub = await DashHd.toXPub(xkey);
// "xpub6FKUF6P1ULrfvSrhA9DKSS3MA3digsd27MSTMjBxCczsfYz7vcFLnbQwjP9CsAfEJsnD4UwtbU43iZaibv4vnzQNZmQAVcufN4r3pva8kTz"
```
```txt
XjxyR1gve94LuKqkMLEeqJbEVM5B5q1ZSx
XxRrwh1xBWig9rfLyiy494u2vj6YXQMsH7
## `DashHd` (BIP-32)
These are the more rudimentary functions which can be used for either style of
HD Keys:
- BIP-44 / BIP-43 (Wallet, Account, XKey, Key)
- or BIP-32 (generic HD Keys)
These do not enforce BIP-44 compliance, so they can be useful for testing and
debugging.
### `create(hdkey)`
Returns an _HD Key_ with any missing values set to their default.
```js
let hdkey = DashHd.create({
chainCode: chainBytes,
privateKey: privOrNull,
publicKey: pubBytes,
});
```
# Fixtures
**HD Key**
For the purpose of testing against known-good values, we provide these fixtures.
```json5
{
versions: DashHd.MAINNET,
depth: 0,
parentFingerprint: 0, // should be set if depth is set
index: 0,
chainCode: chainBytes, // required
privateKey: privOrNull, // required (or null)
publicKey: pubBytes, // required
}
```
## Mnemonic
### `deriveChild(hdkey, index, isHardened)`
This mnemonic can be used to generate any number of seeds, meaning any number of
"password-protected" wallets.
Derives one additional depth of an HD Key, by index value and hardness.
```txt
again cable air agree veteran march surface dragon behind isolate just wreck
```js
let hdkey = DashHd.fromXKey(xpub, { bip32: true });
```
**Misnomer Alert**: this is obviously a _passphrase_, but early on the term
_passphrase_ was mistakenly used to describe a _salt_, so we're stuck calling
this "mnemonic".
```js
let UNHARDENED = false;
let nextIndex = 42;
let nextHdkey = await DashHd.deriveChild(hdkey, nextIndex, UNHARDENED);
```
## Seed, xprv, WIFs, & Addrs (Empty Password)
### `derivePath(hdkey, hdpath)`
If the mnemonic is used _without_ a "password" (or "secret"), it will produce
this HD Wallet "seed":
Iterates over an HD Path, calling `deriveChild(hdkey, index, isHardened)` for
each index.
```txt
f3f1ff73a93aa5b2fa5db7bdabc184e26bd5120fac3345d89133b3e027982f3d5a7b02704b7f03142873bb264498676798dbefa86ff63f18f14d12e61d114be4
Can derive any valid BIP-32 path, at any depth. \
(even if nonsensical - such as a hardened key after an unhardened one)
```js
let hdkey = DashHd.fromSeed(seedBytes);
```
The `xprv` and `xpub` for the HD prefixes `m/44'/5'/0'/0` and `m/44'/5'/2'/1`
are:
```js
let childKey = DashHd.derivePath(hdkey, `m/0'/0/1'/1/0`);
// { versions, depth, parentFingerprint,
// index, chainCode, privateKey, publicKey }
```
```sh
# m/44'/5'/0'/0
xprvA1uHCfBAez3GCjbyU8UWQitSaZ3RUUy8eft7mf8rnH5z6WCQJ6ehHTNAPRes6k6cwimXjhEHoxka79uoQ2Kdyx7BxbGYKGSnkdjfdjXfvjr
This is the same as
xpub6EtdcAi4VMbZRDgSaA1WmrqB8asuswgz1toia3YULccxyJXYqdxwqFgeEexVxr8ytJPHZYTrhbYJjqaFumih45awabyaHwUmCvXbGf7sujG
```js
let childKey = hdkey;
childKey = await DashHd.deriveChild(childKey, 0, true);
childKey = await DashHd.deriveChild(childKey, 0, false);
childKey = await DashHd.deriveChild(childKey, 1, true);
childKey = await DashHd.deriveChild(childKey, 1, false);
childKey = await DashHd.deriveChild(childKey, 0, false);
// { versions, depth, parentFingerprint,
// index, chainCode, privateKey, publicKey }
```
```sh
# m/44'/5'/2'/1/2
xprvA1zEQq1FvKbQkXosnKgsBTrtk1K6iEfdUSLnHgf7ejLYU2NAU9mK5gqAYNP34ykNMfVkY4emcdTjuaqUmz2J7Hohupn9VFRhQrV6CWpmKaZ
## Key Types
xpub6EyapLY9kh9hy1tLtMDsYbodJ39b7hPUqfGP654jD4sXLphK1h5ZdV9ePgapU2jMrVBy4sXUW4CSxG3aXdDgJGTsMQFy8D51TRSdjcjQxpV
A BIP-44 _HD Path_ has 5 depths, each with their own HD Key Type:
```js
//0 1 2 3 4 5
`m/${purpose}'/${coin}'/${account}'/${use}/${index}`;
```
Given the HD paths `m/44'/5'/0'/0/0` and `m/44'/5'/2'/1/2`, that seed will
produce these WIFs (Private Keys) and Pay Addresses (PubKey Hashes).
- Depth 0: _Wallet (Root) Key_ - calculated from a Seed
- Depth 1: _Purpose Key_ - predefined as index `44'` for BIP-44
- Depth 2: _Coin Key_ - predefined as index `5'` for DASH \
(this is also sometimes referred to as the "Wallet")
- Depth 3: _Account Key_ - derived by account index
- Depth 4: _X Key_ is for sharing, derived by Use (Receiving or Change)
- Depth 5: _Key_ is for paying and getting paid (WIF or Address)
- Depth 6+: not defined by _BIP-44_, application specific
```txt
(account 0, external/receiving, address 0)
m/44'/5'/0'/0/0: XD3sNsdXjXvsnGtcbiqj3SCVdGHyHCRWFDaCAhWotxVfudSN4iRt (WIF)
XnRtALP7ns8stH6o79RQTiWGeW2SQeetxL (Addr)
m/44'/5'/0'/0/1: XJ8RCLHTg55mBbvv5mF5Ja3DikzBYWxHn5DvKyJoFm2cufBdUSc2
XeGtfXhcgeyLS2EtAnrkbEKNmVVDupZV6p
Keys can be derived
(account 2, internal/change, address 2)
m/44'/5'/2'/1/2: XJDdTJ1WigKiUdsvofPGmMCHoPd4kpWKD1yGrigJXuwqcxoLUn4W (WIF)
XoMEcuxW4Ki1SXduDjQUdntSYU4PWzhqTC (Addr)
- by instance (recommended):
```js
let wallet = await DashHd.fromSeed(seedBytes);
let accountIndex = 0;
let account = await wallet.deriveAccount(accountIndex);
let use = DashHD.RECEIVE;
let xkey = await account.deriveXKey(use);
let addressIndex = 0;
let key = await xkey.deriveAddress(addressIndex);
```
- by path (not for loops):
```js
let wallet = await DashHd.fromSeed(seedBytes);
let hdpath = `m/${purpose}'/${coin}'/${account}'/${use}/${index}`;
let key = await DashHd.derivePath(wallet, hdpath);
```
The benefit of deriving _by instance_ is that when you need to derive in a loop,
such as multiple keys at the same depth - e.g. Addresses from the same X Key, or
Accounts from the same Wallet - you're not deriving from the Wallet Root each
time.
Since the key derivation process is intentionally somewhat slow, it's best to
loop at the lowest level that you can. For example:
```js
// ...
let xkey = await account.deriveXKey(use);
for (let addressIndex = 0; addressIndex < 100; addressIndex += 1) {
let key = await xkey.deriveAddress(addressIndex);
// ...
}
```
## Seed, xprv, WIFs, & Addrs (With Password)
### Wallet (depth 0)
If the mnemonic is used with the "password" (or "secret") `supersecret123`, it
will produce this HD Wallet seed:
A root HD Key with a `deriveAccount(accountIndex)` method.
Secret: `supersecret123`
Can also derive BIP-32 HD Keys.
```txt
6f9c7acc33e3690d734de56619936d7dce1d3aadf624cdbb09e50a3c978c13234f59112e791910d0cd94c483113dcab0a637cb7f7b85fa78e7af6464e3967713
From a Seed:
```js
let words = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong";
let secret = "TREZOR";
let seed = await DashPhrase.toSeed(words, secret);
let wallet = await DashHd.fromSeed(seed, {});
```
The `xprv` and `xpub` for the HD prefixes `m/44'/5'/0'/0` and `m/44'/5'/2'/1`
are:
To a different Coin Type or non-BIP-44 scheme:
```sh
# m/44'/5'/0'/0
xprvA1WUDWFxdE5UGW1XNTnkZnd3K6bdidZBTtzvtEQziBpS3N8tajC4QKyRLmas7DK4HXK76wSXgMV1uV6RbKyM5f4uu1VmguEhAqvzQwr2mrC
```js
let purpose = 44;
let coinType = 0;
let accountIndex = 0;
let account = await DashHd.derivePath(
wallet,
`m/${purpose}'/${coinType}'/${accountIndex}'`,
);
```
xpub6EVpd1nrTbdmUz5zUVKkvvZms8S886H2q7vXgcpcGXMQvAU38GWJx8HuC28Bm8Cizq7dHJvL6armkvL7vvxRpxUxAmpVQF6s8aq5BRBCMrD
### Account (depth 3)
A hardened HD Key with a `deriveXKey(use)` method.
From a Wallet:
```js
let accountIndex = 0;
let account = wallet.deriveAccount(accountIndex);
let use = DashHd.RECEIVE;
let xkey = await account.deriveXKey(use);
```
```sh
# m/44'/5'/2'/1
xprvA1UUAiR2AFvujb6WyC4TSokLBR48hKSqczH9MZfBXoBUztPnsvWByTuVs5GvmbySGjZ95mZtBMv3p3eBPJFFi4efT8azWz8v5zqVT2dFm6Z
From an HD Path:
xpub6ETpaDwuzdVCx5Az5DbTowh4jStd6nAgzDCk9x4o68iTsgiwRTpSXGDyiNDf9dSC75MLM6wTmfcUntPgNFYZ728zZ84Wb3xs43C8YrGZoap
```js
let accountIndex = 0;
let account = await DashHd.derivePath(wallet, `m/44'/5'/${accountIndex}'`);
let use = DashHd.RECEIVE;
let xkey = await account.deriveXKey(use);
```
Given the HD paths `m/44'/5'/0'/0/0` and `m/44'/5'/2'/1/2`, that seed will
produce these WIFs (Private Keys) and Pay Addresses (PubKey Hashes).
### XKey (depth 4)
An non-hardened HD Key with a `deriveAddress(addressIndex)` method.
Represents a non-hardened XPrv or XPub.
Share an XPub with a contact so that they can derive additional addresses to pay
you repeatedly without sacrificing privacy, and without needing interaction from
you to creat ea new address each time.
Share an XPrv with an application so that you can load the XPub side and it can
use the XPrv side to make payments on your behalf.
From an Account:
```js
let use = DashHd.RECEIVE;
let xkey = await account.deriveXKey(use);
let addressIndex = 0;
let key = await xkey.deriveAddress(addressIndex);
// { ...,
// privateKey: privBytes, publicKey: pubBytes }
```
From an `xprv`:
```js
let xkey = await account.fromXKey(xprv);
let addressIndex = 0;
let key = await xkey.deriveAddress(addressIndex);
// { ...,
// privateKey: privBytes, publicKey: pubBytes }
```
From an `xpub`:
```js
let xkey = await account.fromXKey(xprv);
let addressIndex = 0;
let key = await xkey.deriveAddress(addressIndex);
// { ...,
// privateKey: null, publicKey: pubBytes }
```
### Key (depth 5)
The base _HD Key_ type, but with no additional methods.
A fully-derived BIP-44 Address (non-hardened).
```json5
{ ...,
privateKey: privBytes, publicKey: pubBytes }
```
From a Wallet:
```js
let accountIndex = 0;
let account = await wallet.deriveAccount(accountIndex);
let use = DashHd.RECEIVE;
let xkey = await account.deriveXKey(use);
let addressIndex = 0;
let key = await xkey.deriveAddress(addressIndex);
```
From an XPrv:
```js
let xkey = await account.fromXKey(xprv);
let addressIndex = 0;
let key = await xkey.deriveAddress(addressIndex);
// { ...,
// privateKey: privBytes, publicKey: pubBytes }
```
From an XPub:
```js
let xkey = await account.fromXKey(xpub);
let addressIndex = 0;
let key = await xkey.deriveAddress(addressIndex);
// { ...,
// privateKey: null, publicKey: pubBytes }
```
### HDKey
A generic HD Key at any depth.
```json5
{
versions: DashHd.MAINNET,
depth: 0,
parentFingerprint: 0, // should be set if depth is non-zero
index: 0,
chainCode: chainBytes, // required
privateKey: privOrNull, // required (or null)
publicKey: pubBytes, // required
}
```
The same structure as [Key](#key), but documented separately - because BIP-32
doesn't define semantic differences between HD Keys at different depths (other
than the root).
# Walkthrough
This will focus on the **most typical** use case, where you intend to generate
**multiple addresses** as part of your application's lifecycle.
## Part 1: Passphrase, Secret, Seed
The Passphrase (or Seed), **is** the Wallet.
- A _Wallet_ is derived from a _Seed_.
- A _Seed_ is typically derived from a _Passphrase Mnemonic_ and _Secret Salt_.
From a code perspective:
1. If your user doesn't supply a _Passphrase Mnemonic_, you can generate one:
```js
let targetBitEntropy = 128;
let wordList = await DashPhrase.generate(targetBitEntropy);
// "cat swing flag economy stadium alone churn speed unique patch report train"
```
2. Typically the _Secret Salt_ is left as an **empty string**:
```js
let secretSalt = "";
```
3. HOWEVER, for this demo we'll use the _Zoomonic_ and _Zecret_ \
(these values are specified by BIP-39's test suite for demos, debugging, etc)
```js
let wordList = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong";
let secretSalt = "TREZOR";
```
4. _Key Expansion_ derives the _Seed_ from the _Passphrase_ + _Secret_ \
(it's a specific configuration of PBKDF2 under the hood)
```js
let seedBytes = await DashPhrase.toSeed(wordList, secretSalt);
```
Prompt the user **to make a backup** of their _Passphrase_. \
(or their _Seed_, if you're not implementing *Passphrase*s)
It's common to print this out and put it in a safe.
If the **_Passphrase_ is lost**, the Wallet (and all money) is
**unrecoverable**.
## Part 2: The Wallet Derivation
As mentioned in the API section, it is, in fact, possible for any derivation to
fail.
It's highly unlikely that you'll ever encounter it, but it should be handled
nonetheless.
1. Generate a _Wallet_ Key \
(uses an HMAC-style Key Expansion, defined in BIP-32 )
```js
let wallet;
try {
wallet = await DashHd.fromSeed(seed);
} catch (e) {
window.alert("the passphrass (or seed) could not be used to derive keys");
}
```
2. Notify the user and retry a different Passphrase on failure.
### Part 2a: HD Path Derivation
As a **one-off**, HD Path Derivation can be very convenient:
Note: this approach would **5x slower** for deriving multiple keys because each
key will derive from the Root Wallet Key each time.
1. Define the target HD Path indexes to Depth 4 (_Use_ / _X Key_)
```js
let accountIndex = 0;
let use = DashHd.RECEIVE;
let addressIndex = 0;
let maxTries = 3;
let hdPartial = `m/44'/5'/${accountIndex}'/${use}`;
```
2. Derive the Address Key (Depth 5)
```js
let key;
for (let i = addressIndex; i < maxTries; i += 1) {
try {
let hdpath = `${hdPartial}/${addressIndex}`;
key = DashHd.derivePath(wallet, hdpath); // as defined above
break;
} catch (e) {
// ignore
}
}
if (!key) {
// more than 1 failure in a row would indicate
// the accountIndex or use index could not be derived
// (and hence no addressIndex will ever derive)
throw new Error(
`'${hdPartial}': 'account' or 'use' index cannot be derived`,
);
}
```
3. Mark the Account index as invalid and advance to the next on failure. \
(or fail hard if it's the first account)
### Part 2b: _Wallet_, _Account_, _X Key_
This is the more **typical** and **efficient** use - for when you intend to
generate **multiple addresses** as part of your application's lifecycle.
1. Derive an Account Key and X Key \
(reject the seed if the account at index 0 fails)
```js
let accountIndex = 0;
let account;
let use = DashHd.RECEIVE; // 0 = receive, 1 = change
let xkey;
while (!account) {
try {
account = await wallet.deriveAccount(accountIndex);
xkey = await account.deriveXKey(use);
break;
} catch (e) {
accountIndex += 1;
// if your app handles multiple accounts, just try the next
}
}
```
Note: technically you could advance the Use index, \
but that's more complicated than just advancing to the next account
2. (optional) Encode the _X Key_ as XPrv or XPub for sharing
```js
let xprv = await DashHd.toXPrv(xkey); // "xprv......"
let xpub = await DashHd.toXPub(xkey); // "xpub......"
```
## Part 3: _Address Key_
This is final piece, which you use for making and receiving payments.
1. Derive an Address Key
```js
let index = 0;
let maxTries = 3;
let last = index + maxTries;
let key;
for (let i = index; i < last; i += 1) {
try {
key = await xkey.deriveAddress(index);
} catch (e) {
// you may wish to mark the index as failed
}
}
```
2. Encode the Address Key as WIF or Address for use or sharing
```js
let wif = DashKeys.toWif(keys.privateKey); // "X....."
let addr = DashKeys.toAddr(keys.publicKey); // "X..."
```
# Glossary
See also [Dash Tools Glossary](https://github.com/dashhive/dash-tools#glossary).
- [Base2048](#base2048)
- [Base58Check](#base58Check)
- [BIPs](#bip)
- [BIP-32](#bip-32)
- [BIP-39](#bip-39)
- [BIP-43](#bip-43)
- [BIP-44](#bip-44)
- [Curve](#curve)
- [Derive (by Path)](#derive-by-path)
- [Derived Child Key](#derived-child)
- [Key Expansion](#key-expansion)
- [HD Account](#hd-account)
- [HD Address Key](#hd-address-key)
- [HD Keys](#hd-keys)
- [HD Passphrase Mnemonic](#hd-passphrase-mnemonic)
- [HD Path](#hd-path)
- [HD Wallet](#hd-wallet)
- [HD X Key](#hd-x-key)
- [Root Seed](#root-seed)
- [Root Key](#root-key)
- [Secp256k1](#secp256k1)
- [Test Vectors](#test-vectors)
- [XPrv](#xprv)
- [XPub](#xpub)
- [Zecret](#zecret)
- [Zeed](#zeed)
- [Zoomonic](#zoomonic)
## Base2048
Also: Base2048, _BIP39_, _BIP-0039_
Rather than a bank of 2, 16, 32, 58, 62, or 64 characters, \
you can encode data using a bank of whole words. \
If you use 2048 words, each word represents 11 _bits_. \
12 words represent 131 _bits_ of information. \
Any extra bits are used for checksumming the data. \
See [_HD Passphrase Mnemonic_](#hd-passphrase-mnemonic).
## Base58Check
The encoding format used for sharing _XPrv_ and _XPub_ Keys (_X Keys_). \
(among other things, such as _WIF_ and _Address_)
```text
xprvA2L7qar7dyJNhxnE47gK5J6cc1oEHQuAk8WrZLnLeHTtnkeyP4w6Eo6Tt65trtdkTRtx8opazGnLbpWrkhzNaL6ZsgG3sQmc2yS8AxoMjfZ
```
```text
xpub6FKUF6P1ULrfvSrhA9DKSS3MA3digsd27MSTMjBxCczsfYz7vcFLnbQwjP9CsAfEJsnD4UwtbU43iZaibv4vnzQNZmQAVcufN4r3pva8kTz
```
## BIP
Also: BIPs
Bitcoin Improvement Proposal(s). \
Specification Drafts / RFCs (Request For Comments).
## BIP-32
See [_HD Keys_](#hd-keys).
## BIP-39
Also: Base2048, _BIP39_, _BIP-0039_
BIP for [_HD Passphrase Mnemonic_](#hd-passphrase-mnemonic).
## BIP-43
BIP for the _Purpose_ index of the _HD Path_.
```js
`m/${purpose}'`;
```
This is the basis of [BIP-44][#bip-44] defining HD Paths as `m/44'/`.
See [_HD Keys_](#hd-keys).
## BIP-44
See [_HD Path_](#hd-path).
## Curve
Related to parameters of Elliptic Curve (ECDSA) cryptography / algorithms.
A single X value produces two Y values on a curve (rather than 1 on a line).
In rare instances, an X value may produce **no points** on the curve.
## Derive (by Path)
To split an HD Path by `/` and then iterate to derive each index (_Child_) in
turn.
**Cannot be reversed**.
See [`derivePath(hdkey, hdpath)`][#derivePath-hdkey-hdpath].
## Derived Child
A key directly derived from another key by an _HD Path_ index. \
(typically referring to a single index of the path, not the whole)
See
[`deriveChild(hdkey, index, isHardened)`][#derivePath-hdkey-index-ishardened].
## Key Expansion
An algorithm that creates a larger (byte-size) output than its input. \
Typically uses hashing algos: HMAC, SHA-2, SHA-3, etc. \
May combine multiple algos together. \
Usually intentionally slow. \
May run a high number of "Rounds" in succession. \
(typically hundreds or thousands).
_Passhrase Mnemonics_ to _Seed_ (BIP-39) uses _PBKDF2_. \
_HD Keys_ (BIP-44) use HMAC and *Secp256k1 Tweak*ing for each index.
See also:
- `DashPhrase.toSeed(wordList)`
- `DashHd.fromSeed(seedBytes)`
- `DashHd.deriveChild(hdkey, index, isHardened)`
## HD Account
An HD Key derived at `m/44'/5'/n'` (Depth 3) of the HD Path.
See [API: Key Types](#key-types).
## HD Address Key
Also: _Key_, _HD Private Key_, _WIF_, _Address_
An HD Key at final depth `m/44'/5'/0'/0/0` (Depth 5) of an _HD Path_. \
Can be encoded as _WIF_ or _Address_ for making or receiving payments.
See also [API: Key Types](#key-types).
## HD Keys
Also: _Hierarchical Deterministic Keys_, _BIP-32_, _BIP-44_
Any of generic or purpose-specific keys derived deterministically form a seed.
See more at [API: Key Types](#key-types) (code above) and [HD Path](#hd-path).
## HD Passphrase Mnemonic
Also: _Mnemonic for Generating Hierarchical Deterministic Keys_, _HD Wallet_,
_BIP-39_
12 words used to derive an HD Seed. \
(11¾ for entropy, ¼ for checksum)
Ex: `zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong`
Not used _directly_ in this library, but...\
it _is_ how the HD Seeds used here are typically generated.
See [DashPhrase.js](dash-phrase).
## HD Path
The path that defines an HD Key - typically of the BIP-44 variety:
- a _Root_, ex: `m` (depth 0, the wallet, straight from the seed)
- an _Coin Key_, ex: `m/44'/5'` (depth 2, sometimes called Wallet)
- an _Account_, ex: `m/44'/5'/0'` (depth 3)
- an _X Key_, ex: `m/44'/5'/0'/0` (depth 4, also the Use)
- an _Address Key_, ex: `m/44'/5'/0'/0/0` (depth 5, the end)
In general:
```js
let hdpath = `m/${purpose}'/${coinType}'/${account}'/${use}/${index}`;
```
For DASH:
```js
let hdpath = `m/44'/5'/${account}'/${use}/${index}`;
```
See also [API: Key Types](#key-types) (code above).
## HD Wallet
Either the _Root Key_ at `m` (Depth 0), directly from the _Seed_, \
or the _Coin Key_ at `m/44'/5'` (Depth 2), of the _HD Path_. \
Sometimes also used to mean _HD Account_ at `m/44'/5'/n'`.
Here we typically use it to mean the _Root Key_. \
(because we're focus on DASH more so than other coins)
See also [API: Key Types](#key-types).
## HD X Key
Also: _XKey_, _XPrv_, _XPub_, _Use Key_, _Use Index_, _Extended Key_.
An HD Key derived at `m/44'/5'/0'/n` (Depth 4), of the _HD Path_.
Here we typically use it to mean the _Root Key_. \
(because we're focus on DASH more so than other coins)
See also [API: Key Types](#key-types).
## Root Seed
Also: Master Seed, Seed, HD Seed
Either:
- 64 random bytes
- a 64-byte hash derived from a _Passphrase Mnemonic_
**Cannot be reversed**.
## Root Key
Also: _HD Wallet_, _Master Key_, _HD Master_
An HD Key of `m` (Depth 0), as derived directly from the Seed.
See also [API: Key Types](#key-types).
## Secp256k1
A specific set of parameters "the curve" used by most cryptocurrencies.
See [Curve](#curve).
## Test Vectors
The well-known values used for testing, demos, debugging, and development:
- DashPhrase / BIP-39:
- <https://github.com/trezor/python-mnemonic/blob/master/vectors.json>
- Includes the [_Zoomonic_](#zoomonic), [_Zecret_](#zecret), and
[_Zeed_](#zeed).
- Generic HD Key / BIP-32:
- <https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#test-vectors>
- DashKeys / BIP-44:
- [Zoomonic](#zoomonic)
## XPrv
Also: _Extended Private Key_, _XPriv_, _X Prv_, _X Priv_
Specifically the Base58Check-encoded form of an HD Key at Depth 4. \
(the _X Key_, a.k.a. _Use Key_, including the _Private Key_)\_ \
Can be used to derive any number of *WIF*s and *Address*es.
```text
xprvA2L7qar7dyJNhxnE47gK5J6cc1oEHQuAk8WrZLnLeHTtnkeyP4w6Eo6Tt65trtdkTRtx8opazGnLbpWrkhzNaL6ZsgG3sQmc2yS8AxoMjfZ
```
See [HD X Key](#hd-x-key).
## XPub
Also: _Extended Pubilc Key_, _X Pub_
Specifically the Base58Check-encoded form of an HD Key. \
(just the public key) Can be used to derive any number of receiving *Address*es.
```text
xpub6FKUF6P1ULrfvSrhA9DKSS3MA3digsd27MSTMjBxCczsfYz7vcFLnbQwjP9CsAfEJsnD4UwtbU43iZaibv4vnzQNZmQAVcufN4r3pva8kTz
```
See [XPrv](#xprv), [HD X Key](#hd-x-key).
## Zecret
The _Secret Salt_ used for the BIP-32 Test Vectors.
```text
TREZOR
```
```js
let secretSalt = "TREZOR";
```
Comes from the fact that the company Trezor (a hardware wallet) was involved in
creating the reference implementation and Test Vectors.
## Zeed
The canonical Seed (generated from the Zoomonic salted with "TREZOR"), \
to be used in documentation, examples, and test fixtures.
```txt
(account 0, external/receiving, address 0)
m/44'/5'/0'/0/0: XKHiWYkmDkNnWGP756UCGcuZ21mHGeYdWeCBBHCBGZaf3NYw1SAz (WIF)
XjxyR1gve94LuKqkMLEeqJbEVM5B5q1ZSx (Addr)
m/44'/5'/0'/0/1: XCsy8Qw1fLH7C1UxLjBfTfLpn8DMRK1TMNNE2a5J1F4TyE5UApcK
XxRrwh1xBWig9rfLyiy494u2vj6YXQMsH7
ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a13332572917f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069
```
(account 2, internal/change, address 2)
m/44'/5'/2'/1/2: XBwqVpx9SLtvoscmLgC2AtXoKZi5FxYKtYbPGTyjzsKBxsfAxrmy (WIF)
XhWFxtNSqwTqLYAQ9XQJbfQG3Hj64qLoGt (Addr)
## Zoomonic
```txt
Passphrase (Mnemonic) : zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong
Secret (Salt Password) : TREZOR
Seed : ac27495480225222079d7be181583751e86f571027b0497b5b5d11218e0a8a13332572917f0f8e5a589620c6f15b11c61dee327651a14c34e18231052e48c069
```
**Misnomer Alert**: The so-called "secret" is actually a pbkdf2 _salt_, yet it's
sometimes also referred to as a "passphrase" or "password"... oh well 🤷‍♂️.
# References
## More Fixtures
- https://github.com/dashhive/dash-tools
- https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/hdnode.js
- http://bip32.org/
- http://blog.richardkiss.com/?p=313
- https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
- http://bitcoinmagazine.com/8396/deterministic-wallets-advantages-flaw/
See [FIXTURES.md](./FIXTURES.md).
# License
Copyright © 2023 Dash Incubator \
Copyright © 2023 AJ ONeal \
Copyright © 2018-2022 cryptocoinjs
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