UNPKG

n8n-nodes-wax

Version:

n8n Community Node Package for the WAX Blockchain

366 lines (287 loc) 9.79 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var ecurve = require('ecurve'); var Point = ecurve.Point; var secp256k1 = ecurve.getCurveByName('secp256k1'); var BigInteger = require('bigi'); var assert = require('assert'); var hash = require('./hash'); var PublicKey = require('./key_public'); var keyUtils = require('./key_utils'); var createHash = require('create-hash'); var promiseAsync = require('./promise-async'); var G = secp256k1.G; var n = secp256k1.n; module.exports = PrivateKey; /** @typedef {string} wif - https://en.bitcoin.it/wiki/Wallet_import_format @typedef {string} pubkey - EOSKey.. @typedef {ecurve.Point} Point */ /** @param {BigInteger} d */ function PrivateKey(d) { if (typeof d === 'string') { return PrivateKey.fromString(d); } else if (Buffer.isBuffer(d)) { return PrivateKey.fromBuffer(d); } else if ((0, _typeof2["default"])(d) === 'object' && BigInteger.isBigInteger(d.d)) { return PrivateKey(d.d); } if (!BigInteger.isBigInteger(d)) { throw new TypeError('Invalid private key'); } /** @return {string} private key like PVT_K1_base58privatekey.. */ function toString() { // todo, use PVT_K1_ // return 'PVT_K1_' + keyUtils.checkEncode(toBuffer(), 'K1') return toWif(); } /** @return {wif} */ function toWif() { var private_key = toBuffer(); // checksum includes the version private_key = Buffer.concat([new Buffer([0x80]), private_key]); return keyUtils.checkEncode(private_key, 'sha256x2'); } var public_key; /** @return {Point} */ function toPublic() { if (public_key) { // cache // S L O W in the browser return public_key; } var Q = secp256k1.G.multiply(d); return public_key = PublicKey.fromPoint(Q); } function toBuffer() { return d.toBuffer(32); } /** ECIES @arg {string|Object} pubkey wif, PublicKey object @return {Buffer} 64 byte shared secret */ function getSharedSecret(public_key) { public_key = PublicKey(public_key); var KB = public_key.toUncompressed().toBuffer(); var KBP = Point.fromAffine(secp256k1, BigInteger.fromBuffer(KB.slice(1, 33)), // x BigInteger.fromBuffer(KB.slice(33, 65)) // y ); var r = toBuffer(); var P = KBP.multiply(BigInteger.fromBuffer(r)); var S = P.affineX.toBuffer({ size: 32 }); // SHA512 used in ECIES return hash.sha512(S); } // /** ECIES TODO unit test // @arg {string|Object} pubkey wif, PublicKey object // @return {Buffer} 64 byte shared secret // */ // function getSharedSecret(public_key) { // public_key = PublicKey(public_key).toUncompressed() // var P = public_key.Q.multiply( d ); // var S = P.affineX.toBuffer({size: 32}); // // ECIES, adds an extra sha512 // return hash.sha512(S); // } /** @arg {string} name - child key name. @return {PrivateKey} @example activePrivate = masterPrivate.getChildKey('owner').getChildKey('active') @example activePrivate.getChildKey('mycontract').getChildKey('myperm') */ function getChildKey(name) { // console.error('WARNING: getChildKey untested against eosd'); // no eosd impl yet var index = createHash('sha256').update(toBuffer()).update(name).digest(); return PrivateKey(index); } function toHex() { return toBuffer().toString('hex'); } return { d: d, toWif: toWif, toString: toString, toPublic: toPublic, toBuffer: toBuffer, getSharedSecret: getSharedSecret, getChildKey: getChildKey }; } /** @private */ function parseKey(privateStr) { assert.equal((0, _typeof2["default"])(privateStr), 'string', 'privateStr'); var match = privateStr.match(/^PVT_([A-Za-z0-9]+)_([A-Za-z0-9]+)$/); if (match === null) { // legacy WIF - checksum includes the version var versionKey = keyUtils.checkDecode(privateStr, 'sha256x2'); var version = versionKey.readUInt8(0); assert.equal(0x80, version, "Expected version ".concat(0x80, ", instead got ", version)); var _privateKey = PrivateKey.fromBuffer(versionKey.slice(1)); var _keyType = 'K1'; var format = 'WIF'; return { privateKey: _privateKey, format: format, keyType: _keyType }; } assert(match.length === 3, 'Expecting private key like: PVT_K1_base58privateKey..'); var _match = (0, _slicedToArray2["default"])(match, 3), keyType = _match[1], keyString = _match[2]; assert.equal(keyType, 'K1', 'K1 private key expected'); var privateKey = PrivateKey.fromBuffer(keyUtils.checkDecode(keyString, keyType)); return { privateKey: privateKey, format: 'PVT', keyType: keyType }; } PrivateKey.fromHex = function (hex) { return PrivateKey.fromBuffer(new Buffer(hex, 'hex')); }; PrivateKey.fromBuffer = function (buf) { if (!Buffer.isBuffer(buf)) { throw new Error("Expecting parameter to be a Buffer type"); } if (buf.length === 33 && buf[32] === 1) { // remove compression flag buf = buf.slice(0, -1); } if (32 !== buf.length) { throw new Error("Expecting 32 bytes, instead got ".concat(buf.length)); } return PrivateKey(BigInteger.fromBuffer(buf)); }; /** @arg {string} seed - any length string. This is private, the same seed produces the same private key every time. @return {PrivateKey} */ PrivateKey.fromSeed = function (seed) { // generate_private_key if (!(typeof seed === 'string')) { throw new Error('seed must be of type string'); } return PrivateKey.fromBuffer(hash.sha256(seed)); }; /** @arg {wif} key @return {boolean} true if key is in the Wallet Import Format */ PrivateKey.isWif = function (text) { try { assert(parseKey(text).format === 'WIF'); return true; } catch (e) { return false; } }; /** @arg {wif|Buffer|PrivateKey} key @return {boolean} true if key is convertable to a private key object. */ PrivateKey.isValid = function (key) { try { PrivateKey(key); return true; } catch (e) { return false; } }; /** @deprecated */ PrivateKey.fromWif = function (str) { console.log('PrivateKey.fromWif is deprecated, please use PrivateKey.fromString'); return PrivateKey.fromString(str); }; /** @throws {AssertError|Error} parsing key @arg {string} privateStr Eosio or Wallet Import Format (wif) -- a secret */ PrivateKey.fromString = function (privateStr) { return parseKey(privateStr).privateKey; }; /** Create a new random private key. Call initialize() first to run some self-checking code and gather some CPU entropy. @arg {number} [cpuEntropyBits = 0] - additional CPU entropy, this already happens once so it should not be needed again. @return {Promise<PrivateKey>} - random private key */ PrivateKey.randomKey = function () { var cpuEntropyBits = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; return PrivateKey.initialize().then(function () { return PrivateKey.fromBuffer(keyUtils.random32ByteBuffer({ cpuEntropyBits: cpuEntropyBits })); }); }; /** @return {Promise<PrivateKey>} for testing, does not require initialize(). */ PrivateKey.unsafeRandomKey = function () { return Promise.resolve(PrivateKey.fromBuffer(keyUtils.random32ByteBuffer({ safe: false }))); }; var initialized = false, unitTested = false; /** Run self-checking code and gather CPU entropy. Initialization happens once even if called multiple times. @return {Promise} */ function initialize() { if (initialized) { return; } unitTest(); keyUtils.addEntropy.apply(keyUtils, (0, _toConsumableArray2["default"])(keyUtils.cpuEntropy())); assert(keyUtils.entropyCount() >= 128, 'insufficient entropy'); initialized = true; } PrivateKey.initialize = promiseAsync(initialize); /** Unit test basic private and public key functionality. @throws {AssertError} */ function unitTest() { var pvt = PrivateKey(hash.sha256('')); var pvtError = 'key comparison test failed on a known private key'; assert.equal(pvt.toWif(), '5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss', pvtError); assert.equal(pvt.toString(), '5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss', pvtError); // assert.equal(pvt.toString(), 'PVT_K1_2jH3nnhxhR3zPUcsKaWWZC9ZmZAnKm3GAnFD1xynGJE1Znuvjd', pvtError) var pub = pvt.toPublic(); var pubError = 'pubkey string comparison test failed on a known public key'; assert.equal(pub.toString(), 'EOS859gxfnXyUriMgUeThh1fWv3oqcpLFyHa3TfFYC4PK2HqhToVM', pubError); // assert.equal(pub.toString(), 'PUB_K1_859gxfnXyUriMgUeThh1fWv3oqcpLFyHa3TfFYC4PK2Ht7beeX', pubError) // assert.equal(pub.toStringLegacy(), 'EOS859gxfnXyUriMgUeThh1fWv3oqcpLFyHa3TfFYC4PK2HqhToVM', pubError) doesNotThrow(function () { return PrivateKey.fromString(pvt.toWif()); }, 'converting known wif from string'); doesNotThrow(function () { return PrivateKey.fromString(pvt.toString()); }, 'converting known pvt from string'); doesNotThrow(function () { return PublicKey.fromString(pub.toString()); }, 'converting known public key from string'); // doesNotThrow(() => PublicKey.fromString(pub.toStringLegacy()), 'converting known public key from string') unitTested = true; } /** @private */ var doesNotThrow = function doesNotThrow(cb, msg) { try { cb(); } catch (error) { error.message = "".concat(msg, " ==> ").concat(error.message); throw error; } };