init
This commit is contained in:
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011-2018 bitcoinjs-lib contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
# bip32
|
||||
[](https://travis-ci.org/bitcoinjs/bip32)
|
||||
|
||||
[](https://www.npmjs.org/package/bip32)
|
||||
|
||||
[](https://github.com/prettier/prettier)
|
||||
|
||||
A [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) compatible library written in TypeScript with transpiled JavaScript committed to git.
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
TypeScript
|
||||
|
||||
``` typescript
|
||||
import * as bip32 from 'bip32';
|
||||
import { BIP32Interface } from 'bip32';
|
||||
let node: BIP32Interface = bip32.fromBase58('xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi');
|
||||
|
||||
let child: BIP32Interface = node.derivePath('m/0/0');
|
||||
// ...
|
||||
```
|
||||
|
||||
NodeJS
|
||||
|
||||
``` javascript
|
||||
let bip32 = require('bip32')
|
||||
let node = bip32.fromBase58('xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi')
|
||||
|
||||
let child = node.derivePath('m/0/0')
|
||||
// ...
|
||||
```
|
||||
|
||||
## LICENSE [MIT](LICENSE)
|
||||
A derivation (and extraction for modularity) of the `HDWallet`/`HDNode` written and tested by [bitcoinjs-lib](https://github.com/bitcoinjs/bitcoinjs-lib) contributors since 2014.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
# Installation
|
||||
> `npm install --save @types/node`
|
||||
|
||||
# Summary
|
||||
This package contains type definitions for Node.js (http://nodejs.org/).
|
||||
|
||||
# Details
|
||||
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node
|
||||
|
||||
Additional Details
|
||||
* Last updated: Wed, 19 Dec 2018 18:17:49 GMT
|
||||
* Dependencies: none
|
||||
* Global values: Buffer, NodeJS, SlowBuffer, Symbol, __dirname, __filename, clearImmediate, clearInterval, clearTimeout, console, exports, global, module, process, require, setImmediate, setInterval, setTimeout
|
||||
|
||||
# Credits
|
||||
These definitions were written by Microsoft TypeScript <https://github.com/Microsoft>, DefinitelyTyped <https://github.com/DefinitelyTyped>, Alberto Schiabel <https://github.com/jkomyno>, Alexander T. <https://github.com/a-tarasyuk>, Alvis HT Tang <https://github.com/alvis>, Andrew Makarov <https://github.com/r3nya>, Bruno Scheufler <https://github.com/brunoscheufler>, Chigozirim C. <https://github.com/smac89>, Christian Vaagland Tellnes <https://github.com/tellnes>, Deividas Bakanas <https://github.com/DeividasBakanas>, Eugene Y. Q. Shen <https://github.com/eyqs>, Flarna <https://github.com/Flarna>, Hannes Magnusson <https://github.com/Hannes-Magnusson-CK>, Hoàng Văn Khải <https://github.com/KSXGitHub>, Huw <https://github.com/hoo29>, Kelvin Jin <https://github.com/kjin>, Klaus Meinhardt <https://github.com/ajafff>, Lishude <https://github.com/islishude>, Mariusz Wiktorczyk <https://github.com/mwiktorczyk>, Matthieu Sieben <https://github.com/matthieusieben>, Mohsen Azimi <https://github.com/mohsen1>, Nicolas Even <https://github.com/n-e>, Nicolas Voigt <https://github.com/octo-sniffle>, Parambir Singh <https://github.com/parambirs>, Sebastian Silbermann <https://github.com/eps1lon>, Simon Schick <https://github.com/SimonSchick>, Thomas den Hollander <https://github.com/ThomasdenH>, Wilco Bakker <https://github.com/WilcoBakker>, wwwy3y3 <https://github.com/wwwy3y3>, Zane Hannan AU <https://github.com/ZaneHannanAU>, Jeremie Rodriguez <https://github.com/jeremiergz>, Samuel Ainsworth <https://github.com/samuela>.
|
||||
+9219
File diff suppressed because it is too large
Load Diff
+3163
File diff suppressed because it is too large
Load Diff
+178
@@ -0,0 +1,178 @@
|
||||
{
|
||||
"name": "@types/node",
|
||||
"version": "10.12.18",
|
||||
"description": "TypeScript definitions for Node.js",
|
||||
"license": "MIT",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Microsoft TypeScript",
|
||||
"url": "https://github.com/Microsoft",
|
||||
"githubUsername": "Microsoft"
|
||||
},
|
||||
{
|
||||
"name": "DefinitelyTyped",
|
||||
"url": "https://github.com/DefinitelyTyped",
|
||||
"githubUsername": "DefinitelyTyped"
|
||||
},
|
||||
{
|
||||
"name": "Alberto Schiabel",
|
||||
"url": "https://github.com/jkomyno",
|
||||
"githubUsername": "jkomyno"
|
||||
},
|
||||
{
|
||||
"name": "Alexander T.",
|
||||
"url": "https://github.com/a-tarasyuk",
|
||||
"githubUsername": "a-tarasyuk"
|
||||
},
|
||||
{
|
||||
"name": "Alvis HT Tang",
|
||||
"url": "https://github.com/alvis",
|
||||
"githubUsername": "alvis"
|
||||
},
|
||||
{
|
||||
"name": "Andrew Makarov",
|
||||
"url": "https://github.com/r3nya",
|
||||
"githubUsername": "r3nya"
|
||||
},
|
||||
{
|
||||
"name": "Bruno Scheufler",
|
||||
"url": "https://github.com/brunoscheufler",
|
||||
"githubUsername": "brunoscheufler"
|
||||
},
|
||||
{
|
||||
"name": "Chigozirim C.",
|
||||
"url": "https://github.com/smac89",
|
||||
"githubUsername": "smac89"
|
||||
},
|
||||
{
|
||||
"name": "Christian Vaagland Tellnes",
|
||||
"url": "https://github.com/tellnes",
|
||||
"githubUsername": "tellnes"
|
||||
},
|
||||
{
|
||||
"name": "Deividas Bakanas",
|
||||
"url": "https://github.com/DeividasBakanas",
|
||||
"githubUsername": "DeividasBakanas"
|
||||
},
|
||||
{
|
||||
"name": "Eugene Y. Q. Shen",
|
||||
"url": "https://github.com/eyqs",
|
||||
"githubUsername": "eyqs"
|
||||
},
|
||||
{
|
||||
"name": "Flarna",
|
||||
"url": "https://github.com/Flarna",
|
||||
"githubUsername": "Flarna"
|
||||
},
|
||||
{
|
||||
"name": "Hannes Magnusson",
|
||||
"url": "https://github.com/Hannes-Magnusson-CK",
|
||||
"githubUsername": "Hannes-Magnusson-CK"
|
||||
},
|
||||
{
|
||||
"name": "Hoàng Văn Khải",
|
||||
"url": "https://github.com/KSXGitHub",
|
||||
"githubUsername": "KSXGitHub"
|
||||
},
|
||||
{
|
||||
"name": "Huw",
|
||||
"url": "https://github.com/hoo29",
|
||||
"githubUsername": "hoo29"
|
||||
},
|
||||
{
|
||||
"name": "Kelvin Jin",
|
||||
"url": "https://github.com/kjin",
|
||||
"githubUsername": "kjin"
|
||||
},
|
||||
{
|
||||
"name": "Klaus Meinhardt",
|
||||
"url": "https://github.com/ajafff",
|
||||
"githubUsername": "ajafff"
|
||||
},
|
||||
{
|
||||
"name": "Lishude",
|
||||
"url": "https://github.com/islishude",
|
||||
"githubUsername": "islishude"
|
||||
},
|
||||
{
|
||||
"name": "Mariusz Wiktorczyk",
|
||||
"url": "https://github.com/mwiktorczyk",
|
||||
"githubUsername": "mwiktorczyk"
|
||||
},
|
||||
{
|
||||
"name": "Matthieu Sieben",
|
||||
"url": "https://github.com/matthieusieben",
|
||||
"githubUsername": "matthieusieben"
|
||||
},
|
||||
{
|
||||
"name": "Mohsen Azimi",
|
||||
"url": "https://github.com/mohsen1",
|
||||
"githubUsername": "mohsen1"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Even",
|
||||
"url": "https://github.com/n-e",
|
||||
"githubUsername": "n-e"
|
||||
},
|
||||
{
|
||||
"name": "Nicolas Voigt",
|
||||
"url": "https://github.com/octo-sniffle",
|
||||
"githubUsername": "octo-sniffle"
|
||||
},
|
||||
{
|
||||
"name": "Parambir Singh",
|
||||
"url": "https://github.com/parambirs",
|
||||
"githubUsername": "parambirs"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian Silbermann",
|
||||
"url": "https://github.com/eps1lon",
|
||||
"githubUsername": "eps1lon"
|
||||
},
|
||||
{
|
||||
"name": "Simon Schick",
|
||||
"url": "https://github.com/SimonSchick",
|
||||
"githubUsername": "SimonSchick"
|
||||
},
|
||||
{
|
||||
"name": "Thomas den Hollander",
|
||||
"url": "https://github.com/ThomasdenH",
|
||||
"githubUsername": "ThomasdenH"
|
||||
},
|
||||
{
|
||||
"name": "Wilco Bakker",
|
||||
"url": "https://github.com/WilcoBakker",
|
||||
"githubUsername": "WilcoBakker"
|
||||
},
|
||||
{
|
||||
"name": "wwwy3y3",
|
||||
"url": "https://github.com/wwwy3y3",
|
||||
"githubUsername": "wwwy3y3"
|
||||
},
|
||||
{
|
||||
"name": "Zane Hannan AU",
|
||||
"url": "https://github.com/ZaneHannanAU",
|
||||
"githubUsername": "ZaneHannanAU"
|
||||
},
|
||||
{
|
||||
"name": "Jeremie Rodriguez",
|
||||
"url": "https://github.com/jeremiergz",
|
||||
"githubUsername": "jeremiergz"
|
||||
},
|
||||
{
|
||||
"name": "Samuel Ainsworth",
|
||||
"url": "https://github.com/samuela",
|
||||
"githubUsername": "samuela"
|
||||
}
|
||||
],
|
||||
"main": "",
|
||||
"types": "index",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git"
|
||||
},
|
||||
"scripts": {},
|
||||
"dependencies": {},
|
||||
"typesPublisherContentHash": "2ab4e2583634afae0837756aa0330daeca55b67e8b9947d540c0efdd33becf3d",
|
||||
"typeScriptVersion": "2.0"
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "bip32",
|
||||
"version": "2.0.6",
|
||||
"description": "A BIP32 compatible library",
|
||||
"keywords": [
|
||||
"bip32",
|
||||
"bitcoinjs",
|
||||
"bitcoin",
|
||||
"secp256k1"
|
||||
],
|
||||
"main": "./src/index.js",
|
||||
"types": "./types/index.d.ts",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -p ./tsconfig.json",
|
||||
"coverage-report": "npm run build && npm run nobuild:coverage-report",
|
||||
"coverage": "npm run build && npm run nobuild:coverage",
|
||||
"format": "npm run prettier -- --write",
|
||||
"format:ci": "npm run prettier -- --check",
|
||||
"gitdiff:ci": "npm run build && git diff --exit-code",
|
||||
"lint": "tslint -p tsconfig.json -c tslint.json",
|
||||
"nobuild:coverage-report": "nyc report --reporter=lcov",
|
||||
"nobuild:coverage": "nyc --check-coverage --branches 90 --functions 90 npm run nobuild:unit",
|
||||
"nobuild:unit": "tape test/*.js",
|
||||
"prettier": "prettier 'ts-src/**/*.ts' --ignore-path ./.prettierignore",
|
||||
"test": "npm run build && npm run format:ci && npm run lint && npm run nobuild:coverage",
|
||||
"unit": "npm run build && npm run nobuild:unit"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/bitcoinjs/bip32.git"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"types"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/node": "10.12.18",
|
||||
"bs58check": "^2.1.1",
|
||||
"create-hash": "^1.2.0",
|
||||
"create-hmac": "^1.1.7",
|
||||
"tiny-secp256k1": "^1.1.3",
|
||||
"typeforce": "^1.11.5",
|
||||
"wif": "^2.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nyc": "^15.0.0",
|
||||
"prettier": "1.16.4",
|
||||
"tape": "^4.13.2",
|
||||
"tslint": "^6.1.0",
|
||||
"typescript": "3.3.3333"
|
||||
},
|
||||
"author": "Daniel Cousens",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/bitcoinjs/bip32/issues"
|
||||
}
|
||||
}
|
||||
+297
@@ -0,0 +1,297 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const crypto = require("./crypto");
|
||||
const bs58check = require('bs58check');
|
||||
const ecc = require('tiny-secp256k1');
|
||||
const typeforce = require('typeforce');
|
||||
const wif = require('wif');
|
||||
const UINT256_TYPE = typeforce.BufferN(32);
|
||||
const NETWORK_TYPE = typeforce.compile({
|
||||
wif: typeforce.UInt8,
|
||||
bip32: {
|
||||
public: typeforce.UInt32,
|
||||
private: typeforce.UInt32,
|
||||
},
|
||||
});
|
||||
const BITCOIN = {
|
||||
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
||||
bech32: 'bc',
|
||||
bip32: {
|
||||
public: 0x0488b21e,
|
||||
private: 0x0488ade4,
|
||||
},
|
||||
pubKeyHash: 0x00,
|
||||
scriptHash: 0x05,
|
||||
wif: 0x80,
|
||||
};
|
||||
const HIGHEST_BIT = 0x80000000;
|
||||
const UINT31_MAX = Math.pow(2, 31) - 1;
|
||||
function BIP32Path(value) {
|
||||
return (typeforce.String(value) && value.match(/^(m\/)?(\d+'?\/)*\d+'?$/) !== null);
|
||||
}
|
||||
function UInt31(value) {
|
||||
return typeforce.UInt32(value) && value <= UINT31_MAX;
|
||||
}
|
||||
class BIP32 {
|
||||
constructor(__D, __Q, chainCode, network, __DEPTH = 0, __INDEX = 0, __PARENT_FINGERPRINT = 0x00000000) {
|
||||
this.__D = __D;
|
||||
this.__Q = __Q;
|
||||
this.chainCode = chainCode;
|
||||
this.network = network;
|
||||
this.__DEPTH = __DEPTH;
|
||||
this.__INDEX = __INDEX;
|
||||
this.__PARENT_FINGERPRINT = __PARENT_FINGERPRINT;
|
||||
typeforce(NETWORK_TYPE, network);
|
||||
this.lowR = false;
|
||||
}
|
||||
get depth() {
|
||||
return this.__DEPTH;
|
||||
}
|
||||
get index() {
|
||||
return this.__INDEX;
|
||||
}
|
||||
get parentFingerprint() {
|
||||
return this.__PARENT_FINGERPRINT;
|
||||
}
|
||||
get publicKey() {
|
||||
if (this.__Q === undefined)
|
||||
this.__Q = ecc.pointFromScalar(this.__D, true);
|
||||
return this.__Q;
|
||||
}
|
||||
get privateKey() {
|
||||
return this.__D;
|
||||
}
|
||||
get identifier() {
|
||||
return crypto.hash160(this.publicKey);
|
||||
}
|
||||
get fingerprint() {
|
||||
return this.identifier.slice(0, 4);
|
||||
}
|
||||
get compressed() {
|
||||
return true;
|
||||
}
|
||||
// Private === not neutered
|
||||
// Public === neutered
|
||||
isNeutered() {
|
||||
return this.__D === undefined;
|
||||
}
|
||||
neutered() {
|
||||
return fromPublicKeyLocal(this.publicKey, this.chainCode, this.network, this.depth, this.index, this.parentFingerprint);
|
||||
}
|
||||
toBase58() {
|
||||
const network = this.network;
|
||||
const version = !this.isNeutered()
|
||||
? network.bip32.private
|
||||
: network.bip32.public;
|
||||
const buffer = Buffer.allocUnsafe(78);
|
||||
// 4 bytes: version bytes
|
||||
buffer.writeUInt32BE(version, 0);
|
||||
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ....
|
||||
buffer.writeUInt8(this.depth, 4);
|
||||
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
|
||||
buffer.writeUInt32BE(this.parentFingerprint, 5);
|
||||
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized.
|
||||
// This is encoded in big endian. (0x00000000 if master key)
|
||||
buffer.writeUInt32BE(this.index, 9);
|
||||
// 32 bytes: the chain code
|
||||
this.chainCode.copy(buffer, 13);
|
||||
// 33 bytes: the public key or private key data
|
||||
if (!this.isNeutered()) {
|
||||
// 0x00 + k for private keys
|
||||
buffer.writeUInt8(0, 45);
|
||||
this.privateKey.copy(buffer, 46);
|
||||
// 33 bytes: the public key
|
||||
}
|
||||
else {
|
||||
// X9.62 encoding for public keys
|
||||
this.publicKey.copy(buffer, 45);
|
||||
}
|
||||
return bs58check.encode(buffer);
|
||||
}
|
||||
toWIF() {
|
||||
if (!this.privateKey)
|
||||
throw new TypeError('Missing private key');
|
||||
return wif.encode(this.network.wif, this.privateKey, true);
|
||||
}
|
||||
// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions
|
||||
derive(index) {
|
||||
typeforce(typeforce.UInt32, index);
|
||||
const isHardened = index >= HIGHEST_BIT;
|
||||
const data = Buffer.allocUnsafe(37);
|
||||
// Hardened child
|
||||
if (isHardened) {
|
||||
if (this.isNeutered())
|
||||
throw new TypeError('Missing private key for hardened child key');
|
||||
// data = 0x00 || ser256(kpar) || ser32(index)
|
||||
data[0] = 0x00;
|
||||
this.privateKey.copy(data, 1);
|
||||
data.writeUInt32BE(index, 33);
|
||||
// Normal child
|
||||
}
|
||||
else {
|
||||
// data = serP(point(kpar)) || ser32(index)
|
||||
// = serP(Kpar) || ser32(index)
|
||||
this.publicKey.copy(data, 0);
|
||||
data.writeUInt32BE(index, 33);
|
||||
}
|
||||
const I = crypto.hmacSHA512(this.chainCode, data);
|
||||
const IL = I.slice(0, 32);
|
||||
const IR = I.slice(32);
|
||||
// if parse256(IL) >= n, proceed with the next value for i
|
||||
if (!ecc.isPrivate(IL))
|
||||
return this.derive(index + 1);
|
||||
// Private parent key -> private child key
|
||||
let hd;
|
||||
if (!this.isNeutered()) {
|
||||
// ki = parse256(IL) + kpar (mod n)
|
||||
const ki = ecc.privateAdd(this.privateKey, IL);
|
||||
// In case ki == 0, proceed with the next value for i
|
||||
if (ki == null)
|
||||
return this.derive(index + 1);
|
||||
hd = fromPrivateKeyLocal(ki, IR, this.network, this.depth + 1, index, this.fingerprint.readUInt32BE(0));
|
||||
// Public parent key -> public child key
|
||||
}
|
||||
else {
|
||||
// Ki = point(parse256(IL)) + Kpar
|
||||
// = G*IL + Kpar
|
||||
const Ki = ecc.pointAddScalar(this.publicKey, IL, true);
|
||||
// In case Ki is the point at infinity, proceed with the next value for i
|
||||
if (Ki === null)
|
||||
return this.derive(index + 1);
|
||||
hd = fromPublicKeyLocal(Ki, IR, this.network, this.depth + 1, index, this.fingerprint.readUInt32BE(0));
|
||||
}
|
||||
return hd;
|
||||
}
|
||||
deriveHardened(index) {
|
||||
typeforce(UInt31, index);
|
||||
// Only derives hardened private keys by default
|
||||
return this.derive(index + HIGHEST_BIT);
|
||||
}
|
||||
derivePath(path) {
|
||||
typeforce(BIP32Path, path);
|
||||
let splitPath = path.split('/');
|
||||
if (splitPath[0] === 'm') {
|
||||
if (this.parentFingerprint)
|
||||
throw new TypeError('Expected master, got child');
|
||||
splitPath = splitPath.slice(1);
|
||||
}
|
||||
return splitPath.reduce((prevHd, indexStr) => {
|
||||
let index;
|
||||
if (indexStr.slice(-1) === `'`) {
|
||||
index = parseInt(indexStr.slice(0, -1), 10);
|
||||
return prevHd.deriveHardened(index);
|
||||
}
|
||||
else {
|
||||
index = parseInt(indexStr, 10);
|
||||
return prevHd.derive(index);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
sign(hash, lowR) {
|
||||
if (!this.privateKey)
|
||||
throw new Error('Missing private key');
|
||||
if (lowR === undefined)
|
||||
lowR = this.lowR;
|
||||
if (lowR === false) {
|
||||
return ecc.sign(hash, this.privateKey);
|
||||
}
|
||||
else {
|
||||
let sig = ecc.sign(hash, this.privateKey);
|
||||
const extraData = Buffer.alloc(32, 0);
|
||||
let counter = 0;
|
||||
// if first try is lowR, skip the loop
|
||||
// for second try and on, add extra entropy counting up
|
||||
while (sig[0] > 0x7f) {
|
||||
counter++;
|
||||
extraData.writeUIntLE(counter, 0, 6);
|
||||
sig = ecc.signWithEntropy(hash, this.privateKey, extraData);
|
||||
}
|
||||
return sig;
|
||||
}
|
||||
}
|
||||
verify(hash, signature) {
|
||||
return ecc.verify(hash, this.publicKey, signature);
|
||||
}
|
||||
}
|
||||
function fromBase58(inString, network) {
|
||||
const buffer = bs58check.decode(inString);
|
||||
if (buffer.length !== 78)
|
||||
throw new TypeError('Invalid buffer length');
|
||||
network = network || BITCOIN;
|
||||
// 4 bytes: version bytes
|
||||
const version = buffer.readUInt32BE(0);
|
||||
if (version !== network.bip32.private && version !== network.bip32.public)
|
||||
throw new TypeError('Invalid network version');
|
||||
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ...
|
||||
const depth = buffer[4];
|
||||
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
|
||||
const parentFingerprint = buffer.readUInt32BE(5);
|
||||
if (depth === 0) {
|
||||
if (parentFingerprint !== 0x00000000)
|
||||
throw new TypeError('Invalid parent fingerprint');
|
||||
}
|
||||
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized.
|
||||
// This is encoded in MSB order. (0x00000000 if master key)
|
||||
const index = buffer.readUInt32BE(9);
|
||||
if (depth === 0 && index !== 0)
|
||||
throw new TypeError('Invalid index');
|
||||
// 32 bytes: the chain code
|
||||
const chainCode = buffer.slice(13, 45);
|
||||
let hd;
|
||||
// 33 bytes: private key data (0x00 + k)
|
||||
if (version === network.bip32.private) {
|
||||
if (buffer.readUInt8(45) !== 0x00)
|
||||
throw new TypeError('Invalid private key');
|
||||
const k = buffer.slice(46, 78);
|
||||
hd = fromPrivateKeyLocal(k, chainCode, network, depth, index, parentFingerprint);
|
||||
// 33 bytes: public key data (0x02 + X or 0x03 + X)
|
||||
}
|
||||
else {
|
||||
const X = buffer.slice(45, 78);
|
||||
hd = fromPublicKeyLocal(X, chainCode, network, depth, index, parentFingerprint);
|
||||
}
|
||||
return hd;
|
||||
}
|
||||
exports.fromBase58 = fromBase58;
|
||||
function fromPrivateKey(privateKey, chainCode, network) {
|
||||
return fromPrivateKeyLocal(privateKey, chainCode, network);
|
||||
}
|
||||
exports.fromPrivateKey = fromPrivateKey;
|
||||
function fromPrivateKeyLocal(privateKey, chainCode, network, depth, index, parentFingerprint) {
|
||||
typeforce({
|
||||
privateKey: UINT256_TYPE,
|
||||
chainCode: UINT256_TYPE,
|
||||
}, { privateKey, chainCode });
|
||||
network = network || BITCOIN;
|
||||
if (!ecc.isPrivate(privateKey))
|
||||
throw new TypeError('Private key not in range [1, n)');
|
||||
return new BIP32(privateKey, undefined, chainCode, network, depth, index, parentFingerprint);
|
||||
}
|
||||
function fromPublicKey(publicKey, chainCode, network) {
|
||||
return fromPublicKeyLocal(publicKey, chainCode, network);
|
||||
}
|
||||
exports.fromPublicKey = fromPublicKey;
|
||||
function fromPublicKeyLocal(publicKey, chainCode, network, depth, index, parentFingerprint) {
|
||||
typeforce({
|
||||
publicKey: typeforce.BufferN(33),
|
||||
chainCode: UINT256_TYPE,
|
||||
}, { publicKey, chainCode });
|
||||
network = network || BITCOIN;
|
||||
// verify the X coordinate is a point on the curve
|
||||
if (!ecc.isPoint(publicKey))
|
||||
throw new TypeError('Point is not on the curve');
|
||||
return new BIP32(undefined, publicKey, chainCode, network, depth, index, parentFingerprint);
|
||||
}
|
||||
function fromSeed(seed, network) {
|
||||
typeforce(typeforce.Buffer, seed);
|
||||
if (seed.length < 16)
|
||||
throw new TypeError('Seed should be at least 128 bits');
|
||||
if (seed.length > 64)
|
||||
throw new TypeError('Seed should be at most 512 bits');
|
||||
network = network || BITCOIN;
|
||||
const I = crypto.hmacSHA512(Buffer.from('Bitcoin seed', 'utf8'), seed);
|
||||
const IL = I.slice(0, 32);
|
||||
const IR = I.slice(32);
|
||||
return fromPrivateKey(IL, IR, network);
|
||||
}
|
||||
exports.fromSeed = fromSeed;
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const createHash = require('create-hash');
|
||||
const createHmac = require('create-hmac');
|
||||
function hash160(buffer) {
|
||||
const sha256Hash = createHash('sha256')
|
||||
.update(buffer)
|
||||
.digest();
|
||||
try {
|
||||
return createHash('rmd160')
|
||||
.update(sha256Hash)
|
||||
.digest();
|
||||
}
|
||||
catch (err) {
|
||||
return createHash('ripemd160')
|
||||
.update(sha256Hash)
|
||||
.digest();
|
||||
}
|
||||
}
|
||||
exports.hash160 = hash160;
|
||||
function hmacSHA512(key, data) {
|
||||
return createHmac('sha512', key)
|
||||
.update(data)
|
||||
.digest();
|
||||
}
|
||||
exports.hmacSHA512 = hmacSHA512;
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var bip32_1 = require("./bip32");
|
||||
exports.fromSeed = bip32_1.fromSeed;
|
||||
exports.fromBase58 = bip32_1.fromBase58;
|
||||
exports.fromPublicKey = bip32_1.fromPublicKey;
|
||||
exports.fromPrivateKey = bip32_1.fromPrivateKey;
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/// <reference types="node" />
|
||||
interface Network {
|
||||
wif: number;
|
||||
bip32: {
|
||||
public: number;
|
||||
private: number;
|
||||
};
|
||||
messagePrefix?: string;
|
||||
bech32?: string;
|
||||
pubKeyHash?: number;
|
||||
scriptHash?: number;
|
||||
}
|
||||
export interface BIP32Interface {
|
||||
chainCode: Buffer;
|
||||
network: Network;
|
||||
lowR: boolean;
|
||||
depth: number;
|
||||
index: number;
|
||||
parentFingerprint: number;
|
||||
publicKey: Buffer;
|
||||
privateKey?: Buffer;
|
||||
identifier: Buffer;
|
||||
fingerprint: Buffer;
|
||||
isNeutered(): boolean;
|
||||
neutered(): BIP32Interface;
|
||||
toBase58(): string;
|
||||
toWIF(): string;
|
||||
derive(index: number): BIP32Interface;
|
||||
deriveHardened(index: number): BIP32Interface;
|
||||
derivePath(path: string): BIP32Interface;
|
||||
sign(hash: Buffer, lowR?: boolean): Buffer;
|
||||
verify(hash: Buffer, signature: Buffer): boolean;
|
||||
}
|
||||
export declare function fromBase58(inString: string, network?: Network): BIP32Interface;
|
||||
export declare function fromPrivateKey(privateKey: Buffer, chainCode: Buffer, network?: Network): BIP32Interface;
|
||||
export declare function fromPublicKey(publicKey: Buffer, chainCode: Buffer, network?: Network): BIP32Interface;
|
||||
export declare function fromSeed(seed: Buffer, network?: Network): BIP32Interface;
|
||||
export {};
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
/// <reference types="node" />
|
||||
export declare function hash160(buffer: Buffer): Buffer;
|
||||
export declare function hmacSHA512(key: Buffer, data: Buffer): Buffer;
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { BIP32Interface, fromSeed, fromBase58, fromPublicKey, fromPrivateKey, } from './bip32';
|
||||
Reference in New Issue
Block a user