text: 'use strict';
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
  
  var web3CoreHelpers = require('web3-core-helpers');
  var _regeneratorRuntime = _interopDefault(require('@babel/runtime/regenerator'));
  var _asyncToGenerator = _interopDefault(require('@babel/runtime/helpers/asyncToGenerator'));
  var _possibleConstructorReturn = _interopDefault(require('@babel/runtime/helpers/possibleConstructorReturn'));
  var _getPrototypeOf = _interopDefault(require('@babel/runtime/helpers/getPrototypeOf'));
  var _inherits = _interopDefault(require('@babel/runtime/helpers/inherits'));
  var _assertThisInitialized = _interopDefault(require('@babel/runtime/helpers/assertThisInitialized'));
  var isFunction = _interopDefault(require('lodash/isFunction'));
  var isBoolean = _interopDefault(require('lodash/isBoolean'));
  var RLP = _interopDefault(require('eth-lib/lib/rlp'));
  var Bytes = _interopDefault(require('eth-lib/lib/bytes'));
  var web3Core = require('web3-core');
  var _classCallCheck = _interopDefault(require('@babel/runtime/helpers/classCallCheck'));
  var _createClass = _interopDefault(require('@babel/runtime/helpers/createClass'));
  var scryptsy = _interopDefault(require('scrypt.js'));
  var isString = _interopDefault(require('lodash/isString'));
  var isObject = _interopDefault(require('lodash/isObject'));
  var account = require('eth-lib/lib/account');
  var uuid = _interopDefault(require('uuid'));
  var Hash = _interopDefault(require('eth-lib/lib/hash'));
  var Utils = require('web3-utils');
  var web3Providers = require('web3-providers');
  var web3CoreMethod = require('web3-core-method');
  
  var crypto = typeof global === 'undefined' ? require('crypto-browserify') : require('crypto');
  var Account =
  function () {
    function Account(options) {
      var accounts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
      _classCallCheck(this, Account);
      this.address = options.address;
      this.privateKey = options.privateKey;
      this.accounts = accounts;
      return new Proxy(this, {
        get: function get(target, name) {
          return target[name];
        }
      });
    }
    _createClass(Account, [{
      key: "signTransaction",
      value: function signTransaction(tx, callback) {
        return this.accounts.signTransaction(tx, this.privateKey, callback);
      }
    }, {
      key: "sign",
      value: function sign(data) {
        if (Utils.isHexStrict(data)) {
          data = Utils.hexToBytes(data);
        }
        var messageBuffer = Buffer.from(data);
        var preamble = "\x19Ethereum Signed Message:\n".concat(data.length);
        var preambleBuffer = Buffer.from(preamble);
        var ethMessage = Buffer.concat([preambleBuffer, messageBuffer]);
        var hash = Hash.keccak256s(ethMessage);
        var signature = account.sign(hash, this.privateKey);
        var vrs = account.decodeSignature(signature);
        return {
          message: data,
          messageHash: hash,
          v: vrs[0],
          r: vrs[1],
          s: vrs[2],
          signature: signature
        };
      }
    }, {
      key: "encrypt",
      value: function encrypt(password, options) {
        return Account.fromPrivateKey(this.privateKey, this.accounts.transactionSinger).toV3Keystore(password, options);
      }
    }, {
      key: "toV3Keystore",
      value: function toV3Keystore(password, options) {
        options = options || {};
        var salt = options.salt || crypto.randomBytes(32);
        var iv = options.iv || crypto.randomBytes(16);
        var derivedKey;
        var kdf = options.kdf || 'scrypt';
        var kdfparams = {
          dklen: options.dklen || 32,
          salt: salt.toString('hex')
        };
        if (kdf === 'pbkdf2') {
          kdfparams.c = options.c || 262144;
          kdfparams.prf = 'hmac-sha256';
          derivedKey = crypto.pbkdf2Sync(Buffer.from(password), salt, kdfparams.c, kdfparams.dklen, 'sha256');
        } else if (kdf === 'scrypt') {
          kdfparams.n = options.n || 8192;
          kdfparams.r = options.r || 8;
          kdfparams.p = options.p || 1;
          derivedKey = scryptsy(Buffer.from(password), salt, kdfparams.n, kdfparams.r, kdfparams.p, kdfparams.dklen);
        } else {
          throw new Error('Unsupported kdf');
        }
        var cipher = crypto.createCipheriv(options.cipher || 'aes-128-ctr', derivedKey.slice(0, 16), iv);
        if (!cipher) {
          throw new Error('Unsupported cipher');
        }
        var ciphertext = Buffer.concat([cipher.update(Buffer.from(this.privateKey.replace('0x', ''), 'hex')), cipher.final()]);
        var mac = Utils.sha3(Buffer.concat([derivedKey.slice(16, 32), Buffer.from(ciphertext, 'hex')])).replace('0x', '');
        return {
          version: 3,
          id: uuid.v4({
            random: options.uuid || crypto.randomBytes(16)
          }),
          address: this.address.toLowerCase().replace('0x', ''),
          crypto: {
            ciphertext: ciphertext.toString('hex'),
            cipherparams: {
              iv: iv.toString('hex')
            },
            cipher: options.cipher || 'aes-128-ctr',
            kdf: kdf,
            kdfparams: kdfparams,
            mac: mac.toString('hex')
          }
        };
      }
    }], [{
      key: "from",
      value: function from(entropy) {
        var accounts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
        return new Account(account.create(entropy || Utils.randomHex(32)), accounts.transactionSigner);
      }
    }, {
      key: "fromPrivateKey",
      value: function fromPrivateKey(privateKey) {
        var accounts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
        return new Account(account.fromPrivate(privateKey), accounts.transactionSigner);
      }
    }, {
      key: "fromV3Keystore",
      value: function fromV3Keystore(v3Keystore, password) {
        var nonStrict = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
        var accounts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
        if (!isString(password)) {
          throw new Error('No password given.');
        }
        var json = isObject(v3Keystore) ? v3Keystore : JSON.parse(nonStrict ? v3Keystore.toLowerCase() : v3Keystore);
        if (json.version !== 3) {
          throw new Error('Not a valid V3 wallet');
        }
        var derivedKey;
        var kdfparams;
        if (json.crypto.kdf === 'scrypt') {
          kdfparams = json.crypto.kdfparams;
          derivedKey = scryptsy(Buffer.from(password), Buffer.from(kdfparams.salt, 'hex'), kdfparams.n, kdfparams.r, kdfparams.p, kdfparams.dklen);
        } else if (json.crypto.kdf === 'pbkdf2') {
          kdfparams = json.crypto.kdfparams;
          if (kdfparams.prf !== 'hmac-sha256') {
            throw new Error('Unsupported parameters to PBKDF2');
          }
          derivedKey = crypto.pbkdf2Sync(Buffer.from(password), Buffer.from(kdfparams.salt, 'hex'), kdfparams.c, kdfparams.dklen, 'sha256');
        } else {
          throw new Error('Unsupported key derivation scheme');
        }
        var ciphertext = Buffer.from(json.crypto.ciphertext, 'hex');
        var mac = Utils.sha3(Buffer.concat([derivedKey.slice(16, 32), ciphertext])).replace('0x', '');
        if (mac !== json.crypto.mac) {
          throw new Error('Key derivation failed - possibly wrong password');
        }
        var decipher = crypto.createDecipheriv(json.crypto.cipher, derivedKey.slice(0, 16), Buffer.from(json.crypto.cipherparams.iv, 'hex'));
        var seed = "0x".concat(Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString('hex'));
        return this.fromPrivateKey(seed, accounts);
      }
    }]);
    return Account;
  }();
  
  var Accounts =
  function (_AbstractWeb3Module) {
    _inherits(Accounts, _AbstractWeb3Module);
    function Accounts(provider, providersModuleFactory, formatters, chainIdMethod, getGasPriceMethod, getTransactionCountMethod, options) {
      var _this;
      _classCallCheck(this, Accounts);
      _this = _possibleConstructorReturn(this, _getPrototypeOf(Accounts).call(this, provider, providersModuleFactory, null, null, options));
      _this.transactionSigner = options.transactionSigner;
      _this.formatters = formatters;
      _this.chainIdMethod = chainIdMethod;
      _this.getGasPriceMethod = getGasPriceMethod;
      _this.getTransactionCountMethod = getTransactionCountMethod;
      _this.defaultKeyName = 'web3js_wallet';
      _this.accounts = {};
      _this.accountsIndex = 0;
      _this.wallet = _this.createWalletProxy();
      return _possibleConstructorReturn(_this, new Proxy(_assertThisInitialized(_assertThisInitialized(_this)), {
        get: function get(target, name) {
          return target[name];
        }
      }));
    }
    _createClass(Accounts, [{
      key: "createWalletProxy",
      value: function createWalletProxy() {
        return new Proxy(this, {
          get: function get(target, name) {
            switch (name) {
              case 'create':
                return target.addGeneratedAccountsToWallet;
              case 'encrypt':
                return target.encryptWallet;
              case 'decrypt':
                return target.decryptWallet;
              case 'clear':
                return target.clear;
              default:
                if (target.accounts[name]) {
                  return target.accounts[name];
                }
                return target[name];
            }
          }
        });
      }
    }, {
      key: "addGeneratedAccountsToWallet",
      value: function addGeneratedAccountsToWallet(numberOfAccounts, entropy) {
        var account$$1 = Account.from(entropy || Utils.randomHex(32), this);
        for (var i = 0; i < numberOfAccounts; ++i) {
          this.add(account$$1);
        }
        return this;
      }
    }, {
      key: "add",
      value: function add(account$$1) {
        if (isString(account$$1)) {
          account$$1 = Account.fromPrivateKey(account$$1, this);
        }
        if (!this[account$$1.address]) {
          this.accounts[this.accountsIndex] = account$$1;
          this.accounts[account$$1.address] = account$$1;
          this.accounts[account$$1.address.toLowerCase()] = account$$1;
          this.accountsIndex++;
          return account$$1;
        }
        return this.accounts[account$$1.address];
      }
    }, {
      key: "remove",
      value: function remove(addressOrIndex) {
        var _this2 = this;
        var removed;
        if (this.accounts[addressOrIndex]) {
          Object.keys(this.accounts).forEach(function (key) {
            if (_this2.accounts[key].address === addressOrIndex || key === addressOrIndex) {
              delete _this2.accounts[key];
              _this2.accountsIndex--;
              removed = true;
            }
          });
          return !!removed;
        }
        return false;
      }
    }, {
      key: "clear",
      value: function clear() {
        this.accounts = {};
        this.accountsIndex = 0;
        return this;
      }
    }, {
      key: "encryptWallet",
      value: function encryptWallet(password, options) {
        var _this3 = this;
        var encryptedAccounts = [];
        Object.keys(this.accounts).forEach(function (key) {
          return encryptedAccounts.push(_this3.accounts[key].encrypt(password, options));
        });
        return encryptedAccounts;
      }
    }, {
      key: "decryptWallet",
      value: function decryptWallet(encryptedWallet, password) {
        var _this4 = this;
        encryptedWallet.forEach(function (keystore) {
          var account$$1 = Account.fromV3Keystore(keystore, password, false, _this4);
          if (!account$$1) {
            throw new Error("Couldn't decrypt accounts. Password wrong?");
          }
          _this4.add(account$$1);
        });
        return this;
      }
    }, {
      key: "save",
      value: function save(password, keyName) {
        if (typeof localStorage === 'undefined') {
          throw new TypeError('window.localStorage is undefined.');
        }
        try {
          localStorage.setItem(keyName || this.defaultKeyName, JSON.stringify(this.encryptWallet(password)));
        } catch (error) {
          if (error.code === 18) {
            return true;
          }
          throw new Error(error);
        }
        return true;
      }
    }, {
      key: "load",
      value: function load(password, keyName) {
        var _this5 = this;
        if (typeof localStorage === 'undefined') {
          throw new TypeError('window.localStorage is undefined.');
        }
        var keystore;
        try {
          keystore = localStorage.getItem(keyName || this.defaultKeyName);
          if (keystore) {
            keystore = JSON.parse(keystore).map(function (item) {
              return Account.fromV3Keystore(item, password, false, _this5);
            });
          }
        } catch (error) {
          if (error.code === 18) {
            keystore = this.defaultKeyName;
          } else {
            throw new Error(error);
          }
        }
        return this.decryptWallet(keystore || [], password);
      }
    }, {
      key: "create",
      value: function create(entropy) {
        return Account.from(entropy, this);
      }
    }, {
      key: "privateKeyToAccount",
      value: function privateKeyToAccount(privateKey) {
        return Account.fromPrivateKey(privateKey, this);
      }
    }, {
      key: "hashMessage",
      value: function hashMessage(data) {
        if (Utils.isHexStrict(data)) {
          data = Utils.hexToBytes(data);
        }
        var messageBuffer = Buffer.from(data);
        var preamble = "\x19Ethereum Signed Message:\n".concat(data.length);
        var preambleBuffer = Buffer.from(preamble);
        var ethMessage = Buffer.concat([preambleBuffer, messageBuffer]);
        return Hash.keccak256s(ethMessage);
      }
    }, {
      key: "signTransaction",
      value: function () {
        var _signTransaction = _asyncToGenerator(
        _regeneratorRuntime.mark(function _callee(tx, privateKey, callback) {
          var account$$1, signedTransaction;
          return _regeneratorRuntime.wrap(function _callee$(_context) {
            while (1) {
              switch (_context.prev = _context.next) {
                case 0:
                  _context.prev = 0;
                  account$$1 = Account.fromPrivateKey(privateKey, this);
                  if (tx.chainId) {
                    _context.next = 6;
                    break;
                  }
                  _context.next = 5;
                  return this.chainIdMethod.execute(this);
                case 5:
                  tx.chainId = _context.sent;
                case 6:
                  if (tx.gasPrice) {
                    _context.next = 10;
                    break;
                  }
                  _context.next = 9;
                  return this.getGasPriceMethod.execute(this);
                case 9:
                  tx.gasPrice = _context.sent;
                case 10:
                  if (tx.nonce) {
                    _context.next = 15;
                    break;
                  }
                  this.getTransactionCountMethod.parameters = [account$$1.address];
                  _context.next = 14;
                  return this.getTransactionCountMethod.execute(this);
                case 14:
                  tx.nonce = _context.sent;
                case 15:
                  _context.next = 17;
                  return this.transactionSigner.sign(tx, account$$1.privateKey);
                case 17:
                  signedTransaction = _context.sent;
                  if (isFunction(callback)) {
                    callback(false, signedTransaction);
                  }
                  return _context.abrupt("return", signedTransaction);
                case 22:
                  _context.prev = 22;
                  _context.t0 = _context["catch"](0);
                  if (isFunction(callback)) {
                    callback(_context.t0, null);
                  }
                  throw _context.t0;
                case 26:
                case "end":
                  return _context.stop();
              }
            }
          }, _callee, this, [[0, 22]]);
        }));
        return function signTransaction(_x, _x2, _x3) {
          return _signTransaction.apply(this, arguments);
        };
      }()
    }, {
      key: "recoverTransaction",
      value: function recoverTransaction(rawTx) {
        var values = RLP.decode(rawTx);
        var signature = account.encodeSignature(values.slice(6, 9));
        var recovery = Bytes.toNumber(values[6]);
        var extraData = recovery < 35 ? [] : [Bytes.fromNumber(recovery - 35 >> 1), '0x', '0x'];
        var signingData = values.slice(0, 6).concat(extraData);
        var signingDataHex = RLP.encode(signingData);
        return account.recover(Hash.keccak256(signingDataHex), signature);
      }
    }, {
      key: "sign",
      value: function sign(data, privateKey) {
        if (Utils.isHexStrict(data)) {
          data = Utils.hexToBytes(data);
        }
        return Account.fromPrivateKey(privateKey, this).sign(data);
      }
    }, {
      key: "recover",
      value: function recover(message, signature, preFixed) {
        var args = [].slice.apply(arguments);
        if (isObject(message)) {
          return this.recover(message.messageHash, account.encodeSignature([message.v, message.r, message.s]), true);
        }
        if (!preFixed) {
          message = this.hashMessage(message);
        }
        if (args.length >= 4) {
          preFixed = args.slice(-1)[0];
          preFixed = isBoolean(preFixed) ? preFixed : false;
          return this.recover(message, account.encodeSignature(args.slice(1, 4)), preFixed);
        }
        return account.recover(message, signature);
      }
    }, {
      key: "decrypt",
      value: function decrypt(v3Keystore, password, nonStrict) {
        return Account.fromV3Keystore(v3Keystore, password, nonStrict, this);
      }
    }, {
      key: "encrypt",
      value: function encrypt(privateKey, password, options) {
        return Account.fromPrivateKey(privateKey, this).toV3Keystore(password, options);
      }
    }]);
    return Accounts;
  }(web3Core.AbstractWeb3Module);
  
  var Accounts$1 = function Accounts$$1(provider, options) {
    return new Accounts(provider, new web3Providers.ProvidersModuleFactory(), web3CoreHelpers.formatters, new web3CoreMethod.ChainIdMethod(Utils, web3CoreHelpers.formatters), new web3CoreMethod.GetGasPriceMethod(Utils, web3CoreHelpers.formatters), new web3CoreMethod.GetTransactionCountMethod(Utils, web3CoreHelpers.formatters), options);
  };
  
  exports.Accounts = Accounts$1;
  