UNPKG

eth-lightwallet

Version:

A lightweight ethereum javascript wallet.

1,467 lines (1,155 loc) 2.57 MB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.lightwallet = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ "use strict"; module.exports = { txutils: require('./lib/txutils.js'), encryption: require('./lib/encryption.js'), signing: require('./lib/signing.js'), keystore: require('./lib/keystore.js'), upgrade: require('./lib/upgrade.js') }; },{"./lib/encryption.js":3,"./lib/keystore.js":4,"./lib/signing.js":5,"./lib/txutils.js":6,"./lib/upgrade.js":7}],2:[function(require,module,exports){ "use strict"; function derivedKey(keystore, pwDerivedKey) { if (!keystore.isDerivedKeyCorrect(pwDerivedKey)) { throw new Error('Incorrect derived key!'); } } module.exports = { derivedKey: derivedKey }; },{}],3:[function(require,module,exports){ (function (Buffer){ "use strict"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { keys.push.apply(keys, Object.getOwnPropertySymbols(object)); } if (enumerableOnly) keys = keys.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var Nacl = require('tweetnacl'); var NaclUtil = require('tweetnacl-util'); var Assert = require('./assert'); function encodeHex(msgUInt8Arr) { var msgBase64 = NaclUtil.encodeBase64(msgUInt8Arr); return new Buffer(msgBase64, 'base64').toString('hex'); } function decodeHex(msgHex) { var msgBase64 = new Buffer(msgHex, 'hex').toString('base64'); return NaclUtil.decodeBase64(msgBase64); } function asymEncryptRaw(keystore, pwDerivedKey, msgUint8Array, myAddress, theirPubKey) { Assert.derivedKey(keystore, pwDerivedKey); var privateKey = keystore.exportPrivateKey(myAddress, pwDerivedKey); var privateKeyUInt8Array = decodeHex(privateKey); var pubKeyUInt8Array = decodeHex(theirPubKey); var nonce = Nacl.randomBytes(Nacl.box.nonceLength); var encryptedMessage = Nacl.box(msgUint8Array, nonce, pubKeyUInt8Array, privateKeyUInt8Array); return { alg: 'curve25519-xsalsa20-poly1305', nonce: NaclUtil.encodeBase64(nonce), ciphertext: NaclUtil.encodeBase64(encryptedMessage) }; } function asymDecryptRaw(keystore, pwDerivedKey, encMsg, theirPubKey, myAddress) { Assert.derivedKey(keystore, pwDerivedKey); var privateKey = keystore.exportPrivateKey(myAddress, pwDerivedKey); var privateKeyUInt8Array = decodeHex(privateKey); var pubKeyUInt8Array = decodeHex(theirPubKey); var nonce = NaclUtil.decodeBase64(encMsg.nonce); var cipherText = NaclUtil.decodeBase64(encMsg.ciphertext); var clearText = Nacl.box.open(cipherText, nonce, pubKeyUInt8Array, privateKeyUInt8Array); return clearText; } function asymEncryptString(keystore, pwDerivedKey, msg, myAddress, theirPubKey) { Assert.derivedKey(keystore, pwDerivedKey); var messageUInt8Array = NaclUtil.decodeUTF8(msg); return asymEncryptRaw(keystore, pwDerivedKey, messageUInt8Array, myAddress, theirPubKey); } function asymDecryptString(keystore, pwDerivedKey, encMsg, theirPubKey, myAddress) { Assert.derivedKey(keystore, pwDerivedKey); var clearText = asymDecryptRaw(keystore, pwDerivedKey, encMsg, theirPubKey, myAddress); if (clearText === null) { return false; } return NaclUtil.encodeUTF8(clearText); } function multiEncryptString(keystore, pwDerivedKey, msg, myAddress, theirPubKeyArray) { Assert.derivedKey(keystore, pwDerivedKey); var messageUInt8Array = NaclUtil.decodeUTF8(msg); var symEncryptionKey = Nacl.randomBytes(Nacl.secretbox.keyLength); var symNonce = Nacl.randomBytes(Nacl.secretbox.nonceLength); var symEncMessage = Nacl.secretbox(messageUInt8Array, symNonce, symEncryptionKey); if (theirPubKeyArray.length < 1) { throw new Error('Found no pubkeys to encrypt to.'); } var encryptedSymKey = theirPubKeyArray.map(function (theirPubKey) { var _asymEncryptRaw = asymEncryptRaw(keystore, pwDerivedKey, symEncryptionKey, myAddress, theirPubKey), alg = _asymEncryptRaw.alg, props = _objectWithoutProperties(_asymEncryptRaw, ["alg"]); return _objectSpread({}, props); }); return { version: 1, asymAlg: 'curve25519-xsalsa20-poly1305', symAlg: 'xsalsa20-poly1305', symNonce: NaclUtil.encodeBase64(symNonce), symEncMessage: NaclUtil.encodeBase64(symEncMessage), encryptedSymKey: encryptedSymKey }; } function multiDecryptString(keystore, pwDerivedKey, encMsg, theirPubKey, myAddress) { Assert.derivedKey(keystore, pwDerivedKey); var symKey = null; for (var i = 0; i < encMsg.encryptedSymKey.length; i++) { var result = asymDecryptRaw(keystore, pwDerivedKey, encMsg.encryptedSymKey[i], theirPubKey, myAddress); if (result !== null) { symKey = result; break; } } if (symKey === null) { return false; } var symNonce = NaclUtil.decodeBase64(encMsg.symNonce); var symEncMessage = NaclUtil.decodeBase64(encMsg.symEncMessage); var msg = Nacl.secretbox.open(symEncMessage, symNonce, symKey); if (msg === null) { return false; } return NaclUtil.encodeUTF8(msg); } function addressToPublicEncKey(keystore, pwDerivedKey, address) { Assert.derivedKey(keystore, pwDerivedKey); var privateKey = keystore.exportPrivateKey(address, pwDerivedKey); var privateKeyUInt8Array = decodeHex(privateKey); var pubKeyUInt8Array = Nacl.box.keyPair.fromSecretKey(privateKeyUInt8Array).publicKey; return encodeHex(pubKeyUInt8Array); } module.exports = { encodeHex: encodeHex, decodeHex: decodeHex, asymEncryptString: asymEncryptString, asymDecryptString: asymDecryptString, multiEncryptString: multiEncryptString, multiDecryptString: multiDecryptString, addressToPublicEncKey: addressToPublicEncKey }; }).call(this,require("buffer").Buffer) },{"./assert":2,"buffer":138,"tweetnacl":311,"tweetnacl-util":310}],4:[function(require,module,exports){ (function (Buffer){ "use strict"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { keys.push.apply(keys, Object.getOwnPropertySymbols(object)); } if (enumerableOnly) keys = keys.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var CryptoJS = require('crypto-js'); var Util = require('ethereumjs-util'); var EC = require('elliptic').ec; var BitCore = require('bitcore-lib'); var Random = BitCore.crypto.Random; var Hash = BitCore.crypto.Hash; var Mnemonic = require('bitcore-mnemonic'); var Nacl = require('tweetnacl'); var NaclUtil = require('tweetnacl-util'); var ScryptAsync = require('scrypt-async'); var Assert = require('./assert'); var Encryption = require('./encryption'); var Signing = require('./signing'); var TxUtils = require('./txutils'); var ec = new EC('secp256k1'); function leftPadString(stringToPad, padChar, length) { var repeatedPadChar = ''; for (var i = 0; i < length; i++) { repeatedPadChar += padChar; } return (repeatedPadChar + stringToPad).slice(-length); } var KeyStore = function KeyStore() {}; KeyStore.prototype.init = function (mnemonic, pwDerivedKey, hdPathString, salt) { this.salt = salt; this.hdPathString = hdPathString; this.encSeed = undefined; this.encHdRootPriv = undefined; this.version = 3; this.hdIndex = 0; this.encPrivKeys = {}; this.addresses = []; if (typeof pwDerivedKey !== 'undefined' && typeof mnemonic !== 'undefined') { var words = mnemonic.split(' '); if (!KeyStore.isSeedValid(mnemonic) || words.length !== 12) { throw new Error('KeyStore: Invalid mnemonic'); } // Pad the seed to length 120 before encrypting var paddedSeed = leftPadString(mnemonic, ' ', 120); this.encSeed = KeyStore._encryptString(paddedSeed, pwDerivedKey); // hdRoot is the relative root from which we derive the keys using generateNewAddress(). // The derived keys are then `hdRoot/hdIndex`. var hdRoot = new Mnemonic(mnemonic).toHDPrivateKey().xprivkey; var hdRootKey = new BitCore.HDPrivateKey(hdRoot); var hdPathKey = hdRootKey.derive(hdPathString).xprivkey; this.encHdRootPriv = KeyStore._encryptString(hdPathKey, pwDerivedKey); } }; KeyStore.prototype.isDerivedKeyCorrect = function (pwDerivedKey) { var paddedSeed = KeyStore._decryptString(this.encSeed, pwDerivedKey); return paddedSeed && paddedSeed.length > 0; }; KeyStore.prototype.serialize = function () { return JSON.stringify({ encSeed: this.encSeed, encHdRootPriv: this.encHdRootPriv, addresses: this.addresses, encPrivKeys: this.encPrivKeys, hdPathString: this.hdPathString, salt: this.salt, hdIndex: this.hdIndex, version: this.version }); }; KeyStore.prototype.getAddresses = function () { return this.addresses.map(function (addr) { return Util.addHexPrefix(addr); }); }; KeyStore.prototype.getSeed = function (pwDerivedKey) { Assert.derivedKey(this, pwDerivedKey); var paddedSeed = KeyStore._decryptString(this.encSeed, pwDerivedKey); if (!paddedSeed || paddedSeed.length === 0) { throw new Error('Provided password derived key is wrong'); } return paddedSeed.trim(); }; KeyStore.prototype.exportPrivateKey = function (address, pwDerivedKey) { Assert.derivedKey(this, pwDerivedKey); var addr = Util.stripHexPrefix(address).toLowerCase(); if (this.encPrivKeys[addr] === undefined) { throw new Error('KeyStore.exportPrivateKey: Address not found in KeyStore'); } var encPrivateKey = this.encPrivKeys[addr]; return KeyStore._decryptKey(encPrivateKey, pwDerivedKey); }; KeyStore.prototype.generateNewAddress = function (pwDerivedKey, n) { Assert.derivedKey(this, pwDerivedKey); if (!this.encSeed) { throw new Error('KeyStore.generateNewAddress: No seed set'); } n = n || 1; var keys = this._generatePrivKeys(pwDerivedKey, n); for (var i = 0; i < n; i++) { var keyObj = keys[i]; var address = KeyStore._computeAddressFromPrivKey(keyObj.privKey); this.encPrivKeys[address] = keyObj.encPrivKey; this.addresses.push(address); } }; KeyStore.prototype.keyFromPassword = function (password, callback) { KeyStore.deriveKeyFromPasswordAndSalt(password, this.salt, callback); }; KeyStore.prototype.passwordProvider = function (callback) { var password = prompt('Enter password to continue', 'Enter password'); callback(null, password); }; KeyStore.prototype.hasAddress = function (address, callback) { var addrToCheck = Util.stripHexPrefix(address); if (this.encPrivKeys[addrToCheck] === undefined) { var err = new Error('Address not found!'); callback(err, false); return; } callback(null, true); }; KeyStore.prototype.signTransaction = function (txParams, callback) { var _this = this; var gas = txParams.gas, params = _objectWithoutProperties(txParams, ["gas"]); var txObj = _objectSpread({}, params, { gasLimit: gas }); var tx = TxUtils.createTx(txObj); var rawTx = TxUtils.txToHexString(tx); var signingAddress = Util.stripHexPrefix(txParams.from); this.passwordProvider(function (err, password) { if (err) { callback(err); return; } _this.keyFromPassword(password, function (err, pwDerivedKey) { if (err) { callback(err); return; } var signedTx = Signing.signTx(_this, pwDerivedKey, rawTx, signingAddress); callback(null, Util.addHexPrefix(signedTx)); }); }); }; KeyStore.prototype._generatePrivKeys = function (pwDerivedKey, n) { Assert.derivedKey(this, pwDerivedKey); var hdRoot = KeyStore._decryptString(this.encHdRootPriv, pwDerivedKey); if (!hdRoot || hdRoot.length === 0) { throw new Error('Provided password derived key is wrong'); } var keys = []; for (var i = 0; i < n; i++) { var hdPrivateKey = new BitCore.HDPrivateKey(hdRoot).derive(this.hdIndex++); var privateKeyBuf = hdPrivateKey.privateKey.toBuffer(); var privateKeyHex = privateKeyBuf.toString('hex'); if (privateKeyBuf.length < 16) { // Way too small key, something must have gone wrong // Halt and catch fire throw new Error('Private key suspiciously small: < 16 bytes. Aborting!'); } else if (privateKeyBuf.length > 32) { throw new Error('Private key larger than 32 bytes. Aborting!'); } else if (privateKeyBuf.length < 32) { // Pad private key if too short // bitcore has a bug where it sometimes returns // truncated keys privateKeyHex = leftPadString(privateKeyBuf.toString('hex'), '0', 64); } var encPrivateKey = KeyStore._encryptKey(privateKeyHex, pwDerivedKey); keys[i] = { privKey: privateKeyHex, encPrivKey: encPrivateKey }; } return keys; }; KeyStore.createVault = function (opts, cb) { var hdPathString = opts.hdPathString, seedPhrase = opts.seedPhrase, password = opts.password; var salt = opts.salt; // Default hdPathString if (!hdPathString) { var err = new Error('Keystore: Must include hdPathString in createVault inputs. Suggested alternatives are m/0\'/0\'/0\' for previous lightwallet default, or m/44\'/60\'/0\'/0 for BIP44 (used by Jaxx & MetaMask)'); return cb(err); } if (!seedPhrase) { var _err = new Error('Keystore: Must include seedPhrase in createVault inputs.'); return cb(_err); } if (!salt) { salt = KeyStore.generateSalt(32); } KeyStore.deriveKeyFromPasswordAndSalt(password, salt, function (err, pwDerivedKey) { if (err) { cb(err); return; } var ks = new KeyStore(); ks.init(seedPhrase, pwDerivedKey, hdPathString, salt); cb(null, ks); }); }; KeyStore.generateSalt = function (byteCount) { return BitCore.crypto.Random.getRandomBuffer(byteCount || 32).toString('base64'); }; // Generates a random seed. If the optional string extraEntropy is set, // a random set of entropy is created, then concatenated with extraEntropy // and hashed to produce the entropy that gives the seed. // Thus if extraEntropy comes from a high-entropy source (like dice) // it can give some protection from a bad RNG. // If extraEntropy is not set, the random number generator is used directly. KeyStore.generateRandomSeed = function (extraEntropy) { var seed = ''; if (extraEntropy === undefined) { seed = new Mnemonic(Mnemonic.Words.ENGLISH); } else if (typeof extraEntropy === 'string') { var entBuf = new Buffer(extraEntropy); var randBuf = Random.getRandomBuffer(256 / 8); var hashedEnt = this._concatAndSha256(randBuf, entBuf).slice(0, 128 / 8); seed = new Mnemonic(hashedEnt, Mnemonic.Words.ENGLISH); } else { throw new Error('generateRandomSeed: extraEntropy is set but not a string.'); } return seed.toString(); }; KeyStore.isSeedValid = function (seed) { return Mnemonic.isValid(seed, Mnemonic.Words.ENGLISH); }; KeyStore.deserialize = function (keystore) { var dataKS = JSON.parse(keystore); var version = dataKS.version, salt = dataKS.salt, encSeed = dataKS.encSeed, encHdRootPriv = dataKS.encHdRootPriv, encPrivKeys = dataKS.encPrivKeys, hdIndex = dataKS.hdIndex, hdPathString = dataKS.hdPathString, addresses = dataKS.addresses; if (version === undefined || version < 3) { throw new Error('Old version of serialized keystore. Please use KeyStore.upgradeOldSerialized() to convert it to the latest version.'); } var ks = new KeyStore(); ks.salt = salt; ks.hdPathString = hdPathString; ks.encSeed = encSeed; ks.encHdRootPriv = encHdRootPriv; ks.version = version; ks.hdIndex = hdIndex; ks.encPrivKeys = encPrivKeys; ks.addresses = addresses; return ks; }; KeyStore.deriveKeyFromPasswordAndSalt = function (password, salt, callback) { // Do not require salt, and default it to 'lightwalletSalt' // (for backwards compatibility) if (!callback && typeof salt === 'function') { callback = salt; salt = KeyStore.DEFAULT_SALT; } else if (!salt && typeof callback === 'function') { salt = KeyStore.DEFAULT_SALT; } var logN = 14; var r = 8; var dkLen = 32; var interruptStep = 200; var cb = function cb(derKey) { var err = null; var ui8arr = null; try { ui8arr = new Uint8Array(derKey); } catch (e) { err = e; } callback(err, ui8arr); }; ScryptAsync(password, salt, logN, r, dkLen, interruptStep, cb, null); }; KeyStore._encryptString = function (string, pwDerivedKey) { var nonce = Nacl.randomBytes(Nacl.secretbox.nonceLength); var encStr = Nacl.secretbox(NaclUtil.decodeUTF8(string), nonce, pwDerivedKey); return { encStr: NaclUtil.encodeBase64(encStr), nonce: NaclUtil.encodeBase64(nonce) }; }; KeyStore._decryptString = function (encryptedStr, pwDerivedKey) { var decStr = NaclUtil.decodeBase64(encryptedStr.encStr); var nonce = NaclUtil.decodeBase64(encryptedStr.nonce); var decryptedStr = Nacl.secretbox.open(decStr, nonce, pwDerivedKey); if (decryptedStr === null) { return false; } return NaclUtil.encodeUTF8(decryptedStr); }; KeyStore._encryptKey = function (privateKey, pwDerivedKey) { var nonce = Nacl.randomBytes(Nacl.secretbox.nonceLength); var privateKeyArray = Encryption.decodeHex(privateKey); var encKey = Nacl.secretbox(privateKeyArray, nonce, pwDerivedKey); return { key: NaclUtil.encodeBase64(encKey), nonce: NaclUtil.encodeBase64(nonce) }; }; KeyStore._decryptKey = function (encryptedKey, pwDerivedKey) { var decKey = NaclUtil.decodeBase64(encryptedKey.key); var nonce = NaclUtil.decodeBase64(encryptedKey.nonce); var decryptedKey = Nacl.secretbox.open(decKey, nonce, pwDerivedKey); if (decryptedKey === null) { throw new Error('Decryption failed!'); } return Encryption.encodeHex(decryptedKey); }; KeyStore._computeAddressFromPrivKey = function (privateKey) { var keyPair = ec.genKeyPair(); keyPair._importPrivate(privateKey, 'hex'); var pubKey = keyPair.getPublic(false, 'hex').slice(2); var pubKeyWordArray = CryptoJS.enc.Hex.parse(pubKey); var hash = CryptoJS.SHA3(pubKeyWordArray, { outputLength: 256 }); var address = hash.toString(CryptoJS.enc.Hex).slice(24); return address; }; KeyStore._computePubkeyFromPrivKey = function (privKey, curve) { if (curve !== 'curve25519') { throw new Error('KeyStore._computePubkeyFromPrivKey: Only "curve25519" supported.'); } var privateKeyBase64 = new Buffer(privKey, 'hex').toString('base64'); var privateKeyUInt8Array = NaclUtil.decodeBase64(privateKeyBase64); var pubKey = Nacl.box.keyPair.fromSecretKey(privateKeyUInt8Array).publicKey; var pubKeyBase64 = NaclUtil.encodeBase64(pubKey); var pubKeyHex = new Buffer(pubKeyBase64, 'base64').toString('hex'); return pubKeyHex; }; // This function is tested using the test vectors here: // http://www.di-mgt.com.au/sha_testvectors.html KeyStore._concatAndSha256 = function (entropyBuf0, entropyBuf1) { var totalEnt = Buffer.concat([entropyBuf0, entropyBuf1]); if (totalEnt.length !== entropyBuf0.length + entropyBuf1.length) { throw new Error('generateRandomSeed: Logic error! Concatenation of entropy sources failed.'); } return Hash.sha256(totalEnt); }; KeyStore.DEFAULT_SALT = 'lightwalletSalt'; module.exports = KeyStore; }).call(this,require("buffer").Buffer) },{"./assert":2,"./encryption":3,"./signing":5,"./txutils":6,"bitcore-lib":29,"bitcore-mnemonic":93,"buffer":138,"crypto-js":155,"elliptic":191,"ethereumjs-util":210,"scrypt-async":290,"tweetnacl":311,"tweetnacl-util":310}],5:[function(require,module,exports){ (function (Buffer){ "use strict"; var Transaction = require('ethereumjs-tx'); var Util = require('ethereumjs-util'); var Assert = require('./assert'); function getPrivateKeyBuff(keystore, pwDerivedKey, address) { var privateKey = keystore.exportPrivateKey(Util.stripHexPrefix(address), pwDerivedKey); return new Buffer(privateKey, 'hex'); } function signTx(keystore, pwDerivedKey, rawTx, signingAddress) { Assert.derivedKey(keystore, pwDerivedKey); var tx = new Transaction(new Buffer(Util.stripHexPrefix(rawTx), 'hex')); var privateKeyBuff = getPrivateKeyBuff(keystore, pwDerivedKey, signingAddress); tx.sign(privateKeyBuff); return tx.serialize().toString('hex'); } function signMsg(keystore, pwDerivedKey, rawMsg, signingAddress) { Assert.derivedKey(keystore, pwDerivedKey); var msgHash = Util.addHexPrefix(Util.keccak(rawMsg).toString('hex')); return this.signMsgHash(keystore, pwDerivedKey, msgHash, signingAddress); } function signMsgHash(keystore, pwDerivedKey, msgHash, signingAddress) { Assert.derivedKey(keystore, pwDerivedKey); var msgBuff = new Buffer(Util.stripHexPrefix(msgHash), 'hex'); var privateKeyBuff = getPrivateKeyBuff(keystore, pwDerivedKey, signingAddress); return Util.ecsign(msgBuff, privateKeyBuff); } function concatSig(signature) { var v = signature.v; var r = signature.r; var s = signature.s; r = Util.fromSigned(r); s = Util.fromSigned(s); v = Util.bufferToInt(v); r = Util.setLengthLeft(Util.toUnsigned(r), 32).toString('hex'); s = Util.setLengthLeft(Util.toUnsigned(s), 32).toString('hex'); v = Util.stripHexPrefix(Util.intToHex(v)); return Util.addHexPrefix(r.concat(s, v).toString('hex')); } function recoverAddress(rawMsg, v, r, s) { var msgHash = Util.keccak(rawMsg); return Util.pubToAddress(Util.ecrecover(msgHash, v, r, s)); } module.exports = { signTx: signTx, signMsg: signMsg, signMsgHash: signMsgHash, concatSig: concatSig, recoverAddress: recoverAddress }; }).call(this,require("buffer").Buffer) },{"./assert":2,"buffer":138,"ethereumjs-tx":208,"ethereumjs-util":210}],6:[function(require,module,exports){ (function (Buffer){ "use strict"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { keys.push.apply(keys, Object.getOwnPropertySymbols(object)); } if (enumerableOnly) keys = keys.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var Transaction = require('ethereumjs-tx'); var Util = require('ethereumjs-util'); var Coder = require('web3/lib/solidity/coder'); var Rlp = require('rlp'); var CryptoJS = require('crypto-js'); function createTx(txObject) { return new Transaction(_objectSpread({}, txObject.from && { from: Util.addHexPrefix(txObject.from) }, {}, txObject.to && { to: Util.addHexPrefix(txObject.to) }, {}, txObject.gasPrice && { gasPrice: Util.addHexPrefix(txObject.gasPrice) }, {}, txObject.gasLimit && { gasLimit: Util.addHexPrefix(txObject.gasLimit) }, {}, txObject.nonce && { nonce: Util.addHexPrefix(txObject.nonce) }, {}, txObject.value && { value: Util.addHexPrefix(txObject.value) }, {}, txObject.data && { data: Util.addHexPrefix(txObject.data) })); } function txToHexString(tx) { return Util.addHexPrefix(tx.serialize().toString('hex')); } function _getTypesFromAbi(abi, functionName) { var funcJson = abi.filter(function (json) { return json.type === 'function' && json.name === functionName; })[0]; return funcJson.inputs.map(function (json) { return json.type; }); } function _encodeFunctionTxData(functionName, types, args) { var fullName = "".concat(functionName, "(").concat(types.join(), ")"); var signature = CryptoJS.SHA3(fullName, { outputLength: 256 }).toString(CryptoJS.enc.Hex).slice(0, 8); var encodeParams = Coder.encodeParams(types, args); var dataHex = Util.addHexPrefix("".concat(signature).concat(encodeParams)); return dataHex; } function functionTx(abi, functionName, args, txObject) { var types = _getTypesFromAbi(abi, functionName); var txData = _encodeFunctionTxData(functionName, types, args); var tx = createTx(_objectSpread({}, txObject, { data: txData })); return txToHexString(tx); } function valueTx(txObject) { var tx = createTx(txObject); return txToHexString(tx); } function createdContractAddress(fromAddress, nonce) { var addressBuf = new Buffer(Util.stripHexPrefix(fromAddress), 'hex'); var rlpEncodedHex = Rlp.encode([addressBuf, nonce]).toString('hex'); var rlpEncodedWordArray = CryptoJS.enc.Hex.parse(rlpEncodedHex); var hash = CryptoJS.SHA3(rlpEncodedWordArray, { outputLength: 256 }).toString(CryptoJS.enc.Hex); return Util.addHexPrefix(hash.slice(24)); } function createContractTx(fromAddress, txObject) { var tx = createTx(txObject); var contractAddress = createdContractAddress(fromAddress, txObject.nonce); return { tx: txToHexString(tx), addr: contractAddress }; } module.exports = { _encodeFunctionTxData: _encodeFunctionTxData, _getTypesFromAbi: _getTypesFromAbi, createTx: createTx, txToHexString: txToHexString, functionTx: functionTx, createdContractAddress: createdContractAddress, createContractTx: createContractTx, valueTx: valueTx }; }).call(this,require("buffer").Buffer) },{"buffer":138,"crypto-js":155,"ethereumjs-tx":208,"ethereumjs-util":210,"rlp":288,"web3/lib/solidity/coder":321}],7:[function(require,module,exports){ "use strict"; var CryptoJS = require('crypto-js'); var Keystore = require('./keystore'); var HD_PATH_STRING = 'm/0\'/0\'/0\''; function legacyGenerateEncKey(password, salt) { return CryptoJS.PBKDF2(password, salt, { keySize: 512 / 32, iterations: 150 }).toString(); } function legacyDecryptString(encryptedStr, password) { var encStr = encryptedStr.encStr, iv = encryptedStr.iv, salt = encryptedStr.salt; var decryptedStr = CryptoJS.AES.decrypt(encStr, password, { iv: iv, salt: salt }); return decryptedStr.toString(CryptoJS.enc.Latin1); } function upgradeVersion1(oldKS, password, callback) { var salt = oldKS.salt, keyHash = oldKS.keyHash, encSeed = oldKS.encSeed, hdIndex = oldKS.hdIndex; var derivedKey = legacyGenerateEncKey(password, salt); var hash = CryptoJS.SHA3(derivedKey).toString(); if (keyHash !== hash) { callback(new Error('Keystore Upgrade: Invalid Password!')); return; } var seedPhrase = legacyDecryptString(encSeed, derivedKey); Keystore.createVault({ password: password, seedPhrase: seedPhrase, salt: Keystore.DEFAULT_SALT, hdPathString: HD_PATH_STRING }, function (err, newKeyStore) { if (err) { callback(err); return; } newKeyStore.keyFromPassword(password, function (err, pwDerivedKey) { if (err) { callback(err); return; } newKeyStore.generateNewAddress(pwDerivedKey, hdIndex); callback(null, newKeyStore.serialize()); }); }); } function upgradeVersion2(oldKS, password, callback) { var _oldKS$salt = oldKS.salt, salt = _oldKS$salt === void 0 ? Keystore.DEFAULT_SALT : _oldKS$salt, encSeed = oldKS.encSeed, ksData = oldKS.ksData; Keystore.deriveKeyFromPasswordAndSalt(password, salt, function (err, pwKey) { if (err) { callback(err); return; } var seedPhrase = Keystore._decryptString(encSeed, pwKey); if (seedPhrase) { seedPhrase = seedPhrase.trim(); } if (!seedPhrase || !Keystore.isSeedValid(seedPhrase)) { callback(new Error('Keystore Upgrade: Invalid provided password.')); return; } var hdPaths = Object.keys(ksData); var hdPathString = HD_PATH_STRING; if (hdPaths.length > 0) { hdPathString = hdPaths[0]; } Keystore.createVault({ password: password, seedPhrase: seedPhrase, salt: salt, hdPathString: hdPathString }, function (err, newKeyStore) { if (err) { callback(err); return; } newKeyStore.keyFromPassword(password, function (err, pwDerivedKey) { if (err) { callback(err); return; } var hdIndex = ksData[hdPathString].hdIndex; newKeyStore.generateNewAddress(pwDerivedKey, hdIndex); callback(null, newKeyStore.serialize()); }); }); }); } function upgradeOldSerialized(oldSerialized, password, callback) { var oldKS = JSON.parse(oldSerialized); var version = oldKS.version; if (version === undefined || version === 1) { upgradeVersion1(oldKS, password, callback); } else if (version === 2) { upgradeVersion2(oldKS, password, callback); } else if (version === 3) { callback(null, oldSerialized); } else { throw new Error('Keystore is not of correct version.'); } } module.exports = { upgradeOldSerialized: upgradeOldSerialized }; },{"./keystore":4,"crypto-js":155}],8:[function(require,module,exports){ "use strict"; var asn1 = exports; asn1.bignum = require('bn.js'); asn1.define = require('./asn1/api').define; asn1.base = require('./asn1/base'); asn1.constants = require('./asn1/constants'); asn1.decoders = require('./asn1/decoders'); asn1.encoders = require('./asn1/encoders'); },{"./asn1/api":9,"./asn1/base":11,"./asn1/constants":15,"./asn1/decoders":17,"./asn1/encoders":20,"bn.js":105}],9:[function(require,module,exports){ "use strict"; var asn1 = require('../asn1'); var inherits = require('inherits'); var api = exports; api.define = function define(name, body) { return new Entity(name, body); }; function Entity(name, body) { this.name = name; this.body = body; this.decoders = {}; this.encoders = {}; } ; Entity.prototype._createNamed = function createNamed(base) { var named; try { named = require('vm').runInThisContext('(function ' + this.name + '(entity) {\n' + ' this._initNamed(entity);\n' + '})'); } catch (e) { named = function named(entity) { this._initNamed(entity); }; } inherits(named, base); named.prototype._initNamed = function initnamed(entity) { base.call(this, entity); }; return new named(this); }; Entity.prototype._getDecoder = function _getDecoder(enc) { enc = enc || 'der'; // Lazily create decoder if (!this.decoders.hasOwnProperty(enc)) this.decoders[enc] = this._createNamed(asn1.decoders[enc]); return this.decoders[enc]; }; Entity.prototype.decode = function decode(data, enc, options) { return this._getDecoder(enc).decode(data, options); }; Entity.prototype._getEncoder = function _getEncoder(enc) { enc = enc || 'der'; // Lazily create encoder if (!this.encoders.hasOwnProperty(enc)) this.encoders[enc] = this._createNamed(asn1.encoders[enc]); return this.encoders[enc]; }; Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) { return this._getEncoder(enc).encode(data, reporter); }; },{"../asn1":8,"inherits":230,"vm":317}],10:[function(require,module,exports){ "use strict"; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } var inherits = require('inherits'); var Reporter = require('../base').Reporter; var Buffer = require('buffer').Buffer; function DecoderBuffer(base, options) { Reporter.call(this, options); if (!Buffer.isBuffer(base)) { this.error('Input not Buffer'); return; } this.base = base; this.offset = 0; this.length = base.length; } inherits(DecoderBuffer, Reporter); exports.DecoderBuffer = DecoderBuffer; DecoderBuffer.prototype.save = function save() { return { offset: this.offset, reporter: Reporter.prototype.save.call(this) }; }; DecoderBuffer.prototype.restore = function restore(save) { // Return skipped data var res = new DecoderBuffer(this.base); res.offset = save.offset; res.length = this.offset; this.offset = save.offset; Reporter.prototype.restore.call(this, save.reporter); return res; }; DecoderBuffer.prototype.isEmpty = function isEmpty() { return this.offset === this.length; }; DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) { if (this.offset + 1 <= this.length) return this.base.readUInt8(this.offset++, true);else return this.error(fail || 'DecoderBuffer overrun'); }; DecoderBuffer.prototype.skip = function skip(bytes, fail) { if (!(this.offset + bytes <= this.length)) return this.error(fail || 'DecoderBuffer overrun'); var res = new DecoderBuffer(this.base); // Share reporter state res._reporterState = this._reporterState; res.offset = this.offset; res.length = this.offset + bytes; this.offset += bytes; return res; }; DecoderBuffer.prototype.raw = function raw(save) { return this.base.slice(save ? save.offset : this.offset, this.length); }; function EncoderBuffer(value, reporter) { if (Array.isArray(value)) { this.length = 0; this.value = value.map(function (item) { if (!(item instanceof EncoderBuffer)) item = new EncoderBuffer(item, reporter); this.length += item.length; return item; }, this); } else if (typeof value === 'number') { if (!(0 <= value && value <= 0xff)) return reporter.error('non-byte EncoderBuffer value'); this.value = value; this.length = 1; } else if (typeof value === 'string') { this.value = value; this.length = Buffer.byteLength(value); } else if (Buffer.isBuffer(value)) { this.value = value; this.length = value.length; } else { return reporter.error('Unsupported type: ' + _typeof(value)); } } exports.EncoderBuffer = EncoderBuffer; EncoderBuffer.prototype.join = function join(out, offset) { if (!out) out = new Buffer(this.length); if (!offset) offset = 0; if (this.length === 0) return out; if (Array.isArray(this.value)) { this.value.forEach(function (item) { item.join(out, offset); offset += item.length; }); } else { if (typeof this.value === 'number') out[offset] = this.value;else if (typeof this.value === 'string') out.write(this.value, offset);else if (Buffer.isBuffer(this.value)) this.value.copy(out, offset); offset += this.length; } return out; }; },{"../base":11,"buffer":138,"inherits":230}],11:[function(require,module,exports){ "use strict"; var base = exports; base.Reporter = require('./reporter').Reporter; base.DecoderBuffer = require('./buffer').DecoderBuffer; base.EncoderBuffer = require('./buffer').EncoderBuffer; base.Node = require('./node'); },{"./buffer":10,"./node":12,"./reporter":13}],12:[function(require,module,exports){ "use strict"; function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } var Reporter = require('../base').Reporter; var EncoderBuffer = require('../base').EncoderBuffer; var DecoderBuffer = require('../base').DecoderBuffer; var assert = require('minimalistic-assert'); // Supported tags var tags = ['seq', 'seqof', 'set', 'setof', 'objid', 'bool', 'gentime', 'utctime', 'null_', 'enum', 'int', 'objDesc', 'bitstr', 'bmpstr', 'charstr', 'genstr', 'graphstr', 'ia5str', 'iso646str', 'numstr', 'octstr', 'printstr', 't61str', 'unistr', 'utf8str', 'videostr']; // Public methods list var methods = ['key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice', 'any', 'contains'].concat(tags); // Overrided methods list var overrided = ['_peekTag', '_decodeTag', '_use', '_decodeStr', '_decodeObjid', '_decodeTime', '_decodeNull', '_decodeInt', '_decodeBool', '_decodeList', '_encodeComposite', '_encodeStr', '_encodeObjid', '_encodeTime', '_encodeNull', '_encodeInt', '_encodeBool']; function Node(enc, parent) { var state = {}; this._baseState = state; state.enc = enc; state.parent = parent || null; state.children = null; // State state.tag = null; state.args = null; state.reverseArgs = null; state.choice = null; state.optional = false; state.any = false; state.obj = false; state.use = null; state.useDecoder = null; state.key = null; state['default'] = null; state.explicit = null; state.implicit = null; state.contains = null; // Should create new instance on each method if (!state.parent) { state.children = []; this._wrap(); } } module.exports = Node; var stateProps = ['enc', 'parent', 'children', 'tag', 'args', 'reverseArgs', 'choice', 'optional', 'any', 'obj', 'use', 'alteredUse', 'key', 'default', 'explicit', 'implicit', 'contains']; Node.prototype.clone = function clone() { var state = this._baseState; var cstate = {}; stateProps.forEach(function (prop) { cstate[prop] = state[prop]; }); var res = new this.constructor(cstate.parent); res._baseState = cstate; return res; }; Node.prototype._wrap = function wrap() { var state = this._baseState; methods.forEach(function (method) { this[method] = function _wrappedMethod() { var clone = new this.constructor(this); state.children.push(clone); return clone[method].apply(clone, arguments); }; }, this); }; Node.prototype._init = function init(body) { var state = this._baseState; assert(state.parent === null); body.call(this); // Filter children state.children = state.children.filter(function (child) { return child._baseState.parent === this; }, this); assert.equal(state.children.length, 1, 'Root node can have only one child'); }; Node.prototype._useArgs = function useArgs(args) { var state = this._baseState; // Filter children and args var children = args.filter(function (arg) { return arg instanceof this.constructor; }, this); args = args.filter(function (arg) { return !(arg instanceof this.constructor); }, this); if (children.length !== 0) { assert(state.children === null); state.children = children; // Replace parent to maintain backward link children.forEach(function (child) { child._baseState.parent = this; }, this); } if (args.length !== 0) { assert(state.args === null); state.args = args; state.reverseArgs = args.map(function (arg) { if (_typeof(arg) !== 'object' || arg.constructor !== Object) return arg; var res = {}; Object.keys(arg).forEach(function (key) { if (key == (key | 0)) key |= 0; var value = arg[key]; res[value] = key; }); return res; }); } }; // // Overrided methods // overrided.forEach(function (method) { Node.prototype[method] = function _overrided() { var state = this._baseState; throw new Error(method + ' not implemented for encoding: ' + state.enc); }; }); // // Public methods // tags.forEach(function (tag) { Node.prototype[tag] = function _tagMethod() { var state = this._baseState; var args = Array.prototype.slice.call(arguments); assert(state.tag === null); state.tag = tag; this._useArgs(args); return this; }; }); Node.prototype.use = function use(item) { assert(item); var state = this._baseState; assert(state.use === null); state.use = item; return this; }; Node.prototype.optional = function optional() { var state = this._baseState; state.optional = true; return this; }; Node.prototype.def = function def(val) { var state = this._baseState; assert(state['default'] === null); state['default'] = val; state.optional = true; return this; }; Node.prototype.explicit = function explicit(num) { var state = this._baseState; assert(state.explicit === null && state.implicit === null); state.explicit = num; return this; }; Node.prototype.implicit = function implicit(num) { var state = this._baseState; assert(state.explicit === null && state.implicit === null); state.implicit = num; return this; }; Node.prototype.obj = function obj() { var state = this._baseState; var args = Array.prototype.slice.call(arguments); state.obj = true; if (args.length !== 0) this._useArgs(args); return this; }; Node.prototype.key = function key(newKey) { var state = this._baseState; assert(state.key === null); state.key = newKey; return this; }; Node.prototype.any = function any() { var state = this._baseState; state.any = true; return this; }; Node.prototype.choice = function choice(obj) { var state = this._baseState; assert(state.choice === null); state.choice = obj; this._useArgs(Object.keys(obj).map(function (key) { return obj[key]; })); return this; }; Node.prototype.contains = function contains(item) { var state = this._baseState; assert(state.use === null); state.contains = item; return this; }; // // Decoding // Node.prototype._decode = function decode(input, options) { var state = this._baseState; // Decode root node if (state.parent === null) return input.wrapResult(state.children[0]._decode(input, options)); var result = state['default']; var present = true; var prevKey = null; if (state.key !== null) prevKey = input.enterKey(state.key); // Check if tag is there if (state.optional) { var tag = null; if (state.explicit !== null) tag = state.explicit;else if (state.implicit !== null) tag = state.implicit;else if (state.tag !== null) tag = state.tag; if (tag === null && !state.any) { // Trial and Error var save = input.save(); try { if (state.choice === null) this._decodeGeneric(state.tag, input, options);else this._decodeChoice(input, options); present = true; } catch (e) { present = false; } input.restore(save); } else { present = this._peekTag(input, tag, state.any); if (input.isError(present)) return present; } } // Push object on stack var prevObj; if (state.obj && present) prevObj = input.enterObject(); if (present) { // Unwrap explicit values if (state.explicit !== null) { var explicit = this._decodeTag(input, state.explicit); if (input.isError(explicit)) return explicit; input = explicit; } var start = input.offset; // Unwrap implicit and normal values if (state.use === null && state.choice === null) { if (state.any) var save = input.save(); var body = this._decodeTag(input, state.implicit !== null ? state.implicit : state.tag, state.any); if (input.isError(body)) return body; if (state.any) result = input.raw(save);else input = body; } if (options && options.track && state.tag !== null) options.track(input.path(), start, input.length, 'tagged'); if (options && options.track && state.tag !== null) options.track(input.path(), input.offset, input.length, 'content'); // Select proper method for tag if (state.any) result = result;else if (state.choice === null) result = this._decodeGeneric(state.tag, input, options);else result = this._decodeChoice(input, options); if (input.isError(result)) return result; // Decode children if (!state.any && state.choice === null && state.children !== null) { state.children.forEach(function decodeChildren(child) { // NOTE: We are ignoring errors here, to let parser continue with other // parts of encoded data child._decode(input, options); }); } // Decode contained/encoded by schema, only in bit or octet strings if (state.contains && (state.tag === 'octstr' || state.tag === 'bitstr')) { var data = new DecoderBuffer(result); result = this._getUse(state.contains, input._reporterState.obj)._decode(data, options); } } // Pop object if (state.obj && present) result = input.leaveObject(prevObj); // Set key if (state.key !== null && (result !== null || present === true)) input.leaveKey(prevKey, state.key, result);else if (prevKey !== null) input.exitKey(prevKey); return result; }; Node.prototype._decodeGeneric = function decodeGeneric(tag, input, options) { var state = this._baseState; if (tag === 'seq' || tag === 'set') return null; if (tag === 'seqof' || tag === 'setof') return this._decodeList(input, tag, state.args[0], options);else if (/str$/.test(tag)) return this._decodeStr(input, tag, options);else if (tag === 'objid' && state.args) return this._decodeObjid(input, state.args[0], state.args[1], options);else if (tag === 'objid') return this._decodeObjid(input, null, null, options);else if (tag === 'gentime' || tag === 'utctime') return this._decodeTime(input, tag, options);else if (tag === 'null_') return this._decodeNull(input, options);else if (tag === 'bool') return this._decodeBool(input, options);else if (tag === 'objDesc') return this._decodeStr(input, tag, options);else if (tag === 'int' || tag === 'enum') return this._decodeInt(input, state.args && state.args[0], options); if (state.use !== null) { return this._getUse(state.use, input._reporterState.obj)._decode(input, options); } else { return input.error('unknown tag: ' + tag); } }; Node.prototype._getUse = function _getUse(entity, obj) { var state = this._baseState; // Create altered use decoder if implicit is set state.useDecoder = this._use(entity, obj); assert(state.useDecoder._baseState.parent === null); state.useDecoder = state.useDecoder._baseState.children[0]; if (state.implicit !== state.useDecoder._baseState.implicit) { state.useDecoder = state.useDecoder.clone(); state.useDecoder._baseState.implicit = state.implicit; } return state.useDecoder; }; Node.prototype._decodeChoice = function decodeChoice(input, options) { var state = this._baseSt