text: (function (global, factory) {
      typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('web3-utils'), require('web3-providers'), require('web3-core-helpers'), require('web3-eth-abi'), require('web3-core-promievent'), require('lodash/isFunction'), require('lodash/isUndefined'), require('lodash/cloneDeep'), require('lodash/isArray'), require('@babel/runtime/helpers/get'), require('web3-core-method'), require('web3-core-subscriptions'), require('@babel/runtime/regenerator'), require('@babel/runtime/helpers/asyncToGenerator'), require('@babel/runtime/helpers/classCallCheck'), require('@babel/runtime/helpers/createClass'), require('@babel/runtime/helpers/possibleConstructorReturn'), require('@babel/runtime/helpers/getPrototypeOf'), require('@babel/runtime/helpers/inherits'), require('@babel/runtime/helpers/assertThisInitialized'), require('web3-core')) :
      typeof define === 'function' && define.amd ? define(['exports', 'web3-utils', 'web3-providers', 'web3-core-helpers', 'web3-eth-abi', 'web3-core-promievent', 'lodash/isFunction', 'lodash/isUndefined', 'lodash/cloneDeep', 'lodash/isArray', '@babel/runtime/helpers/get', 'web3-core-method', 'web3-core-subscriptions', '@babel/runtime/regenerator', '@babel/runtime/helpers/asyncToGenerator', '@babel/runtime/helpers/classCallCheck', '@babel/runtime/helpers/createClass', '@babel/runtime/helpers/possibleConstructorReturn', '@babel/runtime/helpers/getPrototypeOf', '@babel/runtime/helpers/inherits', '@babel/runtime/helpers/assertThisInitialized', 'web3-core'], factory) :
      (factory((global.Web3EthContract = {}),global.Utils,global.web3Providers,global.web3CoreHelpers,global.web3EthAbi,global.web3CorePromievent,global.isFunction,global.isUndefined,global.cloneDeep,global.isArray,global._get,global.web3CoreMethod,global.web3CoreSubscriptions,global._regeneratorRuntime,global._asyncToGenerator,global._classCallCheck,global._createClass,global._possibleConstructorReturn,global._getPrototypeOf,global._inherits,global._assertThisInitialized,global.web3Core));
  }(this, (function (exports,Utils,web3Providers,web3CoreHelpers,web3EthAbi,web3CorePromievent,isFunction,isUndefined,cloneDeep,isArray,_get,web3CoreMethod,web3CoreSubscriptions,_regeneratorRuntime,_asyncToGenerator,_classCallCheck,_createClass,_possibleConstructorReturn,_getPrototypeOf,_inherits,_assertThisInitialized,web3Core) { 'use strict';
  
      isFunction = isFunction && isFunction.hasOwnProperty('default') ? isFunction['default'] : isFunction;
      isUndefined = isUndefined && isUndefined.hasOwnProperty('default') ? isUndefined['default'] : isUndefined;
      cloneDeep = cloneDeep && cloneDeep.hasOwnProperty('default') ? cloneDeep['default'] : cloneDeep;
      isArray = isArray && isArray.hasOwnProperty('default') ? isArray['default'] : isArray;
      _get = _get && _get.hasOwnProperty('default') ? _get['default'] : _get;
      _regeneratorRuntime = _regeneratorRuntime && _regeneratorRuntime.hasOwnProperty('default') ? _regeneratorRuntime['default'] : _regeneratorRuntime;
      _asyncToGenerator = _asyncToGenerator && _asyncToGenerator.hasOwnProperty('default') ? _asyncToGenerator['default'] : _asyncToGenerator;
      _classCallCheck = _classCallCheck && _classCallCheck.hasOwnProperty('default') ? _classCallCheck['default'] : _classCallCheck;
      _createClass = _createClass && _createClass.hasOwnProperty('default') ? _createClass['default'] : _createClass;
      _possibleConstructorReturn = _possibleConstructorReturn && _possibleConstructorReturn.hasOwnProperty('default') ? _possibleConstructorReturn['default'] : _possibleConstructorReturn;
      _getPrototypeOf = _getPrototypeOf && _getPrototypeOf.hasOwnProperty('default') ? _getPrototypeOf['default'] : _getPrototypeOf;
      _inherits = _inherits && _inherits.hasOwnProperty('default') ? _inherits['default'] : _inherits;
      _assertThisInitialized = _assertThisInitialized && _assertThisInitialized.hasOwnProperty('default') ? _assertThisInitialized['default'] : _assertThisInitialized;
  
      var AbiModel =
      function () {
        function AbiModel(mappedAbi) {
          _classCallCheck(this, AbiModel);
          this.abi = mappedAbi;
        }
        _createClass(AbiModel, [{
          key: "getMethod",
          value: function getMethod(name) {
            if (this.hasMethod(name)) {
              return this.abi.methods[name];
            }
            return false;
          }
        }, {
          key: "getEvent",
          value: function getEvent(name) {
            if (this.hasEvent(name)) {
              return this.abi.events[name];
            }
            return false;
          }
        }, {
          key: "getEvents",
          value: function getEvents() {
            return this.abi.events;
          }
        }, {
          key: "getEventBySignature",
          value: function getEventBySignature(signature) {
            var _this = this;
            var event;
            Object.keys(this.abi.events).forEach(function (key) {
              if (_this.abi.events[key].signature === signature) {
                event = _this.abi.events[key];
              }
            });
            return event;
          }
        }, {
          key: "hasMethod",
          value: function hasMethod(name) {
            return typeof this.abi.methods[name] !== 'undefined';
          }
        }, {
          key: "hasEvent",
          value: function hasEvent(name) {
            return typeof this.abi.events[name] !== 'undefined';
          }
        }]);
        return AbiModel;
      }();
  
      var AbiItemModel =
      function () {
        function AbiItemModel(abiItem) {
          _classCallCheck(this, AbiItemModel);
          this.abiItem = abiItem;
          this.signature = this.abiItem.signature;
          this.name = this.abiItem.name;
          this.anonymous = this.abiItem.anonymous;
          this.contractMethodParameters = [];
        }
        _createClass(AbiItemModel, [{
          key: "getInputLength",
          value: function getInputLength() {
            if (isArray(this.abiItem.inputs)) {
              return this.abiItem.inputs.length;
            }
            return 0;
          }
        }, {
          key: "getInputs",
          value: function getInputs() {
            if (isArray(this.abiItem.inputs)) {
              return this.abiItem.inputs;
            }
            return [];
          }
        }, {
          key: "getOutputs",
          value: function getOutputs() {
            if (isArray(this.abiItem.outputs)) {
              return this.abiItem.outputs;
            }
            return [];
          }
        }, {
          key: "givenParametersLengthIsValid",
          value: function givenParametersLengthIsValid() {
            var inputLength = this.getInputLength();
            if (this.contractMethodParameters.length === inputLength) {
              return true;
            }
            throw new Error("The number of arguments is not matching the methods required number. You need to pass ".concat(inputLength, " arguments."));
          }
        }, {
          key: "getIndexedInputs",
          value: function getIndexedInputs() {
            return this.getInputs().filter(function (input) {
              return input.indexed === true;
            });
          }
        }, {
          key: "isOfType",
          value: function isOfType(type) {
            return this.abiItem.type === type;
          }
        }, {
          key: "requestType",
          get: function get() {
            if (this.abiItem.type === 'function' || this.abiItem.type === 'constructor') {
              if (this.abiItem.constant === true) {
                return 'call';
              }
              return 'send';
            }
          }
        }]);
        return AbiItemModel;
      }();
  
      var MethodEncoder =
      function () {
        function MethodEncoder(abiCoder) {
          _classCallCheck(this, MethodEncoder);
          this.abiCoder = abiCoder;
        }
        _createClass(MethodEncoder, [{
          key: "encode",
          value: function encode(abiItemModel, deployData) {
            var encodedParameters = this.abiCoder.encodeParameters(abiItemModel.getInputs(), abiItemModel.contractMethodParameters).replace('0x', '');
            if (abiItemModel.signature === 'constructor') {
              if (!deployData) {
                throw new Error('The contract has no contract data option set. This is necessary to append the constructor parameters.');
              }
              return deployData + encodedParameters;
            }
            if (abiItemModel.isOfType('function')) {
              return abiItemModel.signature + encodedParameters;
            }
            return encodedParameters;
          }
        }]);
        return MethodEncoder;
      }();
  
      var EventFilterEncoder =
      function () {
        function EventFilterEncoder(abiCoder) {
          _classCallCheck(this, EventFilterEncoder);
          this.abiCoder = abiCoder;
        }
        _createClass(EventFilterEncoder, [{
          key: "encode",
          value: function encode(abiItemModel, filter) {
            var _this = this;
            var indexedInputs = abiItemModel.getIndexedInputs();
            var topics = [];
            indexedInputs.forEach(function (indexedInput) {
              if (filter[indexedInput.name]) {
                var filterItem = filter[indexedInput.name];
                if (isArray(filterItem)) {
                  filterItem = filterItem.map(function (item) {
                    return _this.abiCoder.encodeParameter(indexedInput.type, item);
                  });
                  topics.push(filterItem);
                  return;
                }
                topics.push(_this.abiCoder.encodeParameter(indexedInput.type, filterItem));
              }
            });
            return topics;
          }
        }]);
        return EventFilterEncoder;
      }();
  
      var AllEventsFilterEncoder =
      function (_EventFilterEncoder) {
        _inherits(AllEventsFilterEncoder, _EventFilterEncoder);
        function AllEventsFilterEncoder() {
          _classCallCheck(this, AllEventsFilterEncoder);
          return _possibleConstructorReturn(this, _getPrototypeOf(AllEventsFilterEncoder).apply(this, arguments));
        }
        _createClass(AllEventsFilterEncoder, [{
          key: "encode",
          value: function encode(abiModel, filter) {
            var _this = this;
            var events = abiModel.getEvents();
            var topics = [];
            Object.keys(events).forEach(function (key) {
              topics.push(_get(_getPrototypeOf(AllEventsFilterEncoder.prototype), "encode", _this).call(_this, events[key], filter));
            });
            return topics;
          }
        }]);
        return AllEventsFilterEncoder;
      }(EventFilterEncoder);
  
      var EventLogDecoder =
      function () {
        function EventLogDecoder(abiCoder) {
          _classCallCheck(this, EventLogDecoder);
          this.abiCoder = abiCoder;
        }
        _createClass(EventLogDecoder, [{
          key: "decode",
          value: function decode(abiItemModel, response) {
            var argTopics = response.topics;
            if (abiItemModel.anonymous) {
              argTopics = response.topics.slice(1);
            }
            response.returnValues = this.abiCoder.decodeLog(abiItemModel.getInputs(), response.data, argTopics);
            response.event = abiItemModel.name;
            response.signature = abiItemModel.signature;
            response.raw = {
              data: response.data,
              topics: response.topics
            };
            if (abiItemModel.anonymous || !response.topics[0]) {
              response.signature = null;
            }
            delete response.data;
            delete response.topics;
            return response;
          }
        }]);
        return EventLogDecoder;
      }();
  
      var AllEventsLogDecoder =
      function (_EventLogDecoder) {
        _inherits(AllEventsLogDecoder, _EventLogDecoder);
        function AllEventsLogDecoder(abiCoder) {
          _classCallCheck(this, AllEventsLogDecoder);
          return _possibleConstructorReturn(this, _getPrototypeOf(AllEventsLogDecoder).call(this, abiCoder));
        }
        _createClass(AllEventsLogDecoder, [{
          key: "decode",
          value: function decode(abiModel, response) {
            return _get(_getPrototypeOf(AllEventsLogDecoder.prototype), "decode", this).call(this, abiModel.getEventBySignature(response.topics[0]), response);
          }
        }]);
        return AllEventsLogDecoder;
      }(EventLogDecoder);
  
      var AbiMapper =
      function () {
        function AbiMapper(contractModuleFactory, abiCoder, utils) {
          _classCallCheck(this, AbiMapper);
          this.utils = utils;
          this.abiCoder = abiCoder;
          this.contractModuleFactory = contractModuleFactory;
        }
        _createClass(AbiMapper, [{
          key: "map",
          value: function map(abi) {
            var _this = this;
            var mappedAbiItems = {
              methods: {},
              events: {}
            };
            abi.forEach(function (abiItem) {
              abiItem.constant = _this.isConstant(abiItem);
              abiItem.payable = _this.isPayable(abiItem);
              if (abiItem.name) {
                abiItem.funcName = _this.utils.jsonInterfaceMethodToString(abiItem);
              }
              var abiItemModel;
              if (abiItem.type === 'function') {
                abiItem.signature = _this.abiCoder.encodeFunctionSignature(abiItem.funcName);
                abiItemModel = _this.contractModuleFactory.createAbiItemModel(abiItem);
                if (!mappedAbiItems.methods[abiItem.name]) {
                  mappedAbiItems.methods[abiItem.name] = abiItemModel;
                } else {
                  if (isArray(mappedAbiItems.methods[abiItem.name])) {
                    mappedAbiItems.methods[abiItem.name].push(abiItemModel);
                  } else {
                    mappedAbiItems.methods[abiItem.name] = [mappedAbiItems.methods[abiItem.name], abiItemModel];
                  }
                }
                mappedAbiItems.methods[abiItem.signature] = abiItemModel;
                mappedAbiItems.methods[abiItem.funcName] = abiItemModel;
                return;
              }
              if (abiItem.type === 'event') {
                abiItem.signature = _this.abiCoder.encodeEventSignature(abiItem.funcName);
                abiItemModel = _this.contractModuleFactory.createAbiItemModel(abiItem);
                if (!mappedAbiItems.events[abiItem.name] || mappedAbiItems.events[abiItem.name].name === 'bound ') {
                  mappedAbiItems.events[abiItem.name] = abiItemModel;
                }
                mappedAbiItems.events[abiItem.signature] = abiItemModel;
                mappedAbiItems.events[abiItem.funcName] = abiItemModel;
              }
              if (abiItem.type === 'constructor') {
                abiItem.signature = abiItem.type;
                mappedAbiItems.methods['contractConstructor'] = _this.contractModuleFactory.createAbiItemModel(abiItem);
              }
            });
            return this.contractModuleFactory.createAbiModel(mappedAbiItems);
          }
        }, {
          key: "isConstant",
          value: function isConstant(abiItem) {
            return abiItem.stateMutability === 'view' || abiItem.stateMutability === 'pure' || abiItem.constant;
          }
        }, {
          key: "isPayable",
          value: function isPayable(abiItem) {
            return abiItem.stateMutability === 'payable' || abiItem.payable;
          }
        }]);
        return AbiMapper;
      }();
  
      var MethodOptionsMapper =
      function () {
        function MethodOptionsMapper(utils, formatters) {
          _classCallCheck(this, MethodOptionsMapper);
          this.utils = utils;
          this.formatters = formatters;
        }
        _createClass(MethodOptionsMapper, [{
          key: "map",
          value: function map(contract, options) {
            var from = null;
            if (options.from) {
              from = this.utils.toChecksumAddress(this.formatters.inputAddressFormatter(options.from));
            }
            options.to = contract.address;
            options.from = from || contract.defaultAccount;
            options.gasPrice = options.gasPrice || contract.defaultGasPrice;
            options.gas = options.gas || options.gasLimit || contract.defaultGas;
            delete options.gasLimit;
            return options;
          }
        }]);
        return MethodOptionsMapper;
      }();
  
      var EventOptionsMapper =
      function () {
        function EventOptionsMapper(formatters, eventFilterEncoder) {
          _classCallCheck(this, EventOptionsMapper);
          this.formatters = formatters;
          this.eventFilterEncoder = eventFilterEncoder;
        }
        _createClass(EventOptionsMapper, [{
          key: "map",
          value: function map(abiItemModel, contract, options) {
            if (!options) {
              options = {};
            }
            if (!isArray(options.topics)) {
              options.topics = [];
            }
            if (typeof options.fromBlock !== 'undefined') {
              options.fromBlock = this.formatters.inputBlockNumberFormatter(options.fromBlock);
            } else if (contract.defaultBlock !== null) {
              options.fromBlock = contract.defaultBlock;
            }
            if (typeof options.toBlock !== 'undefined') {
              options.toBlock = this.formatters.inputBlockNumberFormatter(options.toBlock);
            }
            if (!abiItemModel.anonymous) {
              options.topics.unshift(abiItemModel.signature);
            }
            if (typeof options.filter !== 'undefined') {
              options.topics = options.topics.concat(this.eventFilterEncoder.encode(abiItemModel, options.filter));
            }
            if (!options.address) {
              options.address = contract.address;
            }
            return options;
          }
        }]);
        return EventOptionsMapper;
      }();
  
      var AllEventsOptionsMapper =
      function () {
        function AllEventsOptionsMapper(formatters, allEventsFilterEncoder) {
          _classCallCheck(this, AllEventsOptionsMapper);
          this.formatters = formatters;
          this.allEventsFilterEncoder = allEventsFilterEncoder;
        }
        _createClass(AllEventsOptionsMapper, [{
          key: "map",
          value: function map(abiModel, contract, options) {
            if (!options) {
              options = {};
            }
            options.topics = [];
            if (typeof options.fromBlock !== 'undefined') {
              options.fromBlock = this.formatters.inputBlockNumberFormatter(options.fromBlock);
            } else if (contract.defaultBlock !== null) {
              options.fromBlock = contract.defaultBlock;
            }
            if (typeof options.toBlock !== 'undefined') {
              options.toBlock = this.formatters.inputBlockNumberFormatter(options.toBlock);
            }
            if (typeof options.filter !== 'undefined') {
              options.topics = options.topics.concat(this.allEventsFilterEncoder.encode(abiModel, options.filter));
            }
            if (!options.address) {
              options.address = contract.address;
            }
            return options;
          }
        }]);
        return AllEventsOptionsMapper;
      }();
  
      var MethodsProxy =
      function () {
        function MethodsProxy(contract, abiModel, methodFactory, methodEncoder, methodOptionsValidator, methodOptionsMapper, PromiEvent) {
          var _this = this;
          _classCallCheck(this, MethodsProxy);
          this.contract = contract;
          this.abiModel = abiModel;
          this.methodFactory = methodFactory;
          this.methodEncoder = methodEncoder;
          this.methodOptionsValidator = methodOptionsValidator;
          this.methodOptionsMapper = methodOptionsMapper;
          this.PromiEvent = PromiEvent;
          return new Proxy(this, {
            get: function get(target, name) {
              if (_this.abiModel.hasMethod(name)) {
                var anonymousFunction = function anonymousFunction() {
                  var methodArguments = cloneDeep(Array.prototype.slice.call(arguments));
                  if (!isArray(abiItemModel) && abiItemModel.isOfType('constructor')) {
                    if (methodArguments[0]['data']) {
                      target.contract.options.data = methodArguments[0]['data'];
                    }
                    if (methodArguments[0]['arguments']) {
                      abiItemModel.contractMethodParameters = methodArguments[0]['arguments'];
                    }
                    return anonymousFunction;
                  }
                  if (isArray(abiItemModel)) {
                    var abiItemModelFound = abiItemModel.some(function (model) {
                      model.contractMethodParameters = methodArguments;
                      try {
                        model.givenParametersLengthIsValid();
                      } catch (error) {
                        return false;
                      }
                      abiItemModel = model;
                      return true;
                    });
                    if (!abiItemModelFound) {
                      throw new Error("Methods with name \"".concat(name, "\" found but the given parameters are wrong"));
                    }
                    return anonymousFunction;
                  }
                  abiItemModel.contractMethodParameters = methodArguments;
                  return anonymousFunction;
                };
                var abiItemModel = _this.abiModel.getMethod(name);
                var requestType = abiItemModel.requestType;
                if (isArray(abiItemModel)) {
                  requestType = abiItemModel[0].requestType;
                }
                anonymousFunction[requestType] = function () {
                  if (abiItemModel.isOfType('constructor')) {
                    return target.executeMethod(abiItemModel, cloneDeep(arguments), 'contract-deployment');
                  }
                  return target.executeMethod(abiItemModel, cloneDeep(arguments), requestType);
                };
                anonymousFunction[requestType].request = function () {
                  return target.createMethod(abiItemModel, cloneDeep(arguments), requestType);
                };
                anonymousFunction.estimateGas = function () {
                  return target.executeMethod(abiItemModel, cloneDeep(arguments), 'estimate');
                };
                anonymousFunction.encodeABI = function () {
                  return target.methodEncoder.encode(abiItemModel, target.contract.options.data);
                };
                return anonymousFunction;
              }
              if (target[name]) {
                return target[name];
              }
            }
          });
        }
        _createClass(MethodsProxy, [{
          key: "executeMethod",
          value: function executeMethod(abiItemModel, methodArguments, requestType) {
            var method;
            try {
              method = this.createMethod(abiItemModel, methodArguments, requestType);
            } catch (error) {
              var promiEvent = new this.PromiEvent();
              method = this.methodFactory.createMethodByRequestType(abiItemModel, this.contract, requestType);
              method.arguments = methodArguments;
              promiEvent.reject(error);
              promiEvent.emit('error', error);
              if (isFunction(method.callback)) {
                method.callback(error, null);
              }
              return promiEvent;
            }
            if (requestType === 'call' || requestType === 'estimate') {
              return method.execute(this.contract);
            }
            return method.execute(this.contract, new this.PromiEvent());
          }
        }, {
          key: "createMethod",
          value: function createMethod(abiItemModel, methodArguments, requestType) {
            abiItemModel.givenParametersLengthIsValid();
            var method = this.methodFactory.createMethodByRequestType(abiItemModel, this.contract, requestType);
            method.arguments = methodArguments;
            if (typeof method.parameters[0] === 'undefined') {
              method.parameters[0] = {};
            }
            method.parameters[0]['data'] = this.methodEncoder.encode(abiItemModel, this.contract.options.data);
            method.parameters[0] = this.methodOptionsMapper.map(this.contract, method.parameters[0]);
            this.methodOptionsValidator.validate(abiItemModel, method);
            return method;
          }
        }]);
        return MethodsProxy;
      }();
  
      var EventSubscriptionsProxy =
      function () {
        function EventSubscriptionsProxy(contract, abiModel, eventSubscriptionFactory, eventOptionsMapper, eventLogDecoder, allEventsLogDecoder, allEventsOptionsMapper, PromiEvent) {
          var _this = this;
          _classCallCheck(this, EventSubscriptionsProxy);
          this.contract = contract;
          this.eventSubscriptionFactory = eventSubscriptionFactory;
          this.abiModel = abiModel;
          this.eventOptionsMapper = eventOptionsMapper;
          this.eventLogDecoder = eventLogDecoder;
          this.allEventsLogDecoder = allEventsLogDecoder;
          this.allEventsOptionsMapper = allEventsOptionsMapper;
          this.PromiEvent = PromiEvent;
          return new Proxy(this, {
            get: function get(target, name) {
              if (_this.abiModel.hasEvent(name)) {
                return function (options, callback) {
                  return target.subscribe(target.abiModel.getEvent(name), cloneDeep(options), callback);
                };
              }
              if (name === 'allEvents') {
                return function (options, callback) {
                  return target.subscribeAll(cloneDeep(options), callback);
                };
              }
              return target[name];
            }
          });
        }
        _createClass(EventSubscriptionsProxy, [{
          key: "subscribe",
          value: function subscribe(abiItemModel, options, callback) {
            if (options && !isUndefined(options.filter) && !isUndefined(options.topics)) {
              this.handleValidationError('Invalid subscription options: Only filter or topics are allowed and not both', callback);
              return;
            }
            return this.eventSubscriptionFactory.createEventLogSubscription(this.eventLogDecoder, this.contract, this.eventOptionsMapper.map(abiItemModel, this.contract, options), abiItemModel).subscribe(callback);
          }
        }, {
          key: "subscribeAll",
          value: function subscribeAll(options, callback) {
            if (options && !isUndefined(options.filter) && !isUndefined(options.topics)) {
              this.handleValidationError('Invalid subscription options: Only filter or topics are allowed and not both', callback);
              return;
            }
            return this.eventSubscriptionFactory.createAllEventsLogSubscription(this.allEventsLogDecoder, this.contract, this.allEventsOptionsMapper.map(this.abiModel, this.contract, options)).subscribe(callback);
          }
        }, {
          key: "handleValidationError",
          value: function handleValidationError(errorMessage, callback) {
            var error = new Error(errorMessage);
            if (isFunction(callback)) {
              callback(error, null);
            }
            throw error;
          }
        }]);
        return EventSubscriptionsProxy;
      }();
  
      var SendContractMethod =
      function (_SendTransactionMetho) {
        _inherits(SendContractMethod, _SendTransactionMetho);
        function SendContractMethod(utils, formatters, transactionConfirmationWorkflow, accounts, transactionSigner, allEventsLogDecoder, abiModel) {
          var _this;
          _classCallCheck(this, SendContractMethod);
          _this = _possibleConstructorReturn(this, _getPrototypeOf(SendContractMethod).call(this, utils, formatters, transactionConfirmationWorkflow, accounts, transactionSigner));
          _this.allEventsLogDecoder = allEventsLogDecoder;
          _this.abiModel = abiModel;
          return _this;
        }
        _createClass(SendContractMethod, [{
          key: "afterExecution",
          value: function afterExecution(response) {
            var _this2 = this;
            if (isArray(response.logs)) {
              response.events = {};
              response.logs.forEach(function (log, index) {
                log = _this2.allEventsLogDecoder.decode(_this2.abiModel, log);
                if (log.event) {
                  if (response.events[log.event]) {
                    if (isArray(response.events[log.event])) {
                      response.events[log.event].push(log);
                      return;
                    }
                    response.events[log.event] = [response.events[log.event], log];
                    return;
                  }
                  response.events[log.event] = log;
                  return;
                }
                response.events[index] = log;
              });
              delete response.logs;
            }
            return response;
          }
        }]);
        return SendContractMethod;
      }(web3CoreMethod.SendTransactionMethod);
  
      var MethodOptionsValidator =
      function () {
        function MethodOptionsValidator(utils) {
          _classCallCheck(this, MethodOptionsValidator);
          this.utils = utils;
        }
        _createClass(MethodOptionsValidator, [{
          key: "validate",
          value: function validate(abiItemModel, method) {
            if (!this.isToSet(abiItemModel, method)) {
              throw new Error("This contract object doesn't have address set yet, please set an address first.");
            }
            if (!this.isFromSet(method) && method instanceof SendContractMethod) {
              throw new Error('No valid "from" address specified in neither the given options, nor the default options.');
            }
            if (!this.isValueValid(abiItemModel, method)) {
              throw new Error('Can not send value to non-payable contract method or constructor');
            }
            return true;
          }
        }, {
          key: "isToSet",
          value: function isToSet(abiItemModel, method) {
            if (abiItemModel.signature === 'constructor') {
              return true;
            }
            return this.utils.isAddress(method.parameters[0].to);
          }
        }, {
          key: "isFromSet",
          value: function isFromSet(method) {
            return this.utils.isAddress(method.parameters[0].from);
          }
        }, {
          key: "isValueValid",
          value: function isValueValid(abiItemModel, method) {
            return !(!abiItemModel.payable && method.parameters[0].value && method.parameters[0].value > 0);
          }
        }]);
        return MethodOptionsValidator;
      }();
  
      var CallContractMethod =
      function (_CallMethod) {
        _inherits(CallContractMethod, _CallMethod);
        function CallContractMethod(utils, formatters, abiCoder, abiItemModel) {
          var _this;
          _classCallCheck(this, CallContractMethod);
          _this = _possibleConstructorReturn(this, _getPrototypeOf(CallContractMethod).call(this, utils, formatters));
          _this.abiCoder = abiCoder;
          _this.abiItemModel = abiItemModel;
          return _this;
        }
        _createClass(CallContractMethod, [{
          key: "afterExecution",
          value: function afterExecution(response) {
            if (!response) {
              return null;
            }
            if (response.length >= 2) {
              response = response.slice(2);
            }
            var result = this.abiCoder.decodeParameters(this.abiItemModel.getOutputs(), response);
            if (Object.keys(result).length === 1) {
              return result[0];
            }
            return result;
          }
        }]);
        return CallContractMethod;
      }(web3CoreMethod.CallMethod);
  
      var ContractDeployMethod =
      function (_SendTransactionMetho) {
        _inherits(ContractDeployMethod, _SendTransactionMetho);
        function ContractDeployMethod(utils, formatters, transactionConfirmationWorkflow, accounts, transactionSigner, contract) {
          var _this;
          _classCallCheck(this, ContractDeployMethod);
          _this = _possibleConstructorReturn(this, _getPrototypeOf(ContractDeployMethod).call(this, utils, formatters, transactionConfirmationWorkflow, accounts, transactionSigner));
          _this.contract = contract;
          return _this;
        }
        _createClass(ContractDeployMethod, [{
          key: "beforeExecution",
          value: function beforeExecution(moduleInstance) {
            _get(_getPrototypeOf(ContractDeployMethod.prototype), "beforeExecution", this).call(this, moduleInstance);
            delete this.parameters[0].to;
          }
        }, {
          key: "afterExecution",
          value: function afterExecution(response) {
            var clonedContract = this.contract.clone();
            clonedContract.options.address = response.contractAddress;
            return clonedContract;
          }
        }]);
        return ContractDeployMethod;
      }(web3CoreMethod.SendTransactionMethod);
  
      var PastEventLogsMethod =
      function (_GetPastLogsMethod) {
        _inherits(PastEventLogsMethod, _GetPastLogsMethod);
        function PastEventLogsMethod(utils, formatters, eventLogDecoder, abiItemModel) {
          var _this;
          _classCallCheck(this, PastEventLogsMethod);
          _this = _possibleConstructorReturn(this, _getPrototypeOf(PastEventLogsMethod).call(this, utils, formatters));
          _this.abiItemModel = abiItemModel;
          _this.eventLogDecoder = eventLogDecoder;
          return _this;
        }
        _createClass(PastEventLogsMethod, [{
          key: "afterExecution",
          value: function afterExecution(response) {
            var _this2 = this;
            var formattedLogs = _get(_getPrototypeOf(PastEventLogsMethod.prototype), "afterExecution", this).call(this, response);
            return formattedLogs.map(function (logItem) {
              return _this2.eventLogDecoder.decode(_this2.abiItemModel, logItem);
            });
          }
        }]);
        return PastEventLogsMethod;
      }(web3CoreMethod.GetPastLogsMethod);
  
      var MethodFactory =
      function () {
        function MethodFactory(accounts, utils, formatters, contractModuleFactory, methodModuleFactory, abiCoder) {
          _classCallCheck(this, MethodFactory);
          this.accounts = accounts;
          this.utils = utils;
          this.formatters = formatters;
          this.contractModuleFactory = contractModuleFactory;
          this.methodModuleFactory = methodModuleFactory;
          this.abiCoder = abiCoder;
        }
        _createClass(MethodFactory, [{
          key: "createMethodByRequestType",
          value: function createMethodByRequestType(abiItem, contract, requestType) {
            var rpcMethod;
            switch (requestType) {
              case 'call':
                rpcMethod = this.createCallContractMethod(abiItem);
                break;
              case 'send':
                rpcMethod = this.createSendContractMethod(abiItem, contract.abiModel);
                break;
              case 'estimate':
                rpcMethod = this.createEstimateGasMethod();
                break;
              case 'contract-deployment':
                rpcMethod = this.createContractDeployMethod(contract);
                break;
            }
            if (typeof rpcMethod === 'undefined') {
              throw new TypeError("RPC call not found with requestType: \"".concat(requestType, "\""));
            }
            return rpcMethod;
          }
        }, {
          key: "createPastEventLogsMethod",
          value: function createPastEventLogsMethod(abiItem) {
            return new PastEventLogsMethod(this.utils, this.formatters, this.contractModuleFactory.createEventLogDecoder(), abiItem);
          }
        }, {
          key: "createCallContractMethod",
          value: function createCallContractMethod(abiItem) {
            return new CallContractMethod(this.utils, this.formatters, this.abiCoder, abiItem);
          }
        }, {
          key: "createSendContractMethod",
          value: function createSendContractMethod(abiItem, abiModel) {
            return new SendContractMethod(this.utils, this.formatters, this.methodModuleFactory.createTransactionConfirmationWorkflow(), this.accounts, this.methodModuleFactory.createTransactionSigner(), this.contractModuleFactory.createAllEventsLogDecoder(), abiModel);
          }
        }, {
          key: "createContractDeployMethod",
          value: function createContractDeployMethod(contract) {
            return new ContractDeployMethod(this.utils, this.formatters, this.methodModuleFactory.createTransactionConfirmationWorkflow(), this.accounts, this.methodModuleFactory.createTransactionSigner(), contract);
          }
        }, {
          key: "createEstimateGasMethod",
          value: function createEstimateGasMethod() {
            return new web3CoreMethod.EstimateGasMethod(this.utils, this.formatters);
          }
        }]);
        return MethodFactory;
      }();
  
      var EventLogSubscription =
      function (_LogSubscription) {
        _inherits(EventLogSubscription, _LogSubscription);
        function EventLogSubscription(options, utils, formatters, contract, getPastLogsMethod, eventLogDecoder, abiItemModel) {
          var _this;
          _classCallCheck(this, EventLogSubscription);
          _this = _possibleConstructorReturn(this, _getPrototypeOf(EventLogSubscription).call(this, options, utils, formatters, contract, getPastLogsMethod));
          _this.eventLogDecoder = eventLogDecoder;
          _this.abiItemModel = abiItemModel;
          return _this;
        }
        _createClass(EventLogSubscription, [{
          key: "onNewSubscriptionItem",
          value: function onNewSubscriptionItem(subscriptionItem) {
            return this.eventLogDecoder.decode(this.abiItemModel, this.formatters.outputLogFormatter(subscriptionItem));
          }
        }]);
        return EventLogSubscription;
      }(web3CoreSubscriptions.LogSubscription);
  
      var AllEventsLogSubscription =
      function (_LogSubscription) {
        _inherits(AllEventsLogSubscription, _LogSubscription);
        function AllEventsLogSubscription(options, utils, formatters, contract, getPastLogsMethod, allEventsLogDecoder, abiModel) {
          var _this;
          _classCallCheck(this, AllEventsLogSubscription);
          _this = _possibleConstructorReturn(this, _getPrototypeOf(AllEventsLogSubscription).call(this, options, utils, formatters, contract, getPastLogsMethod));
          _this.allEventsLogDecoder = allEventsLogDecoder;
          _this.abiModel = abiModel;
          return _this;
        }
        _createClass(AllEventsLogSubscription, [{
          key: "onNewSubscriptionItem",
          value: function onNewSubscriptionItem(subscriptionItem) {
            return this.allEventsLogDecoder.decode(this.abiModel, this.formatters.outputLogFormatter(subscriptionItem));
          }
        }]);
        return AllEventsLogSubscription;
      }(web3CoreSubscriptions.LogSubscription);
  
      var EventSubscriptionFactory =
      function () {
        function EventSubscriptionFactory(utils, formatters) {
          _classCallCheck(this, EventSubscriptionFactory);
          this.utils = utils;
          this.formatters = formatters;
        }
        _createClass(EventSubscriptionFactory, [{
          key: "createEventLogSubscription",
          value: function createEventLogSubscription(eventLogDecoder, contract, options, abiItemModel) {
            return new EventLogSubscription(options, this.utils, this.formatters, contract, new web3CoreMethod.GetPastLogsMethod(this.utils, this.formatters), eventLogDecoder, abiItemModel);
          }
        }, {
          key: "createAllEventsLogSubscription",
          value: function createAllEventsLogSubscription(allEventsLogDecoder, contract, options) {
            return new AllEventsLogSubscription(options, this.utils, this.formatters, contract, new web3CoreMethod.GetPastLogsMethod(this.utils, this.formatters), allEventsLogDecoder, contract.abiModel);
          }
        }]);
        return EventSubscriptionFactory;
      }();
  
      var AbstractContract =
      function (_AbstractWeb3Module) {
        _inherits(AbstractContract, _AbstractWeb3Module);
        function AbstractContract(provider, providersModuleFactory, methodModuleFactory, contractModuleFactory, PromiEvent, abiCoder, utils, formatters) {
          var _this;
          var abi = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : web3Core.AbstractWeb3Module.throwIfMissing('abi');
          var address = arguments.length > 9 ? arguments[9] : undefined;
          var options = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : {};
          _classCallCheck(this, AbstractContract);
          _this = _possibleConstructorReturn(this, _getPrototypeOf(AbstractContract).call(this, provider, providersModuleFactory, methodModuleFactory, null, options));
          _this.contractModuleFactory = contractModuleFactory;
          _this.abiCoder = abiCoder;
          _this.utils = utils;
          _this.formatters = formatters;
          _this.abiMapper = _this.contractModuleFactory.createAbiMapper();
          _this.options = options;
          _this.PromiEvent = PromiEvent;
          _this.methodFactory = _this.contractModuleFactory.createMethodFactory();
          _this.abiModel = _this.abiMapper.map(abi);
          _this.options = options;
          if (address) {
            _this.address = address;
          }
          _this.methods = _this.contractModuleFactory.createMethodsProxy(_assertThisInitialized(_assertThisInitialized(_this)), _this.abiModel, _this.PromiEvent);
          _this.events = _this.contractModuleFactory.createEventSubscriptionsProxy(_assertThisInitialized(_assertThisInitialized(_this)), _this.abiModel, _this.PromiEvent);
          return _this;
        }
        _createClass(AbstractContract, [{
          key: "once",
          value: function once(eventName, options, callback) {
            if (!callback) {
              throw new Error('Once requires a callback function.');
            }
            if (options) {
              delete options.fromBlock;
            }
            var eventSubscription = this.events[eventName](options, callback);
            eventSubscription.on('data', function () {
              eventSubscription.unsubscribe();
            });
          }
        }, {
          key: "getPastEvents",
          value: function getPastEvents(eventName, options, callback) {
            var _this2 = this;
            return new Promise(
            function () {
              var _ref = _asyncToGenerator(
              _regeneratorRuntime.mark(function _callee(resolve, reject) {
                var pastEventLogsMethod;
                return _regeneratorRuntime.wrap(function _callee$(_context) {
                  while (1) {
                    switch (_context.prev = _context.next) {
                      case 0:
                        if (!_this2.abiModel.hasEvent(eventName)) {
                          reject(new Error("Event with name \"".concat(eventName, "\" does not exists.")));
                        }
                        pastEventLogsMethod = _this2.methodFactory.createPastEventLogsMethod(_this2.abiModel.getEvent(eventName));
                        pastEventLogsMethod.parameters = [options];
                        pastEventLogsMethod.callback = callback;
                        _context.t0 = resolve;
                        _context.next = 7;
                        return pastEventLogsMethod.execute(_this2);
                      case 7:
                        _context.t1 = _context.sent;
                        return _context.abrupt("return", (0, _context.t0)(_context.t1));
                      case 9:
                      case "end":
                        return _context.stop();
                    }
                  }
                }, _callee, this);
              }));
              return function (_x, _x2) {
                return _ref.apply(this, arguments);
              };
            }());
          }
        }, {
          key: "deploy",
          value: function deploy(options) {
            return this.methods.contractConstructor(options);
          }
        }, {
          key: "clone",
          value: function clone() {
            var contract = new this.constructor(this.currentProvider, this.providersModuleFactory, this.methodModuleFactory, this.contractModuleFactory, this.PromiEvent, this.abiCoder, this.utils, this.formatters, [], this.address, this.options);
            contract.abiModel = this.abiModel;
            contract.methods.abiModel = this.abiModel;
            contract.events.abiModel = this.abiModel;
            return contract;
          }
        }, {
          key: "jsonInterface",
          get: function get() {
            return this.abiModel;
          }
          ,
          set: function set(value) {
            this.abiModel = this.abiMapper.map(value);
            this.methods.abiModel = this.abiModel;
            this.events.abiModel = this.abiModel;
          }
        }, {
          key: "address",
          get: function get() {
            return this.options.address;
          }
          ,
          set: function set(value) {
            this.options.address = value;
          }
        }]);
        return AbstractContract;
      }(web3Core.AbstractWeb3Module);
  
      var ContractModuleFactory =
      function () {
        function ContractModuleFactory(utils, formatters, abiCoder, accounts, methodModuleFactory) {
          _classCallCheck(this, ContractModuleFactory);
          this.utils = utils;
          this.formatters = formatters;
          this.abiCoder = abiCoder;
          this.accounts = accounts;
          this.methodModuleFactory = methodModuleFactory;
        }
        _createClass(ContractModuleFactory, [{
          key: "createContract",
          value: function createContract(provider, providersModuleFactory, PromiEvent, abi, address, options) {
            return new AbstractContract(provider, providersModuleFactory, this.methodModuleFactory, this, PromiEvent, this.abiCoder, this.utils, this.formatters, abi, address, options);
          }
        }, {
          key: "createAbiModel",
          value: function createAbiModel(mappedAbi) {
            return new AbiModel(mappedAbi);
          }
        }, {
          key: "createAbiItemModel",
          value: function createAbiItemModel(abiItem) {
            return new AbiItemModel(abiItem);
          }
        }, {
          key: "createMethodEncoder",
          value: function createMethodEncoder() {
            return new MethodEncoder(this.abiCoder);
          }
        }, {
          key: "createEventFilterEncoder",
          value: function createEventFilterEncoder() {
            return new EventFilterEncoder(this.abiCoder);
          }
        }, {
          key: "createAllEventsFilterEncoder",
          value: function createAllEventsFilterEncoder() {
            return new AllEventsFilterEncoder(this.abiCoder);
          }
        }, {
          key: "createAbiMapper",
          value: function createAbiMapper() {
            return new AbiMapper(this, this.abiCoder, this.utils);
          }
        }, {
          key: "createEventLogDecoder",
          value: function createEventLogDecoder() {
            return new EventLogDecoder(this.abiCoder);
          }
        }, {
          key: "createAllEventsLogDecoder",
          value: function createAllEventsLogDecoder() {
            return new AllEventsLogDecoder(this.abiCoder);
          }
        }, {
          key: "createMethodOptionsValidator",
          value: function createMethodOptionsValidator() {
            return new MethodOptionsValidator(this.utils);
          }
        }, {
          key: "createMethodOptionsMapper",
          value: function createMethodOptionsMapper() {
            return new MethodOptionsMapper(this.utils, this.formatters);
          }
        }, {
          key: "createEventOptionsMapper",
          value: function createEventOptionsMapper() {
            return new EventOptionsMapper(this.formatters, this.createEventFilterEncoder());
          }
        }, {
          key: "createAllEventsOptionsMapper",
          value: function createAllEventsOptionsMapper() {
            return new AllEventsOptionsMapper(this.formatters, this.createAllEventsFilterEncoder());
          }
        }, {
          key: "createMethodFactory",
          value: function createMethodFactory() {
            return new MethodFactory(this.accounts, this.utils, this.formatters, this, this.methodModuleFactory, this.abiCoder);
          }
        }, {
          key: "createMethodsProxy",
          value: function createMethodsProxy(target, abiModel, PromiEvent) {
            return new MethodsProxy(target, abiModel, this.createMethodFactory(), this.createMethodEncoder(), this.createMethodOptionsValidator(), this.createMethodOptionsMapper(), PromiEvent);
          }
        }, {
          key: "createEventSubscriptionsProxy",
          value: function createEventSubscriptionsProxy(contract, abiModel, PromiEvent) {
            return new EventSubscriptionsProxy(contract, abiModel, this.createEventSubscriptionFactory(), this.createEventOptionsMapper(), this.createEventLogDecoder(), this.createAllEventsLogDecoder(), this.createAllEventsOptionsMapper(), PromiEvent);
          }
        }, {
          key: "createEventSubscriptionFactory",
          value: function createEventSubscriptionFactory() {
            return new EventSubscriptionFactory(this.utils, this.formatters);
          }
        }]);
        return ContractModuleFactory;
      }();
  
      var Contract = function Contract(provider, accounts, abi, address, options) {
        return new ContractModuleFactory(Utils, web3CoreHelpers.formatters, new web3EthAbi.AbiCoder(), accounts, new web3CoreMethod.MethodModuleFactory(accounts)).createContract(provider, new web3Providers.ProvidersModuleFactory(), web3CorePromievent.PromiEvent, abi, address, options);
      };
  
      exports.AbstractContract = AbstractContract;
      exports.ContractModuleFactory = ContractModuleFactory;
      exports.Contract = Contract;
  
      Object.defineProperty(exports, '__esModule', { value: true });
  
  })));
  