smartledger-bsv 3.0.0

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.
Files changed (76) hide show
  1. package/LICENSE +36 -0
  2. package/README.md +305 -0
  3. package/SECURITY.md +75 -0
  4. package/bsv-ecies.min.js +12 -0
  5. package/bsv-message.min.js +10 -0
  6. package/bsv-mnemonic.min.js +12 -0
  7. package/bsv.d.ts +440 -0
  8. package/bsv.min.js +37 -0
  9. package/ecies/index.js +1 -0
  10. package/index.js +101 -0
  11. package/lib/address.js +526 -0
  12. package/lib/block/block.js +277 -0
  13. package/lib/block/blockheader.js +294 -0
  14. package/lib/block/index.js +4 -0
  15. package/lib/block/merkleblock.js +316 -0
  16. package/lib/crypto/bn.js +278 -0
  17. package/lib/crypto/ecdsa.js +330 -0
  18. package/lib/crypto/elliptic-fixed.js +74 -0
  19. package/lib/crypto/hash.browser.js +171 -0
  20. package/lib/crypto/hash.js +2 -0
  21. package/lib/crypto/hash.node.js +171 -0
  22. package/lib/crypto/point.js +217 -0
  23. package/lib/crypto/random.js +37 -0
  24. package/lib/crypto/signature.js +410 -0
  25. package/lib/crypto/smartledger_verify.js +109 -0
  26. package/lib/ecies/bitcore-ecies.js +163 -0
  27. package/lib/ecies/electrum-ecies.js +175 -0
  28. package/lib/ecies/errors.js +16 -0
  29. package/lib/ecies/index.js +1 -0
  30. package/lib/encoding/base58.js +108 -0
  31. package/lib/encoding/base58check.js +112 -0
  32. package/lib/encoding/bufferreader.js +200 -0
  33. package/lib/encoding/bufferwriter.js +150 -0
  34. package/lib/encoding/varint.js +71 -0
  35. package/lib/errors/index.js +57 -0
  36. package/lib/errors/spec.js +184 -0
  37. package/lib/hdprivatekey.js +655 -0
  38. package/lib/hdpublickey.js +509 -0
  39. package/lib/message/index.js +4 -0
  40. package/lib/message/message.js +181 -0
  41. package/lib/mnemonic/errors.js +18 -0
  42. package/lib/mnemonic/index.js +4 -0
  43. package/lib/mnemonic/mnemonic.js +304 -0
  44. package/lib/mnemonic/pbkdf2.js +68 -0
  45. package/lib/mnemonic/words/chinese.js +5 -0
  46. package/lib/mnemonic/words/english.js +5 -0
  47. package/lib/mnemonic/words/french.js +5 -0
  48. package/lib/mnemonic/words/index.js +8 -0
  49. package/lib/mnemonic/words/italian.js +5 -0
  50. package/lib/mnemonic/words/japanese.js +5 -0
  51. package/lib/mnemonic/words/spanish.js +5 -0
  52. package/lib/networks.js +392 -0
  53. package/lib/opcode.js +248 -0
  54. package/lib/privatekey.js +373 -0
  55. package/lib/publickey.js +387 -0
  56. package/lib/script/index.js +3 -0
  57. package/lib/script/interpreter.js +1807 -0
  58. package/lib/script/script.js +1153 -0
  59. package/lib/transaction/index.js +7 -0
  60. package/lib/transaction/input/index.js +6 -0
  61. package/lib/transaction/input/input.js +202 -0
  62. package/lib/transaction/input/multisig.js +220 -0
  63. package/lib/transaction/input/multisigscripthash.js +189 -0
  64. package/lib/transaction/input/publickey.js +96 -0
  65. package/lib/transaction/input/publickeyhash.js +103 -0
  66. package/lib/transaction/output.js +192 -0
  67. package/lib/transaction/sighash.js +288 -0
  68. package/lib/transaction/signature.js +88 -0
  69. package/lib/transaction/transaction.js +1208 -0
  70. package/lib/transaction/unspentoutput.js +97 -0
  71. package/lib/util/_.js +44 -0
  72. package/lib/util/js.js +91 -0
  73. package/lib/util/preconditions.js +34 -0
  74. package/message/index.js +1 -0
  75. package/mnemonic/index.js +1 -0
  76. package/package.json +86 -0
