'use strict';Object.defineProperty(exports, "__esModule", { value: true });var _extends = Object.assign || function (target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i];for (var key in source) {if (Object.prototype.hasOwnProperty.call(source, key)) {target[key] = source[key];}}}return target;};exports.

























confirmOperation = confirmOperation;exports.



revokeOperation = revokeOperation;exports.


























attachWallets = attachWallets;exports.













































load = load;var _lodash = require('lodash');var _contract = require('@parity/api/lib/contract');var _contract2 = _interopRequireDefault(_contract);var _error = require('@parity/api/lib/transport/error');var _actions = require('@parity/ui/lib/Errors/actions');var _abi = require('../../contracts/abi');var _wallets2 = require('../../util/wallets');var _wallets3 = _interopRequireDefault(_wallets2);var _updates3 = require('../../util/wallets/updates');function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { default: obj };}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;} // Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
function confirmOperation(address, owner, operation) {return modifyOperation('confirm', address, owner, operation);}function revokeOperation(address, owner, operation) {return modifyOperation('revoke', address, owner, operation);}function modifyOperation(modification, address, owner, operation) {return function (dispatch, getState) {var _getState = getState(),api = _getState.api;dispatch(setOperationPendingState(address, operation, true));_wallets3.default.postModifyOperation(api, address, modification, owner, operation).then(function (requestId) {return api.pollMethod('parity_checkRequest', requestId);}).catch(function (error) {if (error.code === _error.ERROR_CODES.REQUEST_REJECTED) {return;}dispatch((0, _actions.newError)(error));}).then(function () {dispatch(setOperationPendingState(address, operation, false));});};}function attachWallets(_wallets) {return function (dispatch, getState) {var _getState2 = getState(),wallet = _getState2.wallet,api = _getState2.api;var prevAddresses = wallet.walletsAddresses;var nextAddresses = Object.keys(_wallets).map(function (a) {return a.toLowerCase();}).sort();if ((0, _lodash.isEqual)(prevAddresses, nextAddresses)) {return;}if (wallet.filterSubId) {api.eth.uninstallFilter(wallet.filterSubId);}if (nextAddresses.length === 0) {return dispatch(updateWallets({ wallets: {}, walletsAddresses: [], filterSubId: null }));} // Filter the logs from the current block
    api.eth.blockNumber().then(function (block) {var filterOptions = { fromBlock: block, toBlock: 'latest', address: nextAddresses };return api.eth.newFilter(filterOptions);}).then(function (filterId) {dispatch(updateWallets({ wallets: _wallets, walletsAddresses: nextAddresses, filterSubId: filterId }));}).catch(function (error) {if (process.env.NODE_ENV === 'production') {console.error('walletActions::attachWallets', error);} else {throw error;}});fetchWalletsInfo(Object.keys(_wallets))(dispatch, getState);};}function load(api) {return function (dispatch, getState) {var contract = new _contract2.default(api, _abi.foundationWallet);dispatch(setWalletContract(contract));api.subscribe('eth_blockNumber', function (error) {if (error) {if (process.env.NODE_ENV === 'production') {return console.error('[eth_blockNumber] walletActions::load', error);} else {throw error;}}var
      filterSubId = getState().wallet.filterSubId;

      if (!filterSubId) {
        return;
      }

      api.eth.
      getFilterChanges(filterSubId).
      then(function (logs) {
        parseLogs(logs)(dispatch, getState);
      }).
      catch(function (error) {
        if (process.env.NODE_ENV === 'production') {
          return console.error('[getFilterChanges] walletActions::load', error);
        } else {
          throw error;
        }
      });
    });
  };
}

function fetchWalletsInfo(updates) {
  return function (dispatch, getState) {
    if (Array.isArray(updates)) {
      var _updates2 = updates.reduce(function (updates, address) {var _updates$address;
        updates[address] = (_updates$address = {}, _defineProperty(_updates$address, _updates3.UPDATE_OWNERS,
        true), _defineProperty(_updates$address, _updates3.UPDATE_REQUIRE,
        true), _defineProperty(_updates$address, _updates3.UPDATE_DAILYLIMIT,
        true), _defineProperty(_updates$address, _updates3.UPDATE_CONFIRMATIONS,
        true), _defineProperty(_updates$address, _updates3.UPDATE_TRANSACTIONS,
        true), _defineProperty(_updates$address, 'address',
        address), _updates$address);


        return updates;
      }, {});

      return fetchWalletsInfo(_updates2)(dispatch, getState);
    }var _getState3 =

    getState(),api = _getState3.api;
    var _updates = Object.values(updates);

    Promise.
    all(_updates.map(function (update) {
      var contract = new _contract2.default(api, _abi.foundationWallet).at(update.address);

      return fetchWalletInfo(contract, update, getState);
    })).
    then(function (updates) {
      dispatch(updateWalletsDetails(updates));
    }).
    catch(function (error) {
      if (process.env.NODE_ENV === 'production') {
        return console.error('walletAction::fetchWalletsInfo', error);
      } else {
        throw error;
      }
    });
  };
}

