@opcat-labs/opcat 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cjs2esm.json +18 -0
- package/.mocharc.yaml +1 -1
- package/CHANGELOG.md +13 -0
- package/README.md +6 -0
- package/{lib/address.js → cjs/address.cjs} +77 -72
- package/cjs/block/block.cjs +332 -0
- package/{lib/block/blockheader.js → cjs/block/blockheader.cjs} +8 -7
- package/cjs/block/index.cjs +2 -0
- package/{lib/block/merkleblock.js → cjs/block/merkleblock.cjs} +23 -15
- package/cjs/bn.cjs +3411 -0
- package/{lib/crypto/bn.js → cjs/crypto/bn.cjs} +3 -3
- package/{lib/crypto/ecdsa.js → cjs/crypto/ecdsa.cjs} +150 -14
- package/{lib/crypto/hash.node.js → cjs/crypto/hash.cjs} +13 -2
- package/cjs/crypto/index.cjs +16 -0
- package/{lib/crypto/point.js → cjs/crypto/point.cjs} +11 -4
- package/cjs/crypto/random.cjs +18 -0
- package/{lib/crypto/signature.js → cjs/crypto/signature.cjs} +158 -8
- package/{lib/encoding/base58.js → cjs/encoding/base58.cjs} +58 -2
- package/cjs/encoding/base58check.cjs +192 -0
- package/cjs/encoding/bufferreader.cjs +333 -0
- package/cjs/encoding/bufferwriter.cjs +244 -0
- package/{lib/encoding/decode-asm.js → cjs/encoding/decode-asm.cjs} +4 -4
- package/{lib/encoding/decode-hex.js → cjs/encoding/decode-hex.cjs} +1 -1
- package/cjs/encoding/index.cjs +14 -0
- package/cjs/encoding/varint.cjs +116 -0
- package/{lib/errors/index.js → cjs/errors/index.cjs} +9 -9
- package/{lib/errors/spec.js → cjs/errors/spec.cjs} +2 -2
- package/cjs/hash-cache.cjs +98 -0
- package/{lib/hdprivatekey.js → cjs/hdprivatekey.cjs} +232 -140
- package/{lib/hdpublickey.js → cjs/hdpublickey.cjs} +120 -93
- package/cjs/index.cjs +94 -0
- package/cjs/interpreter/index.cjs +2 -0
- package/cjs/interpreter/interpreter.cjs +1988 -0
- package/{lib/script/stack.js → cjs/interpreter/stack.cjs} +9 -2
- package/{lib/message/message.js → cjs/message/message.cjs} +62 -25
- package/cjs/mnemonic/index.cjs +3 -0
- package/{lib/mnemonic/mnemonic.js → cjs/mnemonic/mnemonic.cjs} +44 -13
- package/{lib/mnemonic/pbkdf2.node.js → cjs/mnemonic/pbkdf2.cjs} +9 -2
- package/cjs/mnemonic/words/index.cjs +66 -0
- package/cjs/network.cjs +13 -0
- package/cjs/networks.cjs +321 -0
- package/{lib/opcode.js → cjs/opcode.cjs} +69 -5
- package/cjs/privatekey.cjs +422 -0
- package/{lib/publickey.js → cjs/publickey.cjs} +14 -16
- package/cjs/script/index.cjs +2 -0
- package/{lib/script/script.js → cjs/script/script.cjs} +322 -67
- package/cjs/transaction/index.cjs +5 -0
- package/cjs/transaction/input/index.cjs +34 -0
- package/cjs/transaction/input/input.cjs +396 -0
- package/{lib/transaction/input/multisig.js → cjs/transaction/input/multisig.cjs} +112 -18
- package/{lib/transaction/input/publickey.js → cjs/transaction/input/publickey.cjs} +29 -19
- package/{lib/transaction/input/publickeyhash.js → cjs/transaction/input/publickeyhash.cjs} +25 -17
- package/{lib/transaction/output.js → cjs/transaction/output.cjs} +100 -15
- package/cjs/transaction/sighash.cjs +187 -0
- package/{lib/transaction/signature.js → cjs/transaction/signature.cjs} +30 -6
- package/cjs/transaction/transaction.cjs +2000 -0
- package/{lib/transaction/unspentoutput.js → cjs/transaction/unspentoutput.cjs} +5 -5
- package/cjs/util/derivation.cjs +53 -0
- package/cjs/util/index.cjs +11 -0
- package/cjs/util/js.cjs +95 -0
- package/{lib/util/preconditions.js → cjs/util/preconditions.cjs} +2 -2
- package/esm/address.js +483 -0
- package/{lib → esm}/block/block.js +82 -27
- package/esm/block/blockheader.js +296 -0
- package/esm/block/index.js +2 -0
- package/esm/block/merkleblock.js +331 -0
- package/esm/bn.js +3411 -0
- package/esm/crypto/bn.js +278 -0
- package/esm/crypto/ecdsa.js +475 -0
- package/{lib/crypto/hash.browser.js → esm/crypto/hash.js} +18 -7
- package/esm/crypto/index.js +16 -0
- package/esm/crypto/point.js +228 -0
- package/esm/crypto/random.js +18 -0
- package/esm/crypto/signature.js +475 -0
- package/esm/encoding/base58.js +167 -0
- package/esm/encoding/base58check.js +192 -0
- package/esm/encoding/bufferreader.js +333 -0
- package/esm/encoding/bufferwriter.js +243 -0
- package/esm/encoding/decode-asm.js +24 -0
- package/esm/encoding/decode-hex.js +32 -0
- package/esm/encoding/decode-script-chunks.js +43 -0
- package/esm/encoding/encode-hex.js +284 -0
- package/esm/encoding/index.js +14 -0
- package/esm/encoding/is-hex.js +7 -0
- package/esm/encoding/varint.js +116 -0
- package/esm/errors/index.js +54 -0
- package/esm/errors/spec.js +314 -0
- package/esm/hash-cache.js +98 -0
- package/esm/hdprivatekey.js +768 -0
- package/esm/hdpublickey.js +549 -0
- package/esm/index.js +66 -0
- package/esm/interpreter/index.js +2 -0
- package/{lib/script → esm/interpreter}/interpreter.js +219 -66
- package/esm/interpreter/stack.js +116 -0
- package/esm/message/message.js +228 -0
- package/esm/mnemonic/index.js +3 -0
- package/esm/mnemonic/mnemonic.js +332 -0
- package/{lib/mnemonic/pbkdf2.browser.js → esm/mnemonic/pbkdf2.js} +13 -6
- package/esm/mnemonic/words/chinese.js +2054 -0
- package/esm/mnemonic/words/english.js +2054 -0
- package/esm/mnemonic/words/french.js +2054 -0
- package/esm/mnemonic/words/index.js +66 -0
- package/esm/mnemonic/words/italian.js +2054 -0
- package/esm/mnemonic/words/japanese.js +2054 -0
- package/esm/mnemonic/words/spanish.js +2054 -0
- package/esm/network.js +13 -0
- package/{lib → esm}/networks.js +61 -120
- package/esm/opcode.js +319 -0
- package/{lib → esm}/privatekey.js +76 -28
- package/esm/publickey.js +384 -0
- package/esm/script/index.js +2 -0
- package/esm/script/script.js +1329 -0
- package/esm/script/write-i32-le.js +17 -0
- package/esm/script/write-push-data.js +35 -0
- package/esm/script/write-u16-le.js +12 -0
- package/esm/script/write-u32-le.js +16 -0
- package/esm/script/write-u64-le.js +24 -0
- package/esm/script/write-u8-le.js +8 -0
- package/esm/script/write-varint.js +46 -0
- package/esm/transaction/index.js +5 -0
- package/esm/transaction/input/index.js +33 -0
- package/{lib → esm}/transaction/input/input.js +132 -90
- package/esm/transaction/input/multisig.js +335 -0
- package/esm/transaction/input/publickey.js +108 -0
- package/esm/transaction/input/publickeyhash.js +124 -0
- package/esm/transaction/output.js +316 -0
- package/{lib → esm}/transaction/sighash.js +42 -22
- package/esm/transaction/signature.js +120 -0
- package/{lib → esm}/transaction/transaction.js +522 -163
- package/esm/transaction/unspentoutput.js +112 -0
- package/esm/util/_.js +47 -0
- package/esm/util/derivation.js +53 -0
- package/esm/util/index.js +12 -0
- package/esm/util/js.js +95 -0
- package/esm/util/preconditions.js +33 -0
- package/fixup.cjs +17 -0
- package/package.json +40 -26
- package/test/{address.js → address.cjs} +14 -43
- package/test/block/{block.js → block.cjs} +3 -5
- package/test/block/{blockheader.js → blockheader.cjs} +2 -2
- package/test/block/{merklebloack.js → merklebloack.cjs} +2 -2
- package/test/crypto/{ecdsa.js → ecdsa.cjs} +9 -9
- package/test/crypto/{hash.browser.js → hash.browser.cjs} +2 -1
- package/test/crypto/{signature.js → signature.cjs} +2 -2
- package/test/data/bitcoind/script_tests.json +5 -5
- package/test/{hashCache.js → hashCache.cjs} +2 -1
- package/test/{hdkeys.js → hdkeys.cjs} +4 -2
- package/test/{hdprivatekey.js → hdprivatekey.cjs} +7 -6
- package/test/{hdpublickey.js → hdpublickey.cjs} +2 -7
- package/test/mnemonic/{pbkdf2.test.js → pbkdf2.test.cjs} +2 -2
- package/test/{networks.js → networks.cjs} +12 -31
- package/test/{publickey.js → publickey.cjs} +2 -2
- package/test/script/{interpreter.js → interpreter.cjs} +5 -5
- package/test/script/{script.js → script.cjs} +8 -2
- package/test/transaction/{deserialize.js → deserialize.cjs} +2 -2
- package/test/transaction/input/{input.js → input.cjs} +1 -1
- package/test/transaction/input/{multisig.js → multisig.cjs} +2 -1
- package/test/transaction/input/{publickeyhash.js → publickeyhash.cjs} +1 -1
- package/test/transaction/{sighash.js → sighash.cjs} +1 -1
- package/test/transaction/{transaction.js → transaction.cjs} +2 -2
- package/tsconfig.json +13 -0
- package/types/address.d.cts +252 -0
- package/types/block/block.d.cts +139 -0
- package/types/block/blockheader.d.cts +125 -0
- package/types/block/index.d.cts +2 -0
- package/types/block/merkleblock.d.cts +95 -0
- package/types/bn.d.cts +202 -0
- package/types/crypto/bn.d.cts +2 -0
- package/types/crypto/ecdsa.d.cts +187 -0
- package/types/crypto/hash.d.cts +118 -0
- package/types/crypto/index.d.cts +7 -0
- package/types/crypto/point.d.cts +134 -0
- package/types/crypto/random.d.cts +13 -0
- package/types/crypto/signature.d.cts +160 -0
- package/types/encoding/base58.d.cts +106 -0
- package/types/encoding/base58check.d.cts +107 -0
- package/types/encoding/bufferreader.d.cts +164 -0
- package/types/encoding/bufferwriter.d.cts +126 -0
- package/types/encoding/decode-asm.d.cts +2 -0
- package/types/encoding/decode-hex.d.cts +2 -0
- package/types/encoding/decode-script-chunks.d.cts +14 -0
- package/types/encoding/encode-hex.d.cts +2 -0
- package/types/encoding/index.d.cts +6 -0
- package/types/encoding/is-hex.d.cts +2 -0
- package/types/encoding/varint.d.cts +66 -0
- package/types/errors/index.d.cts +4 -0
- package/types/errors/spec.d.cts +22 -0
- package/types/hash-cache.d.cts +65 -0
- package/types/hdprivatekey.d.cts +281 -0
- package/types/hdpublickey.d.cts +240 -0
- package/types/index.d.cts +26 -0
- package/types/interpreter/index.d.cts +2 -0
- package/types/interpreter/interpreter.d.cts +228 -0
- package/types/interpreter/stack.d.cts +35 -0
- package/types/message/message.d.cts +110 -0
- package/types/mnemonic/index.d.cts +2 -0
- package/types/mnemonic/mnemonic.d.cts +171 -0
- package/types/mnemonic/pbkdf2.d.cts +14 -0
- package/types/mnemonic/words/chinese.d.cts +2 -0
- package/types/mnemonic/words/english.d.cts +2 -0
- package/types/mnemonic/words/french.d.cts +2 -0
- package/types/mnemonic/words/index.d.cts +22 -0
- package/types/mnemonic/words/italian.d.cts +2 -0
- package/types/mnemonic/words/japanese.d.cts +2 -0
- package/types/mnemonic/words/spanish.d.cts +2 -0
- package/types/network.d.cts +11 -0
- package/types/networks.d.cts +76 -0
- package/types/opcode.d.cts +93 -0
- package/types/privatekey.d.cts +169 -0
- package/types/publickey.d.cts +202 -0
- package/types/script/index.d.cts +2 -0
- package/types/script/script.d.cts +449 -0
- package/types/script/write-i32-le.d.cts +2 -0
- package/types/script/write-push-data.d.cts +2 -0
- package/types/script/write-u16-le.d.cts +2 -0
- package/types/script/write-u32-le.d.cts +2 -0
- package/types/script/write-u64-le.d.cts +2 -0
- package/types/script/write-u8-le.d.cts +2 -0
- package/types/script/write-varint.d.cts +2 -0
- package/types/transaction/index.d.cts +2 -0
- package/types/transaction/input/index.d.cts +2 -0
- package/types/transaction/input/input.d.cts +178 -0
- package/types/transaction/input/multisig.d.cts +127 -0
- package/types/transaction/input/publickey.d.cts +44 -0
- package/types/transaction/input/publickeyhash.d.cts +45 -0
- package/types/transaction/output.d.cts +118 -0
- package/types/transaction/sighash.d.cts +61 -0
- package/types/transaction/signature.d.cts +43 -0
- package/types/transaction/transaction.d.cts +716 -0
- package/types/transaction/unspentoutput.d.cts +83 -0
- package/types/util/_.d.cts +26 -0
- package/types/util/derivation.d.cts +21 -0
- package/types/util/index.d.cts +5 -0
- package/types/util/js.d.cts +50 -0
- package/types/util/preconditions.d.cts +3 -0
- package/index.d.ts +0 -1541
- package/index.js +0 -74
- package/lib/block/index.js +0 -4
- package/lib/bn.js +0 -3423
- package/lib/crypto/hash.js +0 -2
- package/lib/crypto/random.browser.js +0 -28
- package/lib/crypto/random.js +0 -2
- package/lib/crypto/random.node.js +0 -11
- package/lib/encoding/base58check.js +0 -121
- package/lib/encoding/bufferreader.js +0 -212
- package/lib/encoding/bufferwriter.js +0 -140
- package/lib/encoding/varint.js +0 -75
- package/lib/hash-cache.js +0 -50
- package/lib/mnemonic/pbkdf2.js +0 -2
- package/lib/mnemonic/words/index.js +0 -8
- package/lib/script/index.js +0 -5
- package/lib/transaction/index.js +0 -7
- package/lib/transaction/input/index.js +0 -5
- package/lib/util/js.js +0 -90
- /package/{lib/encoding/decode-script-chunks.js → cjs/encoding/decode-script-chunks.cjs} +0 -0
- /package/{lib/encoding/encode-hex.js → cjs/encoding/encode-hex.cjs} +0 -0
- /package/{lib/encoding/is-hex.js → cjs/encoding/is-hex.cjs} +0 -0
- /package/{lib/mnemonic/words/chinese.js → cjs/mnemonic/words/chinese.cjs} +0 -0
- /package/{lib/mnemonic/words/english.js → cjs/mnemonic/words/english.cjs} +0 -0
- /package/{lib/mnemonic/words/french.js → cjs/mnemonic/words/french.cjs} +0 -0
- /package/{lib/mnemonic/words/italian.js → cjs/mnemonic/words/italian.cjs} +0 -0
- /package/{lib/mnemonic/words/japanese.js → cjs/mnemonic/words/japanese.cjs} +0 -0
- /package/{lib/mnemonic/words/spanish.js → cjs/mnemonic/words/spanish.cjs} +0 -0
- /package/{lib/script/write-i32-le.js → cjs/script/write-i32-le.cjs} +0 -0
- /package/{lib/script/write-push-data.js → cjs/script/write-push-data.cjs} +0 -0
- /package/{lib/script/write-u16-le.js → cjs/script/write-u16-le.cjs} +0 -0
- /package/{lib/script/write-u32-le.js → cjs/script/write-u32-le.cjs} +0 -0
- /package/{lib/script/write-u64-le.js → cjs/script/write-u64-le.cjs} +0 -0
- /package/{lib/script/write-u8-le.js → cjs/script/write-u8-le.cjs} +0 -0
- /package/{lib/script/write-varint.js → cjs/script/write-varint.cjs} +0 -0
- /package/{lib/util/_.js → cjs/util/_.cjs} +0 -0
- /package/test/crypto/{bn.js → bn.cjs} +0 -0
- /package/test/crypto/{hash.js → hash.cjs} +0 -0
- /package/test/crypto/{point.js → point.cjs} +0 -0
- /package/test/crypto/{random.js → random.cjs} +0 -0
- /package/test/data/{blk86756-testnet.js → blk86756-testnet.cjs} +0 -0
- /package/test/data/{merkleblocks.js → merkleblocks.cjs} +0 -0
- /package/test/encoding/{base58.js → base58.cjs} +0 -0
- /package/test/encoding/{base58check.js → base58check.cjs} +0 -0
- /package/test/encoding/{bufferreader.js → bufferreader.cjs} +0 -0
- /package/test/encoding/{bufferwriter.js → bufferwriter.cjs} +0 -0
- /package/test/encoding/{varint.js → varint.cjs} +0 -0
- /package/test/{index.js → index.cjs} +0 -0
- /package/test/message/{message.js → message.cjs} +0 -0
- /package/test/mnemonic/{mnemonic.js → mnemonic.cjs} +0 -0
- /package/test/{opcode.js → opcode.cjs} +0 -0
- /package/test/{privatekey.js → privatekey.cjs} +0 -0
- /package/test/transaction/input/{publickey.js → publickey.cjs} +0 -0
- /package/test/transaction/{output.js → output.cjs} +0 -0
- /package/test/transaction/{signature.js → signature.cjs} +0 -0
- /package/test/transaction/{unspentoutput.js → unspentoutput.cjs} +0 -0
- /package/test/util/{js.js → js.cjs} +0 -0
- /package/test/util/{preconditions.js → preconditions.cjs} +0 -0
|
@@ -0,0 +1,768 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import assert from 'assert';
|
|
4
|
+
import _ from './util/_.js';
|
|
5
|
+
import $ from './util/preconditions.js';
|
|
6
|
+
import Derivation from './util/derivation.js';
|
|
7
|
+
import BN from './crypto/bn.js';
|
|
8
|
+
import Base58 from './encoding/base58.js';
|
|
9
|
+
import Base58Check from './encoding/base58check.js';
|
|
10
|
+
import Hash from './crypto/hash.js';
|
|
11
|
+
import Networks from './networks.js';
|
|
12
|
+
import Point from './crypto/point.js';
|
|
13
|
+
import PrivateKey from './privatekey.js';
|
|
14
|
+
import Random from './crypto/random.js';
|
|
15
|
+
import HDPublicKey from './hdpublickey.js';
|
|
16
|
+
import JSUtil from './util/js.js';
|
|
17
|
+
import errors from './errors/index.js';
|
|
18
|
+
|
|
19
|
+
var hdErrors = errors.HDPrivateKey;
|
|
20
|
+
|
|
21
|
+
var MINIMUM_ENTROPY_BITS = 128;
|
|
22
|
+
var BITS_TO_BYTES = 1 / 8;
|
|
23
|
+
var MAXIMUM_ENTROPY_BITS = 512;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Creates a new HDPrivateKey instance from various input formats.
|
|
27
|
+
* More info on https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
|
28
|
+
* @constructor
|
|
29
|
+
* @param {HDPrivateKey|string|Buffer|Object} arg - Input can be:
|
|
30
|
+
* - Existing HDPrivateKey instance (returns same instance)
|
|
31
|
+
* - Network name (generates random key for that network)
|
|
32
|
+
* - Serialized string/Buffer (base58 encoded)
|
|
33
|
+
* - JSON string
|
|
34
|
+
* - Object with key properties
|
|
35
|
+
* @throws {hdErrors.UnrecognizedArgument} If input format is not recognized
|
|
36
|
+
* @throws {Error} If serialized input is invalid
|
|
37
|
+
*/
|
|
38
|
+
function HDPrivateKey(arg) {
|
|
39
|
+
if (arg instanceof HDPrivateKey) {
|
|
40
|
+
return arg;
|
|
41
|
+
}
|
|
42
|
+
if (!(this instanceof HDPrivateKey)) {
|
|
43
|
+
return new HDPrivateKey(arg);
|
|
44
|
+
}
|
|
45
|
+
if (!arg) {
|
|
46
|
+
return this._generateRandomly();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (Networks.get(arg)) {
|
|
50
|
+
return this._generateRandomly(arg);
|
|
51
|
+
} else if (_.isString(arg) || Buffer.isBuffer(arg)) {
|
|
52
|
+
if (HDPrivateKey.isValidSerialized(arg)) {
|
|
53
|
+
this._buildFromSerialized(arg);
|
|
54
|
+
} else if (JSUtil.isValidJSON(arg)) {
|
|
55
|
+
this._buildFromJSON(arg);
|
|
56
|
+
} else if (Buffer.isBuffer(arg) && HDPrivateKey.isValidSerialized(arg.toString())) {
|
|
57
|
+
this._buildFromSerialized(arg.toString());
|
|
58
|
+
} else {
|
|
59
|
+
throw HDPrivateKey.getSerializedError(arg);
|
|
60
|
+
}
|
|
61
|
+
} else if (_.isObject(arg)) {
|
|
62
|
+
this._buildFromObject(arg);
|
|
63
|
+
} else {
|
|
64
|
+
throw new hdErrors.UnrecognizedArgument(arg);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Gets the hdPublicKey of the HDPrivateKey.
|
|
70
|
+
* @name HDPrivateKey.prototype.hdPublicKey
|
|
71
|
+
* @type {HDPublicKey}
|
|
72
|
+
* @memberof HDPrivateKey
|
|
73
|
+
*/
|
|
74
|
+
Object.defineProperty(HDPrivateKey.prototype, 'hdPublicKey', {
|
|
75
|
+
configurable: false,
|
|
76
|
+
enumerable: true,
|
|
77
|
+
get: function () {
|
|
78
|
+
this._calcHDPublicKey();
|
|
79
|
+
return this._hdPublicKey;
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Gets the xpubkey of the HDPrivateKey.
|
|
85
|
+
* @name HDPrivateKey.prototype.xpubkey
|
|
86
|
+
* @type {string}
|
|
87
|
+
* @memberof HDPrivateKey
|
|
88
|
+
*/
|
|
89
|
+
Object.defineProperty(HDPrivateKey.prototype, 'xpubkey', {
|
|
90
|
+
configurable: false,
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
this._calcHDPublicKey();
|
|
94
|
+
return this._hdPublicKey.xpubkey;
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Creates a new HDPrivateKey instance with random values.
|
|
101
|
+
* @returns {HDPrivateKey} A new HDPrivateKey object with randomly generated properties.
|
|
102
|
+
*/
|
|
103
|
+
HDPrivateKey.fromRandom = function () {
|
|
104
|
+
return new HDPrivateKey();
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Verifies that a given path is valid.
|
|
109
|
+
*
|
|
110
|
+
* @param {string|number} arg
|
|
111
|
+
* @param {boolean} [hardened]
|
|
112
|
+
* @return {boolean}
|
|
113
|
+
*/
|
|
114
|
+
HDPrivateKey.isValidPath = function (arg, hardened) {
|
|
115
|
+
if (_.isString(arg)) {
|
|
116
|
+
var indexes = Derivation.getDerivationIndexes(arg);
|
|
117
|
+
return indexes !== null && _.every(indexes, HDPrivateKey.isValidPath);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (_.isNumber(arg)) {
|
|
121
|
+
if (arg < HDPrivateKey.Hardened && hardened === true) {
|
|
122
|
+
arg += HDPrivateKey.Hardened;
|
|
123
|
+
}
|
|
124
|
+
return arg >= 0 && arg < HDPrivateKey.MaxIndex;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return false;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* WARNING: This method will not be officially supported until v1.0.0.
|
|
134
|
+
*
|
|
135
|
+
*
|
|
136
|
+
* Get a derived child based on a string or number.
|
|
137
|
+
*
|
|
138
|
+
* If the first argument is a string, it's parsed as the full path of
|
|
139
|
+
* derivation. Valid values for this argument include "m" (which returns the
|
|
140
|
+
* same private key), "m/0/1/40/2'/1000", where the ' quote means a hardened
|
|
141
|
+
* derivation.
|
|
142
|
+
*
|
|
143
|
+
* If the first argument is a number, the child with that index will be
|
|
144
|
+
* derived. If the second argument is truthy, the hardened version will be
|
|
145
|
+
* derived. See the example usage for clarification.
|
|
146
|
+
*
|
|
147
|
+
* WARNING: The `nonCompliant` option should NOT be used, except for older implementation
|
|
148
|
+
* that used a derivation strategy that used a non-zero padded private key.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```javascript
|
|
152
|
+
* var parent = new HDPrivateKey('xprv...');
|
|
153
|
+
* var child_0_1_2h = parent.deriveChild(0).deriveChild(1).deriveChild(2, true);
|
|
154
|
+
* var copy_of_child_0_1_2h = parent.deriveChild("m/0/1/2'");
|
|
155
|
+
* assert(child_0_1_2h.xprivkey === copy_of_child_0_1_2h);
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* @param {string|number} arg
|
|
159
|
+
* @param {boolean} [hardened]
|
|
160
|
+
*/
|
|
161
|
+
HDPrivateKey.prototype.deriveChild = function (arg, hardened) {
|
|
162
|
+
if (_.isNumber(arg)) {
|
|
163
|
+
return this._deriveWithNumber(arg, hardened);
|
|
164
|
+
} else if (_.isString(arg)) {
|
|
165
|
+
return this._deriveFromString(arg);
|
|
166
|
+
} else {
|
|
167
|
+
throw new hdErrors.InvalidDerivationArgument(arg);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* WARNING: This method will not be officially supported until v1.0.0
|
|
173
|
+
*
|
|
174
|
+
*
|
|
175
|
+
* WARNING: If this is a new implementation you should NOT use this method, you should be using
|
|
176
|
+
* `derive` instead.
|
|
177
|
+
*
|
|
178
|
+
* This method is explicitly for use and compatibility with an implementation that
|
|
179
|
+
* was not compliant with BIP32 regarding the derivation algorithm. The private key
|
|
180
|
+
* must be 32 bytes hashing, and this implementation will use the non-zero padded
|
|
181
|
+
* serialization of a private key, such that it's still possible to derive the privateKey
|
|
182
|
+
* to recover those funds.
|
|
183
|
+
*
|
|
184
|
+
* @param {number|string} arg - Either a child index number or derivation path string
|
|
185
|
+
* @param {boolean} [hardened] - Whether to create hardened derivation (only used with number arg)
|
|
186
|
+
* @returns {HDPrivateKey} The derived child private key
|
|
187
|
+
* @throws {hdErrors.InvalidDerivationArgument} If argument type is invalid
|
|
188
|
+
*/
|
|
189
|
+
HDPrivateKey.prototype.deriveNonCompliantChild = function (arg, hardened) {
|
|
190
|
+
if (_.isNumber(arg)) {
|
|
191
|
+
return this._deriveWithNumber(arg, hardened, true);
|
|
192
|
+
} else if (_.isString(arg)) {
|
|
193
|
+
return this._deriveFromString(arg, true);
|
|
194
|
+
} else {
|
|
195
|
+
throw new hdErrors.InvalidDerivationArgument(arg);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Derives a child HDPrivateKey from the current key using the specified index.
|
|
201
|
+
* Handles both hardened and non-hardened derivation according to BIP32.
|
|
202
|
+
*
|
|
203
|
+
* @param {number} index - The child index to derive
|
|
204
|
+
* @param {boolean} [hardened] - Whether to use hardened derivation
|
|
205
|
+
* @param {boolean} [nonCompliant=false] - If true, uses non-zero-padded private key serialization
|
|
206
|
+
* @returns {HDPrivateKey} The derived child private key
|
|
207
|
+
* @throws {hdErrors.InvalidPath} If the derivation path is invalid
|
|
208
|
+
* @private
|
|
209
|
+
*/
|
|
210
|
+
HDPrivateKey.prototype._deriveWithNumber = function (index, hardened, nonCompliant) {
|
|
211
|
+
if (!HDPrivateKey.isValidPath(index, hardened)) {
|
|
212
|
+
throw new hdErrors.InvalidPath(index);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
hardened = index >= HDPrivateKey.Hardened ? true : hardened;
|
|
216
|
+
if (index < HDPrivateKey.Hardened && hardened === true) {
|
|
217
|
+
index += HDPrivateKey.Hardened;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
var indexBuffer = JSUtil.integerAsBuffer(index);
|
|
221
|
+
var data;
|
|
222
|
+
if (hardened && nonCompliant) {
|
|
223
|
+
// The private key serialization in this case will not be exactly 32 bytes and can be
|
|
224
|
+
// any value less, and the value is not zero-padded.
|
|
225
|
+
var nonZeroPadded = this.privateKey.bn.toBuffer();
|
|
226
|
+
data = Buffer.concat([Buffer.from([0]), nonZeroPadded, indexBuffer]);
|
|
227
|
+
} else if (hardened) {
|
|
228
|
+
// This will use a 32 byte zero padded serialization of the private key
|
|
229
|
+
var privateKeyBuffer = this.privateKey.bn.toBuffer({ size: 32 });
|
|
230
|
+
assert(
|
|
231
|
+
privateKeyBuffer.length === 32,
|
|
232
|
+
'length of private key buffer is expected to be 32 bytes',
|
|
233
|
+
);
|
|
234
|
+
data = Buffer.concat([Buffer.from([0]), privateKeyBuffer, indexBuffer]);
|
|
235
|
+
} else {
|
|
236
|
+
data = Buffer.concat([this.publicKey.toBuffer(), indexBuffer]);
|
|
237
|
+
}
|
|
238
|
+
var hash = Hash.sha512hmac(data, this._buffers.chainCode);
|
|
239
|
+
var leftPart = BN.fromBuffer(hash.slice(0, 32), {
|
|
240
|
+
size: 32,
|
|
241
|
+
});
|
|
242
|
+
var chainCode = hash.slice(32, 64);
|
|
243
|
+
|
|
244
|
+
var privateKey = leftPart.add(this.privateKey.toBigNumber()).umod(Point.getN()).toBuffer({
|
|
245
|
+
size: 32,
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
if (!PrivateKey.isValid(privateKey)) {
|
|
249
|
+
// Index at this point is already hardened, we can pass null as the hardened arg
|
|
250
|
+
return this._deriveWithNumber(index + 1, null, nonCompliant);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
var derived = new HDPrivateKey({
|
|
254
|
+
network: this.network,
|
|
255
|
+
depth: this.depth + 1,
|
|
256
|
+
parentFingerPrint: this.fingerPrint,
|
|
257
|
+
childIndex: index,
|
|
258
|
+
chainCode: chainCode,
|
|
259
|
+
privateKey: privateKey,
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
return derived;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Derives a child HDPrivateKey from a string path.
|
|
267
|
+
* @param {string} path - The derivation path (e.g. "m/44'/0'/0'")
|
|
268
|
+
* @param {boolean} [nonCompliant] - Whether to use non-compliant derivation
|
|
269
|
+
* @returns {HDPrivateKey} The derived private key
|
|
270
|
+
* @throws {hdErrors.InvalidPath} If the path is invalid
|
|
271
|
+
* @private
|
|
272
|
+
*/
|
|
273
|
+
HDPrivateKey.prototype._deriveFromString = function (path, nonCompliant) {
|
|
274
|
+
if (!HDPrivateKey.isValidPath(path)) {
|
|
275
|
+
throw new hdErrors.InvalidPath(path);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
var indexes = Derivation.getDerivationIndexes(path);
|
|
279
|
+
var derived = indexes.reduce(function (prev, index) {
|
|
280
|
+
return prev._deriveWithNumber(index, null, nonCompliant);
|
|
281
|
+
}, this);
|
|
282
|
+
|
|
283
|
+
return derived;
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Verifies that a given serialized private key in base58 with checksum format
|
|
288
|
+
* is valid.
|
|
289
|
+
*
|
|
290
|
+
* @param {string|Buffer} data - the serialized private key
|
|
291
|
+
* @param {string|Network} network - optional, if present, checks that the
|
|
292
|
+
* network provided matches the network serialized.
|
|
293
|
+
* @return {boolean}
|
|
294
|
+
*/
|
|
295
|
+
HDPrivateKey.isValidSerialized = function (data, network) {
|
|
296
|
+
return !HDPrivateKey.getSerializedError(data, network);
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Checks what's the error that causes the validation of a serialized private key
|
|
301
|
+
* in base58 with checksum to fail.
|
|
302
|
+
*
|
|
303
|
+
* @param {string|Buffer} data - the serialized private key
|
|
304
|
+
* @param {string|Network} network - optional, if present, checks that the
|
|
305
|
+
* network provided matches the network serialized.
|
|
306
|
+
* @return {errors.InvalidArgument|null}
|
|
307
|
+
*/
|
|
308
|
+
HDPrivateKey.getSerializedError = function (data, network) {
|
|
309
|
+
if (!(_.isString(data) || Buffer.isBuffer(data))) {
|
|
310
|
+
return new hdErrors.UnrecognizedArgument('Expected string or buffer');
|
|
311
|
+
}
|
|
312
|
+
if (!Base58.validCharacters(data)) {
|
|
313
|
+
return new errors.InvalidB58Char('(unknown)', data);
|
|
314
|
+
}
|
|
315
|
+
try {
|
|
316
|
+
data = Base58Check.decode(data);
|
|
317
|
+
} catch (e) {
|
|
318
|
+
return new errors.InvalidB58Checksum(data);
|
|
319
|
+
}
|
|
320
|
+
if (data.length !== HDPrivateKey.DataLength) {
|
|
321
|
+
return new hdErrors.InvalidLength(data);
|
|
322
|
+
}
|
|
323
|
+
if (!_.isUndefined(network)) {
|
|
324
|
+
var error = HDPrivateKey._validateNetwork(data, network);
|
|
325
|
+
if (error) {
|
|
326
|
+
return error;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return null;
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Validates if the provided data matches the expected network's extended private key version.
|
|
334
|
+
* @param {Buffer} data - The data buffer to validate (must include version bytes).
|
|
335
|
+
* @param {string|Network} networkArg - Network identifier or Network object to validate against.
|
|
336
|
+
* @returns {Error|null} Returns error if validation fails, otherwise null.
|
|
337
|
+
* @private
|
|
338
|
+
*/
|
|
339
|
+
HDPrivateKey._validateNetwork = function (data, networkArg) {
|
|
340
|
+
var network = Networks.get(networkArg);
|
|
341
|
+
if (!network) {
|
|
342
|
+
return new errors.InvalidNetworkArgument(networkArg);
|
|
343
|
+
}
|
|
344
|
+
var version = data.slice(0, 4);
|
|
345
|
+
if (version.readUInt32BE(0) !== network.xprivkey) {
|
|
346
|
+
return new errors.InvalidNetwork(version);
|
|
347
|
+
}
|
|
348
|
+
return null;
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Creates an HDPrivateKey instance from a string representation.
|
|
353
|
+
* @param {string} arg - The string to convert to an HDPrivateKey
|
|
354
|
+
* @returns {HDPrivateKey} A new HDPrivateKey instance
|
|
355
|
+
* @throws {Error} If the input is not a valid string
|
|
356
|
+
*/
|
|
357
|
+
HDPrivateKey.fromString = function (arg) {
|
|
358
|
+
$.checkArgument(_.isString(arg), 'No valid string was provided');
|
|
359
|
+
return new HDPrivateKey(arg);
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Creates an HDPrivateKey instance from a plain object.
|
|
364
|
+
* @param {Object} arg - The object containing HDPrivateKey properties.
|
|
365
|
+
* @throws {Error} Throws if argument is not a valid object.
|
|
366
|
+
* @returns {HDPrivateKey} A new HDPrivateKey instance.
|
|
367
|
+
*/
|
|
368
|
+
HDPrivateKey.fromObject = function (arg) {
|
|
369
|
+
$.checkArgument(_.isObject(arg), 'No valid argument was provided');
|
|
370
|
+
return new HDPrivateKey(arg);
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Builds an HDPrivateKey instance from a JSON string.
|
|
375
|
+
* @private
|
|
376
|
+
* @param {string} arg - JSON string to parse and build from.
|
|
377
|
+
* @returns {HDPrivateKey} The constructed HDPrivateKey instance.
|
|
378
|
+
*/
|
|
379
|
+
HDPrivateKey.prototype._buildFromJSON = function (arg) {
|
|
380
|
+
return this._buildFromObject(JSON.parse(arg));
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Builds an HDPrivateKey from an object by converting its properties to buffers.
|
|
385
|
+
* Handles type conversion for version, depth, parentFingerPrint, childIndex, chainCode, privateKey, and checksum.
|
|
386
|
+
* @private
|
|
387
|
+
* @param {Object} arg - The source object containing key properties
|
|
388
|
+
* @returns {HDPrivateKey} The constructed HDPrivateKey instance
|
|
389
|
+
*/
|
|
390
|
+
HDPrivateKey.prototype._buildFromObject = function (arg) {
|
|
391
|
+
// TODO: Type validation
|
|
392
|
+
var buffers = {
|
|
393
|
+
version: arg.network ? JSUtil.integerAsBuffer(Networks.get(arg.network).xprivkey) : arg.version,
|
|
394
|
+
depth: _.isNumber(arg.depth) ? Buffer.from([arg.depth & 0xff]) : arg.depth,
|
|
395
|
+
parentFingerPrint: _.isNumber(arg.parentFingerPrint)
|
|
396
|
+
? JSUtil.integerAsBuffer(arg.parentFingerPrint)
|
|
397
|
+
: arg.parentFingerPrint,
|
|
398
|
+
childIndex: _.isNumber(arg.childIndex)
|
|
399
|
+
? JSUtil.integerAsBuffer(arg.childIndex)
|
|
400
|
+
: arg.childIndex,
|
|
401
|
+
chainCode: _.isString(arg.chainCode) ? Buffer.from(arg.chainCode, 'hex') : arg.chainCode,
|
|
402
|
+
privateKey:
|
|
403
|
+
_.isString(arg.privateKey) && JSUtil.isHexa(arg.privateKey)
|
|
404
|
+
? Buffer.from(arg.privateKey, 'hex')
|
|
405
|
+
: arg.privateKey,
|
|
406
|
+
checksum: arg.checksum
|
|
407
|
+
? arg.checksum.length
|
|
408
|
+
? arg.checksum
|
|
409
|
+
: JSUtil.integerAsBuffer(arg.checksum)
|
|
410
|
+
: undefined,
|
|
411
|
+
};
|
|
412
|
+
return this._buildFromBuffers(buffers);
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Builds an HDPrivateKey instance from a serialized Base58Check encoded string.
|
|
417
|
+
* @private
|
|
418
|
+
* @param {string} arg - The Base58Check encoded extended private key (xprivkey)
|
|
419
|
+
* @returns {HDPrivateKey} The instance built from the decoded buffers
|
|
420
|
+
*/
|
|
421
|
+
HDPrivateKey.prototype._buildFromSerialized = function (arg) {
|
|
422
|
+
var decoded = Base58Check.decode(arg);
|
|
423
|
+
var buffers = {
|
|
424
|
+
version: decoded.slice(HDPrivateKey.VersionStart, HDPrivateKey.VersionEnd),
|
|
425
|
+
depth: decoded.slice(HDPrivateKey.DepthStart, HDPrivateKey.DepthEnd),
|
|
426
|
+
parentFingerPrint: decoded.slice(
|
|
427
|
+
HDPrivateKey.ParentFingerPrintStart,
|
|
428
|
+
HDPrivateKey.ParentFingerPrintEnd,
|
|
429
|
+
),
|
|
430
|
+
childIndex: decoded.slice(HDPrivateKey.ChildIndexStart, HDPrivateKey.ChildIndexEnd),
|
|
431
|
+
chainCode: decoded.slice(HDPrivateKey.ChainCodeStart, HDPrivateKey.ChainCodeEnd),
|
|
432
|
+
privateKey: decoded.slice(HDPrivateKey.PrivateKeyStart, HDPrivateKey.PrivateKeyEnd),
|
|
433
|
+
checksum: decoded.slice(HDPrivateKey.ChecksumStart, HDPrivateKey.ChecksumEnd),
|
|
434
|
+
xprivkey: arg,
|
|
435
|
+
};
|
|
436
|
+
return this._buildFromBuffers(buffers);
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Generates a new HDPrivateKey instance with a randomly generated seed.
|
|
441
|
+
* @param {Network} network - The network to use for the HDPrivateKey.
|
|
442
|
+
* @returns {HDPrivateKey} A new HDPrivateKey instance with random seed.
|
|
443
|
+
* @private
|
|
444
|
+
*/
|
|
445
|
+
HDPrivateKey.prototype._generateRandomly = function (network) {
|
|
446
|
+
return HDPrivateKey.fromSeed(Random.getRandomBuffer(64), network);
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Generate a private key from a seed, as described in BIP32
|
|
451
|
+
*
|
|
452
|
+
* @param {string|Buffer} hexa
|
|
453
|
+
* @param {Network} [network]
|
|
454
|
+
* @return HDPrivateKey
|
|
455
|
+
* @static
|
|
456
|
+
*/
|
|
457
|
+
HDPrivateKey.fromSeed = function (hexa, network) {
|
|
458
|
+
if (JSUtil.isHexaString(hexa)) {
|
|
459
|
+
hexa = Buffer.from(hexa, 'hex');
|
|
460
|
+
}
|
|
461
|
+
if (!Buffer.isBuffer(hexa)) {
|
|
462
|
+
throw new hdErrors.InvalidEntropyArgument(hexa);
|
|
463
|
+
}
|
|
464
|
+
if (hexa.length < MINIMUM_ENTROPY_BITS * BITS_TO_BYTES) {
|
|
465
|
+
throw new hdErrors.InvalidEntropyArgument.NotEnoughEntropy(hexa);
|
|
466
|
+
}
|
|
467
|
+
if (hexa.length > MAXIMUM_ENTROPY_BITS * BITS_TO_BYTES) {
|
|
468
|
+
throw new hdErrors.InvalidEntropyArgument.TooMuchEntropy(hexa);
|
|
469
|
+
}
|
|
470
|
+
var hash = Hash.sha512hmac(hexa, Buffer.from('Bitcoin seed'));
|
|
471
|
+
|
|
472
|
+
return new HDPrivateKey({
|
|
473
|
+
network: Networks.get(network) || Networks.defaultNetwork,
|
|
474
|
+
depth: 0,
|
|
475
|
+
parentFingerPrint: 0,
|
|
476
|
+
childIndex: 0,
|
|
477
|
+
privateKey: hash.slice(0, 32),
|
|
478
|
+
chainCode: hash.slice(32, 64),
|
|
479
|
+
});
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Calculates and caches the HD public key from the private key.
|
|
484
|
+
* This is an internal method that lazily computes the public key only when needed.
|
|
485
|
+
* The result is stored in `this._hdPublicKey` to avoid repeated calculations.
|
|
486
|
+
* @private
|
|
487
|
+
*/
|
|
488
|
+
HDPrivateKey.prototype._calcHDPublicKey = function () {
|
|
489
|
+
if (!this._hdPublicKey) {
|
|
490
|
+
var args = _.clone(this._buffers);
|
|
491
|
+
var point = Point.getG().mul(BN.fromBuffer(args.privateKey));
|
|
492
|
+
args.publicKey = Point.pointToCompressed(point);
|
|
493
|
+
args.version = JSUtil.integerAsBuffer(Networks.get(args.version.readUInt32BE(0)).xpubkey);
|
|
494
|
+
args.privateKey = undefined;
|
|
495
|
+
args.checksum = undefined;
|
|
496
|
+
args.xprivkey = undefined;
|
|
497
|
+
this._hdPublicKey = new HDPublicKey(args);
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Converts the HDPrivateKey instance to its corresponding HDPublicKey.
|
|
503
|
+
* @returns {HDPublicKey} The derived HD public key.
|
|
504
|
+
*/
|
|
505
|
+
HDPrivateKey.prototype.toHDPublicKey = function () {
|
|
506
|
+
this._calcHDPublicKey();
|
|
507
|
+
return this._hdPublicKey;
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Returns the private key associated with this HD private key.
|
|
513
|
+
* @returns {PrivateKey} The private key instance.
|
|
514
|
+
*/
|
|
515
|
+
HDPrivateKey.prototype.toPrivateKey = function () {
|
|
516
|
+
return this.privateKey;
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Receives a object with buffers in all the properties and populates the
|
|
522
|
+
* internal structure
|
|
523
|
+
*
|
|
524
|
+
* @param {Object} arg
|
|
525
|
+
* @param {buffer.Buffer} arg.version
|
|
526
|
+
* @param {buffer.Buffer} arg.depth
|
|
527
|
+
* @param {buffer.Buffer} arg.parentFingerPrint
|
|
528
|
+
* @param {buffer.Buffer} arg.childIndex
|
|
529
|
+
* @param {buffer.Buffer} arg.chainCode
|
|
530
|
+
* @param {buffer.Buffer} arg.privateKey
|
|
531
|
+
* @param {buffer.Buffer} arg.checksum
|
|
532
|
+
* @param {string=} arg.xprivkey - if set, don't recalculate the base58
|
|
533
|
+
* representation
|
|
534
|
+
* @return {HDPrivateKey} this
|
|
535
|
+
* @private
|
|
536
|
+
*/
|
|
537
|
+
HDPrivateKey.prototype._buildFromBuffers = function (arg) {
|
|
538
|
+
HDPrivateKey._validateBufferArguments(arg);
|
|
539
|
+
|
|
540
|
+
JSUtil.defineImmutable(this, {
|
|
541
|
+
_buffers: arg,
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
var sequence = [
|
|
545
|
+
arg.version,
|
|
546
|
+
arg.depth,
|
|
547
|
+
arg.parentFingerPrint,
|
|
548
|
+
arg.childIndex,
|
|
549
|
+
arg.chainCode,
|
|
550
|
+
Buffer.alloc(1),
|
|
551
|
+
arg.privateKey,
|
|
552
|
+
];
|
|
553
|
+
var concat = Buffer.concat(sequence);
|
|
554
|
+
if (!arg.checksum || !arg.checksum.length) {
|
|
555
|
+
arg.checksum = Base58Check.checksum(concat);
|
|
556
|
+
} else {
|
|
557
|
+
if (arg.checksum.toString() !== Base58Check.checksum(concat).toString()) {
|
|
558
|
+
throw new errors.InvalidB58Checksum(concat);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
var network = Networks.get(arg.version.readUInt32BE(0));
|
|
563
|
+
var xprivkey;
|
|
564
|
+
xprivkey = Base58Check.encode(Buffer.concat(sequence));
|
|
565
|
+
arg.xprivkey = Buffer.from(xprivkey);
|
|
566
|
+
|
|
567
|
+
var privateKey = new PrivateKey(BN.fromBuffer(arg.privateKey), network);
|
|
568
|
+
var publicKey = privateKey.toPublicKey();
|
|
569
|
+
var size = HDPrivateKey.ParentFingerPrintSize;
|
|
570
|
+
var fingerPrint = Hash.sha256ripemd160(publicKey.toBuffer()).slice(0, size);
|
|
571
|
+
|
|
572
|
+
JSUtil.defineImmutable(this, {
|
|
573
|
+
xprivkey: xprivkey,
|
|
574
|
+
network: network,
|
|
575
|
+
depth: arg.depth[0],
|
|
576
|
+
privateKey: privateKey,
|
|
577
|
+
publicKey: publicKey,
|
|
578
|
+
fingerPrint: fingerPrint,
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
this._hdPublicKey = null;
|
|
582
|
+
return this;
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Validates buffer arguments for HDPrivateKey.
|
|
587
|
+
* Checks that each required buffer field exists and has the correct size.
|
|
588
|
+
* @private
|
|
589
|
+
* @param {Object} arg - Object containing buffer fields to validate
|
|
590
|
+
* @param {Buffer} arg.version - Version buffer
|
|
591
|
+
* @param {Buffer} arg.depth - Depth buffer
|
|
592
|
+
* @param {Buffer} arg.parentFingerPrint - Parent fingerprint buffer
|
|
593
|
+
* @param {Buffer} arg.childIndex - Child index buffer
|
|
594
|
+
* @param {Buffer} arg.chainCode - Chain code buffer
|
|
595
|
+
* @param {Buffer} arg.privateKey - Private key buffer
|
|
596
|
+
* @param {Buffer} [arg.checksum] - Optional checksum buffer
|
|
597
|
+
*/
|
|
598
|
+
HDPrivateKey._validateBufferArguments = function (arg) {
|
|
599
|
+
var checkBuffer = function (name, size) {
|
|
600
|
+
var buff = arg[name];
|
|
601
|
+
assert(Buffer.isBuffer(buff), name + ' argument is not a buffer');
|
|
602
|
+
assert(
|
|
603
|
+
buff.length === size,
|
|
604
|
+
name + ' has not the expected size: found ' + buff.length + ', expected ' + size,
|
|
605
|
+
);
|
|
606
|
+
};
|
|
607
|
+
checkBuffer('version', HDPrivateKey.VersionSize);
|
|
608
|
+
checkBuffer('depth', HDPrivateKey.DepthSize);
|
|
609
|
+
checkBuffer('parentFingerPrint', HDPrivateKey.ParentFingerPrintSize);
|
|
610
|
+
checkBuffer('childIndex', HDPrivateKey.ChildIndexSize);
|
|
611
|
+
checkBuffer('chainCode', HDPrivateKey.ChainCodeSize);
|
|
612
|
+
checkBuffer('privateKey', HDPrivateKey.PrivateKeySize);
|
|
613
|
+
if (arg.checksum && arg.checksum.length) {
|
|
614
|
+
checkBuffer('checksum', HDPrivateKey.CheckSumSize);
|
|
615
|
+
}
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Returns the extended private key string representation of this HDPrivateKey.
|
|
620
|
+
* (a string starting with "xprv...")
|
|
621
|
+
* @returns {string} The extended private key in base58 string format.
|
|
622
|
+
*/
|
|
623
|
+
HDPrivateKey.prototype.toString = function () {
|
|
624
|
+
return this.xprivkey;
|
|
625
|
+
};
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Returns the console representation of this extended private key.
|
|
629
|
+
* @return string
|
|
630
|
+
*/
|
|
631
|
+
HDPrivateKey.prototype.inspect = function () {
|
|
632
|
+
return '<HDPrivateKey: ' + this.xprivkey + '>';
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Returns a plain object with a representation of this private key.
|
|
637
|
+
*
|
|
638
|
+
* Fields include:
|
|
639
|
+
* <ul>
|
|
640
|
+
* <li> network: either 'livenet' or 'testnet' </li>
|
|
641
|
+
* <li> depth: a number ranging from 0 to 255 </li>
|
|
642
|
+
* <li> fingerPrint: a number ranging from 0 to 2^32-1, taken from the hash of the associated public key </li>
|
|
643
|
+
* <li> parentFingerPrint: a number ranging from 0 to 2^32-1, taken from the hash of this parent's associated public key or zero. </li>
|
|
644
|
+
* <li> childIndex: the index from which this child was derived (or zero) </li>
|
|
645
|
+
* <li> chainCode: an hexa string representing a number used in the derivation </li>
|
|
646
|
+
* <li> privateKey: the private key associated, in hexa representation </li>
|
|
647
|
+
* <li> xprivkey: the representation of this extended private key in checksum base58 format </li>
|
|
648
|
+
* <li> checksum: the base58 checksum of xprivkey </li>
|
|
649
|
+
* </ul>
|
|
650
|
+
* @return {Object}
|
|
651
|
+
*/
|
|
652
|
+
HDPrivateKey.prototype.toObject = HDPrivateKey.prototype.toJSON = function toObject() {
|
|
653
|
+
return {
|
|
654
|
+
network: Networks.get(this._buffers.version.readUInt32BE(0), 'xprivkey').name,
|
|
655
|
+
depth: this._buffers.depth[0],
|
|
656
|
+
fingerPrint: this.fingerPrint.readUInt32BE(0),
|
|
657
|
+
parentFingerPrint: this._buffers.parentFingerPrint.readUInt32BE(0),
|
|
658
|
+
childIndex: this._buffers.childIndex.readUInt32BE(0),
|
|
659
|
+
chainCode: this._buffers.chainCode.toString('hex'),
|
|
660
|
+
privateKey: this.privateKey.toBuffer().toString('hex'),
|
|
661
|
+
checksum: this._buffers.checksum.readUInt32BE(0),
|
|
662
|
+
xprivkey: this.xprivkey,
|
|
663
|
+
};
|
|
664
|
+
};
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Build a HDPrivateKey from a buffer
|
|
668
|
+
*
|
|
669
|
+
* @param {Buffer} arg
|
|
670
|
+
* @return {HDPrivateKey}
|
|
671
|
+
*/
|
|
672
|
+
HDPrivateKey.fromBuffer = function (buf) {
|
|
673
|
+
return new HDPrivateKey(buf.toString());
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Build a HDPrivateKey from a hex string
|
|
678
|
+
*
|
|
679
|
+
* @param {string} hex
|
|
680
|
+
* @return {HDPrivateKey}
|
|
681
|
+
*/
|
|
682
|
+
HDPrivateKey.fromHex = function (hex) {
|
|
683
|
+
return HDPrivateKey.fromBuffer(Buffer.from(hex, 'hex'));
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Returns a buffer representation of the HDPrivateKey
|
|
688
|
+
*
|
|
689
|
+
* @return {string}
|
|
690
|
+
*/
|
|
691
|
+
HDPrivateKey.prototype.toBuffer = function () {
|
|
692
|
+
return Buffer.from(this.toString());
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Returns a hex string representation of the HDPrivateKey
|
|
697
|
+
*
|
|
698
|
+
* @return {string}
|
|
699
|
+
*/
|
|
700
|
+
HDPrivateKey.prototype.toHex = function () {
|
|
701
|
+
return this.toBuffer().toString('hex');
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Sets the default depth for hierarchical deterministic (HD) private keys.
|
|
706
|
+
* @type {number}
|
|
707
|
+
* @default 0
|
|
708
|
+
*/
|
|
709
|
+
HDPrivateKey.DefaultDepth = 0;
|
|
710
|
+
/**
|
|
711
|
+
* Sets the default fingerprint value for HDPrivateKey instances.
|
|
712
|
+
* @type {number}
|
|
713
|
+
* @default 0
|
|
714
|
+
*/
|
|
715
|
+
HDPrivateKey.DefaultFingerprint = 0;
|
|
716
|
+
/**
|
|
717
|
+
* Default child index used for deriving child keys in the HD (Hierarchical Deterministic) key derivation path.
|
|
718
|
+
* @type {number}
|
|
719
|
+
* @default 0
|
|
720
|
+
*/
|
|
721
|
+
HDPrivateKey.DefaultChildIndex = 0;
|
|
722
|
+
/**
|
|
723
|
+
* Sets the hardened derivation flag for HDPrivateKey (inherited from Derivation.Hardened).
|
|
724
|
+
* @type {number}
|
|
725
|
+
*/
|
|
726
|
+
HDPrivateKey.Hardened = Derivation.Hardened;
|
|
727
|
+
/**
|
|
728
|
+
* Maximum index value for HD private keys (2 * Hardened value).
|
|
729
|
+
* @type {number}
|
|
730
|
+
*/
|
|
731
|
+
HDPrivateKey.MaxIndex = 2 * HDPrivateKey.Hardened;
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Sets the root element alias for HDPrivateKey to match Derivation's root element alias.
|
|
735
|
+
* @type {string}
|
|
736
|
+
*/
|
|
737
|
+
HDPrivateKey.RootElementAlias = Derivation.RootElementAlias;
|
|
738
|
+
|
|
739
|
+
HDPrivateKey.VersionSize = 4;
|
|
740
|
+
HDPrivateKey.DepthSize = 1;
|
|
741
|
+
HDPrivateKey.ParentFingerPrintSize = 4;
|
|
742
|
+
HDPrivateKey.ChildIndexSize = 4;
|
|
743
|
+
HDPrivateKey.ChainCodeSize = 32;
|
|
744
|
+
HDPrivateKey.PrivateKeySize = 32;
|
|
745
|
+
HDPrivateKey.CheckSumSize = 4;
|
|
746
|
+
|
|
747
|
+
HDPrivateKey.DataLength = 78;
|
|
748
|
+
HDPrivateKey.SerializedByteSize = 82;
|
|
749
|
+
|
|
750
|
+
HDPrivateKey.VersionStart = 0;
|
|
751
|
+
HDPrivateKey.VersionEnd = HDPrivateKey.VersionStart + HDPrivateKey.VersionSize;
|
|
752
|
+
HDPrivateKey.DepthStart = HDPrivateKey.VersionEnd;
|
|
753
|
+
HDPrivateKey.DepthEnd = HDPrivateKey.DepthStart + HDPrivateKey.DepthSize;
|
|
754
|
+
HDPrivateKey.ParentFingerPrintStart = HDPrivateKey.DepthEnd;
|
|
755
|
+
HDPrivateKey.ParentFingerPrintEnd =
|
|
756
|
+
HDPrivateKey.ParentFingerPrintStart + HDPrivateKey.ParentFingerPrintSize;
|
|
757
|
+
HDPrivateKey.ChildIndexStart = HDPrivateKey.ParentFingerPrintEnd;
|
|
758
|
+
HDPrivateKey.ChildIndexEnd = HDPrivateKey.ChildIndexStart + HDPrivateKey.ChildIndexSize;
|
|
759
|
+
HDPrivateKey.ChainCodeStart = HDPrivateKey.ChildIndexEnd;
|
|
760
|
+
HDPrivateKey.ChainCodeEnd = HDPrivateKey.ChainCodeStart + HDPrivateKey.ChainCodeSize;
|
|
761
|
+
HDPrivateKey.PrivateKeyStart = HDPrivateKey.ChainCodeEnd + 1;
|
|
762
|
+
HDPrivateKey.PrivateKeyEnd = HDPrivateKey.PrivateKeyStart + HDPrivateKey.PrivateKeySize;
|
|
763
|
+
HDPrivateKey.ChecksumStart = HDPrivateKey.PrivateKeyEnd;
|
|
764
|
+
HDPrivateKey.ChecksumEnd = HDPrivateKey.ChecksumStart + HDPrivateKey.CheckSumSize;
|
|
765
|
+
|
|
766
|
+
assert(HDPrivateKey.ChecksumEnd === HDPrivateKey.SerializedByteSize);
|
|
767
|
+
|
|
768
|
+
export default HDPrivateKey;
|