@@ -0,0 +1,655 @@
1
+ 'use strict'
2
+
3
+ var assert = require('assert')
4
+ var buffer = require('buffer')
5
+ var _ = require('./util/_')
6
+ var $ = require('./util/preconditions')
7
+
8
+ var BN = require('./crypto/bn')
9
+ var Base58 = require('./encoding/base58')
10
+ var Base58Check = require('./encoding/base58check')
11
+ var Hash = require('./crypto/hash')
12
+ var Network = require('./networks')
13
+ var Point = require('./crypto/point')
14
+ var PrivateKey = require('./privatekey')
15
+ var Random = require('./crypto/random')
16
+
17
+ var errors = require('./errors')
18
+ var hdErrors = errors.HDPrivateKey
19
+ var JSUtil = require('./util/js')
20
+
21
+ var MINIMUM_ENTROPY_BITS = 128
22
+ var BITS_TO_BYTES = 1 / 8
23
+ var MAXIMUM_ENTROPY_BITS = 512
24
+
25
+ /**
26
+ * Represents an instance of an hierarchically derived private key.
27
+ *
28
+ * More info on https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
29
+ *
30
+ * @constructor
31
+ * @param {string|Buffer|Object} arg
32
+ */
33
+ function HDPrivateKey (arg) {
34
+ if (arg instanceof HDPrivateKey) {
35
+ return arg
36
+ }
37
+ if (!(this instanceof HDPrivateKey)) {
38
+ return new HDPrivateKey(arg)
39
+ }
40
+ if (!arg) {
41
+ return this._generateRandomly()
42
+ }
43
+
44
+ if (Network.get(arg)) {
45
+ return this._generateRandomly(arg)
46
+ } else if (_.isString(arg) || Buffer.isBuffer(arg)) {
47
+ if (HDPrivateKey.isValidSerialized(arg)) {
48
+ this._buildFromSerialized(arg)
49
+ } else if (JSUtil.isValidJSON(arg)) {
50
+ this._buildFromJSON(arg)
51
+ } else if (Buffer.isBuffer(arg) && HDPrivateKey.isValidSerialized(arg.toString())) {
52
+ this._buildFromSerialized(arg.toString())
53
+ } else {
54
+ throw HDPrivateKey.getSerializedError(arg)
55
+ }
56
+ } else if (_.isObject(arg)) {
57
+ this._buildFromObject(arg)
58
+ } else {
59
+ throw new hdErrors.UnrecognizedArgument(arg)
60
+ }
61
+ }
62
+
63
+ HDPrivateKey.fromRandom = function () {
64
+ return new HDPrivateKey()
65
+ }
66
+
67
+ /**
68
+ * Verifies that a given path is valid.
69
+ *
70
+ * @param {string|number} arg
71
+ * @param {boolean?} hardened
72
+ * @return {boolean}
73
+ */
74
+ HDPrivateKey.isValidPath = function (arg, hardened) {
75
+ if (_.isString(arg)) {
76
+ var indexes = HDPrivateKey._getDerivationIndexes(arg)
77
+ return indexes !== null && _.every(indexes, HDPrivateKey.isValidPath)
78
+ }
79
+
80
+ if (_.isNumber(arg)) {
81
+ if (arg < HDPrivateKey.Hardened && hardened === true) {
82
+ arg += HDPrivateKey.Hardened
83
+ }
84
+ return arg >= 0 && arg < HDPrivateKey.MaxIndex
85
+ }
86
+
87
+ return false
88
+ }
89
+
90
+ /**
91
+ * Internal function that splits a string path into a derivation index array.
92
+ * It will return null if the string path is malformed.
93
+ * It does not validate if indexes are in bounds.
94
+ *
95
+ * @param {string} path
96
+ * @return {Array}
97
+ */
98
+ HDPrivateKey._getDerivationIndexes = function (path) {
99
+ var steps = path.split('/')
100
+
101
+ // Special cases:
102
+ if (_.includes(HDPrivateKey.RootElementAlias, path)) {
103
+ return []
104
+ }
105
+
106
+ if (!_.includes(HDPrivateKey.RootElementAlias, steps[0])) {
107
+ return null
108
+ }
109
+
110
+ var indexes = steps.slice(1).map(function (step) {
111
+ var isHardened = step.slice(-1) === '\''
112
+ if (isHardened) {
113
+ step = step.slice(0, -1)
114
+ }
115
+ if (!step || step[0] === '-') {
116
+ return NaN
117
+ }
118
+ var index = +step // cast to number
119
+ if (isHardened) {
120
+ index += HDPrivateKey.Hardened
121
+ }
122
+
123
+ return index
124
+ })
125
+
126
+ return _.some(indexes, isNaN) ? null : indexes
127
+ }
128
+
129
+ /**
130
+ * WARNING: This method is deprecated. Use deriveChild or deriveNonCompliantChild instead. This is not BIP32 compliant
131
+ *
132
+ *
133
+ * Get a derived child based on a string or number.
134
+ *
135
+ * If the first argument is a string, it's parsed as the full path of
136
+ * derivation. Valid values for this argument include "m" (which returns the
137
+ * same private key), "m/0/1/40/2'/1000", where the ' quote means a hardened
138
+ * derivation.
139
+ *
140
+ * If the first argument is a number, the child with that index will be
141
+ * derived. If the second argument is truthy, the hardened version will be
142
+ * derived. See the example usage for clarification.
143
+ *
144
+ * @example
145
+ * ```javascript
146
+ * var parent = new HDPrivateKey('xprv...');
147
+ * var child_0_1_2h = parent.derive(0).derive(1).derive(2, true);
148
+ * var copy_of_child_0_1_2h = parent.derive("m/0/1/2'");
149
+ * assert(child_0_1_2h.xprivkey === copy_of_child_0_1_2h);
150
+ * ```
151
+ *
152
+ * @param {string|number} arg
153
+ * @param {boolean?} hardened
154
+ */
155
+ HDPrivateKey.prototype.derive = function () {
156
+ throw new Error('derive has been deprecated. use deriveChild or, for the old way, deriveNonCompliantChild.')
157
+ }
158
+
159
+ /**
160
+ * WARNING: This method will not be officially supported until v1.0.0.
161
+ *
162
+ *
163
+ * Get a derived child based on a string or number.
164
+ *
165
+ * If the first argument is a string, it's parsed as the full path of
166
+ * derivation. Valid values for this argument include "m" (which returns the
167
+ * same private key), "m/0/1/40/2'/1000", where the ' quote means a hardened
168
+ * derivation.
169
+ *
170
+ * If the first argument is a number, the child with that index will be
171
+ * derived. If the second argument is truthy, the hardened version will be
172
+ * derived. See the example usage for clarification.
173
+ *
174
+ * WARNING: The `nonCompliant` option should NOT be used, except for older implementation
175
+ * that used a derivation strategy that used a non-zero padded private key.
176
+ *
177
+ * @example
178
+ * ```javascript
179
+ * var parent = new HDPrivateKey('xprv...');
180
+ * var child_0_1_2h = parent.deriveChild(0).deriveChild(1).deriveChild(2, true);
181
+ * var copy_of_child_0_1_2h = parent.deriveChild("m/0/1/2'");
182
+ * assert(child_0_1_2h.xprivkey === copy_of_child_0_1_2h);
183
+ * ```
184
+ *
185
+ * @param {string|number} arg
186
+ * @param {boolean?} hardened
187
+ */
188
+ HDPrivateKey.prototype.deriveChild = function (arg, hardened) {
189
+ if (_.isNumber(arg)) {
190
+ return this._deriveWithNumber(arg, hardened)
191
+ } else if (_.isString(arg)) {
192
+ return this._deriveFromString(arg)
193
+ } else {
194
+ throw new hdErrors.InvalidDerivationArgument(arg)
195
+ }
196
+ }
197
+
198
+ /**
199
+ * WARNING: This method will not be officially supported until v1.0.0
200
+ *
201
+ *
202
+ * WARNING: If this is a new implementation you should NOT use this method, you should be using
203
+ * `derive` instead.
204
+ *
205
+ * This method is explicitly for use and compatibility with an implementation that
206
+ * was not compliant with BIP32 regarding the derivation algorithm. The private key
207
+ * must be 32 bytes hashing, and this implementation will use the non-zero padded
208
+ * serialization of a private key, such that it's still possible to derive the privateKey
209
+ * to recover those funds.
210
+ *
211
+ * @param {string|number} arg
212
+ * @param {boolean?} hardened
213
+ */
214
+ HDPrivateKey.prototype.deriveNonCompliantChild = function (arg, hardened) {
215
+ if (_.isNumber(arg)) {
216
+ return this._deriveWithNumber(arg, hardened, true)
217
+ } else if (_.isString(arg)) {
218
+ return this._deriveFromString(arg, true)
219
+ } else {
220
+ throw new hdErrors.InvalidDerivationArgument(arg)
221
+ }
222
+ }
223
+
224
+ HDPrivateKey.prototype._deriveWithNumber = function (index, hardened, nonCompliant) {
225
+ if (!HDPrivateKey.isValidPath(index, hardened)) {
226
+ throw new hdErrors.InvalidPath(index)
227
+ }
228
+
229
+ hardened = index >= HDPrivateKey.Hardened ? true : hardened
230
+ if (index < HDPrivateKey.Hardened && hardened === true) {
231
+ index += HDPrivateKey.Hardened
232
+ }
233
+
234
+ var indexBuffer = JSUtil.integerAsBuffer(index)
235
+ var data
236
+ if (hardened && nonCompliant) {
237
+ // The private key serialization in this case will not be exactly 32 bytes and can be
238
+ // any value less, and the value is not zero-padded.
239
+ var nonZeroPadded = this.privateKey.bn.toBuffer()
240
+ data = Buffer.concat([buffer.Buffer.from([0]), nonZeroPadded, indexBuffer])
241
+ } else if (hardened) {
242
+ // This will use a 32 byte zero padded serialization of the private key
243
+ var privateKeyBuffer = this.privateKey.bn.toBuffer({ size: 32 })
244
+ assert(privateKeyBuffer.length === 32, 'length of private key buffer is expected to be 32 bytes')
245
+ data = Buffer.concat([buffer.Buffer.from([0]), privateKeyBuffer, indexBuffer])
246
+ } else {
247
+ data = Buffer.concat([this.publicKey.toBuffer(), indexBuffer])
248
+ }
249
+ var hash = Hash.sha512hmac(data, this._buffers.chainCode)
250
+ var leftPart = BN.fromBuffer(hash.slice(0, 32), {
251
+ size: 32
252
+ })
253
+ var chainCode = hash.slice(32, 64)
254
+
255
+ var privateKey = leftPart.add(this.privateKey.toBigNumber()).umod(Point.getN()).toBuffer({
256
+ size: 32
257
+ })
258
+
259
+ if (!PrivateKey.isValid(privateKey)) {
260
+ // Index at this point is already hardened, we can pass null as the hardened arg
261
+ return this._deriveWithNumber(index + 1, null, nonCompliant)
262
+ }
263
+
264
+ var derived = new HDPrivateKey({
265
+ network: this.network,
266
+ depth: this.depth + 1,
267
+ parentFingerPrint: this.fingerPrint,
268
+ childIndex: index,
269
+ chainCode: chainCode,
270
+ privateKey: privateKey
271
+ })
272
+
273
+ return derived
274
+ }
275
+
276
+ HDPrivateKey.prototype._deriveFromString = function (path, nonCompliant) {
277
+ if (!HDPrivateKey.isValidPath(path)) {
278
+ throw new hdErrors.InvalidPath(path)
279
+ }
280
+
281
+ var indexes = HDPrivateKey._getDerivationIndexes(path)
282
+ var derived = indexes.reduce(function (prev, index) {
283
+ return prev._deriveWithNumber(index, null, nonCompliant)
284
+ }, this)
285
+
286
+ return derived
287
+ }
288
+
289
+ /**
290
+ * Verifies that a given serialized private key in base58 with checksum format
291
+ * is valid.
292
+ *
293
+ * @param {string|Buffer} data - the serialized private key
294
+ * @param {string|Network=} network - optional, if present, checks that the
295
+ * network provided matches the network serialized.
296
+ * @return {boolean}
297
+ */
298
+ HDPrivateKey.isValidSerialized = function (data, network) {
299
+ return !HDPrivateKey.getSerializedError(data, network)
300
+ }
301
+
302
+ /**
303
+ * Checks what's the error that causes the validation of a serialized private key
304
+ * in base58 with checksum to fail.
305
+ *
306
+ * @param {string|Buffer} data - the serialized private key
307
+ * @param {string|Network=} network - optional, if present, checks that the
308
+ * network provided matches the network serialized.
309
+ * @return {errors.InvalidArgument|null}
310
+ */
311
+ HDPrivateKey.getSerializedError = function (data, network) {
312
+ if (!(_.isString(data) || Buffer.isBuffer(data))) {
313
+ return new hdErrors.UnrecognizedArgument('Expected string or buffer')
314
+ }
315
+ if (!Base58.validCharacters(data)) {
316
+ return new errors.InvalidB58Char('(unknown)', data)
317
+ }
318
+ try {
319
+ data = Base58Check.decode(data)
320
+ } catch (e) {
321
+ return new errors.InvalidB58Checksum(data)
322
+ }
323
+ if (data.length !== HDPrivateKey.DataLength) {
324
+ return new hdErrors.InvalidLength(data)
325
+ }
326
+ if (!_.isUndefined(network)) {
327
+ var error = HDPrivateKey._validateNetwork(data, network)
328
+ if (error) {
329
+ return error
330
+ }
331
+ }
332
+ return null
333
+ }
334
+
335
+ HDPrivateKey._validateNetwork = function (data, networkArg) {
336
+ var network = Network.get(networkArg)
337
+ if (!network) {
338
+ return new errors.InvalidNetworkArgument(networkArg)
339
+ }
340
+ var version = data.slice(0, 4)
341
+ if (version.readUInt32BE(0) !== network.xprivkey) {
342
+ return new errors.InvalidNetwork(version)
343
+ }
344
+ return null
345
+ }
346
+
347
+ HDPrivateKey.fromString = function (arg) {
348
+ $.checkArgument(_.isString(arg), 'No valid string was provided')
349
+ return new HDPrivateKey(arg)
350
+ }
351
+
352
+ HDPrivateKey.fromObject = function (arg) {
353
+ $.checkArgument(_.isObject(arg), 'No valid argument was provided')
354
+ return new HDPrivateKey(arg)
355
+ }
356
+
357
+ HDPrivateKey.prototype._buildFromJSON = function (arg) {
358
+ return this._buildFromObject(JSON.parse(arg))
359
+ }
360
+
361
+ HDPrivateKey.prototype._buildFromObject = function (arg) {
362
+ // TODO: Type validation
363
+ var buffers = {
364
+ version: arg.network ? JSUtil.integerAsBuffer(Network.get(arg.network).xprivkey) : arg.version,
365
+ depth: _.isNumber(arg.depth) ? Buffer.from([arg.depth & 0xff]) : arg.depth,
366
+ parentFingerPrint: _.isNumber(arg.parentFingerPrint) ? JSUtil.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint,
367
+ childIndex: _.isNumber(arg.childIndex) ? JSUtil.integerAsBuffer(arg.childIndex) : arg.childIndex,
368
+ chainCode: _.isString(arg.chainCode) ? Buffer.from(arg.chainCode, 'hex') : arg.chainCode,
369
+ privateKey: (_.isString(arg.privateKey) && JSUtil.isHexa(arg.privateKey)) ? Buffer.from(arg.privateKey, 'hex') : arg.privateKey,
370
+ checksum: arg.checksum ? (arg.checksum.length ? arg.checksum : JSUtil.integerAsBuffer(arg.checksum)) : undefined
371
+ }
372
+ return this._buildFromBuffers(buffers)
373
+ }
374
+
375
+ HDPrivateKey.prototype._buildFromSerialized = function (arg) {
376
+ var decoded = Base58Check.decode(arg)
377
+ var buffers = {
378
+ version: decoded.slice(HDPrivateKey.VersionStart, HDPrivateKey.VersionEnd),
379
+ depth: decoded.slice(HDPrivateKey.DepthStart, HDPrivateKey.DepthEnd),
380
+ parentFingerPrint: decoded.slice(HDPrivateKey.ParentFingerPrintStart,
381
+ HDPrivateKey.ParentFingerPrintEnd),
382
+ childIndex: decoded.slice(HDPrivateKey.ChildIndexStart, HDPrivateKey.ChildIndexEnd),
383
+ chainCode: decoded.slice(HDPrivateKey.ChainCodeStart, HDPrivateKey.ChainCodeEnd),
384
+ privateKey: decoded.slice(HDPrivateKey.PrivateKeyStart, HDPrivateKey.PrivateKeyEnd),
385
+ checksum: decoded.slice(HDPrivateKey.ChecksumStart, HDPrivateKey.ChecksumEnd),
386
+ xprivkey: arg
387
+ }
388
+ return this._buildFromBuffers(buffers)
389
+ }
390
+
391
+ HDPrivateKey.prototype._generateRandomly = function (network) {
392
+ return HDPrivateKey.fromSeed(Random.getRandomBuffer(64), network)
393
+ }
394
+
395
+ /**
396
+ * Generate a private key from a seed, as described in BIP32
397
+ *
398
+ * @param {string|Buffer} hexa
399
+ * @param {*} network
400
+ * @return HDPrivateKey
401
+ */
402
+ HDPrivateKey.fromSeed = function (hexa, network) {
403
+ if (JSUtil.isHexaString(hexa)) {
404
+ hexa = Buffer.from(hexa, 'hex')
405
+ }
406
+ if (!Buffer.isBuffer(hexa)) {
407
+ throw new hdErrors.InvalidEntropyArgument(hexa)
408
+ }
409
+ if (hexa.length < MINIMUM_ENTROPY_BITS * BITS_TO_BYTES) {
410
+ throw new hdErrors.InvalidEntropyArgument.NotEnoughEntropy(hexa)
411
+ }
412
+ if (hexa.length > MAXIMUM_ENTROPY_BITS * BITS_TO_BYTES) {
413
+ throw new hdErrors.InvalidEntropyArgument.TooMuchEntropy(hexa)
414
+ }
415
+ var hash = Hash.sha512hmac(hexa, buffer.Buffer.from('Bitcoin seed'))
416
+
417
+ return new HDPrivateKey({
418
+ network: Network.get(network) || Network.defaultNetwork,
419
+ depth: 0,
420
+ parentFingerPrint: 0,
421
+ childIndex: 0,
422
+ privateKey: hash.slice(0, 32),
423
+ chainCode: hash.slice(32, 64)
424
+ })
425
+ }
426
+
427
+ HDPrivateKey.prototype._calcHDPublicKey = function () {
428
+ if (!this._hdPublicKey) {
429
+ var HDPublicKey = require('./hdpublickey')
430
+ this._hdPublicKey = new HDPublicKey(this)
431
+ }
432
+ }
433
+
434
+ /**
435
+ * Receives a object with buffers in all the properties and populates the
436
+ * internal structure
437
+ *
438
+ * @param {Object} arg
439
+ * @param {buffer.Buffer} arg.version
440
+ * @param {buffer.Buffer} arg.depth
441
+ * @param {buffer.Buffer} arg.parentFingerPrint
442
+ * @param {buffer.Buffer} arg.childIndex
443
+ * @param {buffer.Buffer} arg.chainCode
444
+ * @param {buffer.Buffer} arg.privateKey
445
+ * @param {buffer.Buffer} arg.checksum
446
+ * @param {string=} arg.xprivkey - if set, don't recalculate the base58
447
+ * representation
448
+ * @return {HDPrivateKey} this
449
+ */
450
+ HDPrivateKey.prototype._buildFromBuffers = function (arg) {
451
+ HDPrivateKey._validateBufferArguments(arg)
452
+
453
+ JSUtil.defineImmutable(this, {
454
+ _buffers: arg
455
+ })
456
+
457
+ var sequence = [
458
+ arg.version, arg.depth, arg.parentFingerPrint, arg.childIndex, arg.chainCode,
459
+ Buffer.alloc(1), arg.privateKey
460
+ ]
461
+ var concat = buffer.Buffer.concat(sequence)
462
+ if (!arg.checksum || !arg.checksum.length) {
463
+ arg.checksum = Base58Check.checksum(concat)
464
+ } else {
465
+ if (arg.checksum.toString() !== Base58Check.checksum(concat).toString()) {
466
+ throw new errors.InvalidB58Checksum(concat)
467
+ }
468
+ }
469
+
470
+ var network = Network.get(arg.version.readUInt32BE(0))
471
+ var xprivkey
472
+ xprivkey = Base58Check.encode(buffer.Buffer.concat(sequence))
473
+ arg.xprivkey = Buffer.from(xprivkey)
474
+
475
+ var privateKey = new PrivateKey(BN.fromBuffer(arg.privateKey), network)
476
+ var publicKey = privateKey.toPublicKey()
477
+ var size = HDPrivateKey.ParentFingerPrintSize
478
+ var fingerPrint = Hash.sha256ripemd160(publicKey.toBuffer()).slice(0, size)
479
+
480
+ JSUtil.defineImmutable(this, {
481
+ xprivkey: xprivkey,
482
+ network: network,
483
+ depth: arg.depth[0],
484
+ privateKey: privateKey,
485
+ publicKey: publicKey,
486
+ fingerPrint: fingerPrint
487
+ })
488
+
489
+ this._hdPublicKey = null
490
+
491
+ Object.defineProperty(this, 'hdPublicKey', {
492
+ configurable: false,
493
+ enumerable: true,
494
+ get: function () {
495
+ this._calcHDPublicKey()
496
+ return this._hdPublicKey
497
+ }
498
+ })
499
+ Object.defineProperty(this, 'xpubkey', {
500
+ configurable: false,
501
+ enumerable: true,
502
+ get: function () {
503
+ this._calcHDPublicKey()
504
+ return this._hdPublicKey.xpubkey
505
+ }
506
+ })
507
+ return this
508
+ }
509
+
510
+ HDPrivateKey._validateBufferArguments = function (arg) {
511
+ var checkBuffer = function (name, size) {
512
+ var buff = arg[name]
513
+ assert(Buffer.isBuffer(buff), name + ' argument is not a buffer')
514
+ assert(
515
+ buff.length === size,
516
+ name + ' has not the expected size: found ' + buff.length + ', expected ' + size
517
+ )
518
+ }
519
+ checkBuffer('version', HDPrivateKey.VersionSize)
520
+ checkBuffer('depth', HDPrivateKey.DepthSize)
521
+ checkBuffer('parentFingerPrint', HDPrivateKey.ParentFingerPrintSize)
522
+ checkBuffer('childIndex', HDPrivateKey.ChildIndexSize)
523
+ checkBuffer('chainCode', HDPrivateKey.ChainCodeSize)
524
+ checkBuffer('privateKey', HDPrivateKey.PrivateKeySize)
525
+ if (arg.checksum && arg.checksum.length) {
526
+ checkBuffer('checksum', HDPrivateKey.CheckSumSize)
527
+ }
528
+ }
529
+
530
+ /**
531
+ * Returns the string representation of this private key (a string starting
532
+ * with "xprv..."
533
+ *
534
+ * @return string
535
+ */
536
+ HDPrivateKey.prototype.toString = function () {
537
+ return this.xprivkey
538
+ }
539
+
540
+ /**
541
+ * Returns the console representation of this extended private key.
542
+ * @return string
543
+ */
544
+ HDPrivateKey.prototype.inspect = function () {
545
+ return '<HDPrivateKey: ' + this.xprivkey + '>'
546
+ }
547
+
548
+ /**
549
+ * Returns a plain object with a representation of this private key.
550
+ *
551
+ * Fields include:<ul>
552
+ * <li> network: either 'livenet' or 'testnet'
553
+ * <li> depth: a number ranging from 0 to 255
554
+ * <li> fingerPrint: a number ranging from 0 to 2^32-1, taken from the hash of the
555
+ * <li> associated public key
556
+ * <li> parentFingerPrint: a number ranging from 0 to 2^32-1, taken from the hash
557
+ * <li> of this parent's associated public key or zero.
558
+ * <li> childIndex: the index from which this child was derived (or zero)
559
+ * <li> chainCode: an hexa string representing a number used in the derivation
560
+ * <li> privateKey: the private key associated, in hexa representation
561
+ * <li> xprivkey: the representation of this extended private key in checksum
562
+ * <li> base58 format
563
+ * <li> checksum: the base58 checksum of xprivkey
564
+ * </ul>
565
+ * @return {Object}
566
+ */
567
+ HDPrivateKey.prototype.toObject = HDPrivateKey.prototype.toJSON = function toObject () {
568
+ return {
569
+ network: Network.get(this._buffers.version.readUInt32BE(0), 'xprivkey').name,
570
+ depth: this._buffers.depth[0],
571
+ fingerPrint: this.fingerPrint.readUInt32BE(0),
572
+ parentFingerPrint: this._buffers.parentFingerPrint.readUInt32BE(0),
573
+ childIndex: this._buffers.childIndex.readUInt32BE(0),
574
+ chainCode: this._buffers.chainCode.toString('hex'),
575
+ privateKey: this.privateKey.toBuffer().toString('hex'),
576
+ checksum: this._buffers.checksum.readUInt32BE(0),
577
+ xprivkey: this.xprivkey
578
+ }
579
+ }
580
+
581
+ /**
582
+ * Build a HDPrivateKey from a buffer
583
+ *
584
+ * @param {Buffer} arg
585
+ * @return {HDPrivateKey}
586
+ */
587
+ HDPrivateKey.fromBuffer = function (buf) {
588
+ return new HDPrivateKey(buf.toString())
589
+ }
590
+
591
+ /**
592
+ * Build a HDPrivateKey from a hex string
593
+ *
594
+ * @param {string} hex
595
+ * @return {HDPrivateKey}
596
+ */
597
+ HDPrivateKey.fromHex = function (hex) {
598
+ return HDPrivateKey.fromBuffer(Buffer.from(hex, 'hex'))
599
+ }
600
+
601
+ /**
602
+ * Returns a buffer representation of the HDPrivateKey
603
+ *
604
+ * @return {string}
605
+ */
606
+ HDPrivateKey.prototype.toBuffer = function () {
607
+ return Buffer.from(this.toString())
608
+ }
609
+
610
+ /**
611
+ * Returns a hex string representation of the HDPrivateKey
612
+ *
613
+ * @return {string}
614
+ */
615
+ HDPrivateKey.prototype.toHex = function () {
616
+ return this.toBuffer().toString('hex')
617
+ }
618
+
619
+ HDPrivateKey.DefaultDepth = 0
620
+ HDPrivateKey.DefaultFingerprint = 0
621
+ HDPrivateKey.DefaultChildIndex = 0
622
+ HDPrivateKey.Hardened = 0x80000000
623
+ HDPrivateKey.MaxIndex = 2 * HDPrivateKey.Hardened
624
+
625
+ HDPrivateKey.RootElementAlias = ['m', 'M', 'm\'', 'M\'']
626
+
627
+ HDPrivateKey.VersionSize = 4
628
+ HDPrivateKey.DepthSize = 1
629
+ HDPrivateKey.ParentFingerPrintSize = 4
630
+ HDPrivateKey.ChildIndexSize = 4
631
+ HDPrivateKey.ChainCodeSize = 32
632
+ HDPrivateKey.PrivateKeySize = 32
633
+ HDPrivateKey.CheckSumSize = 4
634
+
635
+ HDPrivateKey.DataLength = 78
636
+ HDPrivateKey.SerializedByteSize = 82
637
+
638
+ HDPrivateKey.VersionStart = 0
639
+ HDPrivateKey.VersionEnd = HDPrivateKey.VersionStart + HDPrivateKey.VersionSize
640
+ HDPrivateKey.DepthStart = HDPrivateKey.VersionEnd
641
+ HDPrivateKey.DepthEnd = HDPrivateKey.DepthStart + HDPrivateKey.DepthSize
642
+ HDPrivateKey.ParentFingerPrintStart = HDPrivateKey.DepthEnd
643
+ HDPrivateKey.ParentFingerPrintEnd = HDPrivateKey.ParentFingerPrintStart + HDPrivateKey.ParentFingerPrintSize
644
+ HDPrivateKey.ChildIndexStart = HDPrivateKey.ParentFingerPrintEnd
645
+ HDPrivateKey.ChildIndexEnd = HDPrivateKey.ChildIndexStart + HDPrivateKey.ChildIndexSize
646
+ HDPrivateKey.ChainCodeStart = HDPrivateKey.ChildIndexEnd
647
+ HDPrivateKey.ChainCodeEnd = HDPrivateKey.ChainCodeStart + HDPrivateKey.ChainCodeSize
648
+ HDPrivateKey.PrivateKeyStart = HDPrivateKey.ChainCodeEnd + 1
649
+ HDPrivateKey.PrivateKeyEnd = HDPrivateKey.PrivateKeyStart + HDPrivateKey.PrivateKeySize
650
+ HDPrivateKey.ChecksumStart = HDPrivateKey.PrivateKeyEnd
651
+ HDPrivateKey.ChecksumEnd = HDPrivateKey.ChecksumStart + HDPrivateKey.CheckSumSize
652
+
653
+ assert(HDPrivateKey.ChecksumEnd === HDPrivateKey.SerializedByteSize)
654
+
655
+ module.exports = HDPrivateKey