function fetchWalletInfo(contract, update, getState) {
  var promises = [];

  if (update[_updates3.UPDATE_OWNERS]) {
    promises.push(fetchWalletOwners(contract));
  }

  if (update[_updates3.UPDATE_REQUIRE]) {
    promises.push(fetchWalletRequire(contract));
  }

  if (update[_updates3.UPDATE_DAILYLIMIT]) {
    promises.push(fetchWalletDailylimit(contract));
  }

  if (update[_updates3.UPDATE_TRANSACTIONS]) {
    promises.push(fetchWalletTransactions(contract));
  }

  return Promise.
  all(promises).
  then(function (updates) {
    if (update[_updates3.UPDATE_CONFIRMATIONS]) {
      var ownersUpdate = updates.find(function (u) {return u.key === _updates3.UPDATE_OWNERS;});
      var transactionsUpdate = updates.find(function (u) {return u.key === _updates3.UPDATE_TRANSACTIONS;});

      var owners = ownersUpdate && ownersUpdate.value || null;
      var transactions = transactionsUpdate && transactionsUpdate.value || null;

      return fetchWalletConfirmations(contract, update[_updates3.UPDATE_CONFIRMATIONS], owners, transactions, getState).
      then(function (update) {
        updates.push(update);
        return updates;
      });
    }

    return updates;
  }).
  then(function (updates) {
    var wallet = { address: update.address };

    updates.forEach(function (update) {
      wallet[update.key] = update.value;
    });

    return wallet;
  });
}

function fetchWalletTransactions(contract) {
  return _wallets3.default.
  fetchTransactions(contract).
  then(function (transactions) {
    return {
      key: _updates3.UPDATE_TRANSACTIONS,
      value: transactions };

  });
}

function fetchWalletOwners(contract) {
  return _wallets3.default.
  fetchOwners(contract).
  then(function (value) {
    return {
      key: _updates3.UPDATE_OWNERS,
      value: value };

  });
}

function fetchWalletRequire(contract) {
  return _wallets3.default.
  fetchRequire(contract).
  then(function (value) {
    return {
      key: _updates3.UPDATE_REQUIRE,
      value: value };

  });
}

function fetchWalletDailylimit(contract) {
  return _wallets3.default.
  fetchDailylimit(contract).
  then(function (value) {
    return {
      key: _updates3.UPDATE_DAILYLIMIT,
      value: value };

  });
}

function fetchWalletConfirmations(contract, _operations) {var _owners = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;var _transactions = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;var getState = arguments[4];
  var wallet = getState().wallet.wallets[contract.address];

  var owners = _owners || wallet && wallet.owners || null;
  var transactions = _transactions || wallet && wallet.transactions || null;
  var cache = { owners: owners, transactions: transactions };

  return _wallets3.default.fetchPendingTransactions(contract, cache).
  then(function (confirmations) {
    return {
      key: _updates3.UPDATE_CONFIRMATIONS,
      value: confirmations };

  });
}

function parseLogs(logs) {
  return function (dispatch, getState) {
    if (!logs || logs.length === 0) {
      return;
    }var _getState4 =

    getState(),api = _getState4.api;
    var updates = {};

    var promises = logs.map(function (log) {var
      address = log.address;

      return _wallets3.default.logToUpdate(api, address, log).
      then(function (update) {var _ref;
        var prev = updates[address] || (_ref = {}, _defineProperty(_ref, _updates3.UPDATE_DAILYLIMIT,
        true), _defineProperty(_ref, 'address',
        address), _ref);


        if (update[_updates3.UPDATE_CONFIRMATIONS]) {
          var operations = (prev[_updates3.UPDATE_CONFIRMATIONS] || []).concat(update[_updates3.UPDATE_CONFIRMATIONS]);

          update[_updates3.UPDATE_CONFIRMATIONS] = (0, _lodash.uniq)(operations);
        }

        updates[address] = _extends({},
        prev,
        update);

      });
    });

    return Promise.all(promises).
    then(function () {
      fetchWalletsInfo(updates)(dispatch, getState);
    });
  };
}

function setOperationPendingState(address, operation, isPending) {
  return {
    type: 'setOperationPendingState',
    address: address, operation: operation, isPending: isPending };

}

function updateWalletsDetails(wallets) {
  return {
    type: 'updateWalletsDetails',
    wallets: wallets };

}

function setWalletContract(contract) {
  return {
    type: 'setWalletContract',
    contract: contract };

}

function updateWallets(data) {
  return _extends({
    type: 'updateWallets' },
  data);

}