'use strict';Object.defineProperty(exports, "__esModule", { value: true });exports.ETH_TOKEN = undefined;var _slicedToArray = function () {function sliceIterator(arr, i) {var _arr = [];var _n = true;var _d = false;var _e = undefined;try {for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {_arr.push(_s.value);if (i && _arr.length === i) break;}} catch (err) {_d = true;_e = err;} finally {try {if (!_n && _i["return"]) _i["return"]();} finally {if (_d) throw _e;}}return _arr;}return function (arr, i) {if (Array.isArray(arr)) {return arr;} else if (Symbol.iterator in Object(arr)) {return sliceIterator(arr, i);} else {throw new TypeError("Invalid attempt to destructure non-iterable instance");}};}(); // 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/>.
exports.






















fetchTokenIds = fetchTokenIds;exports.









fetchTokensBasics = fetchTokensBasics;exports.

























fetchTokensInfo = fetchTokensInfo;exports.









































fetchTokensImages = fetchTokensImages;exports.
































fetchAccountsBalances = fetchAccountsBalances;var _lodash = require('lodash');var _bignumber = require('bignumber.js');var _bignumber2 = _interopRequireDefault(_bignumber);var _sha = require('@parity/api/lib/util/sha3');var _ui = require('@parity/ui');var _ethereumBlack64x = require('../../../assets/images/contracts/ethereum-black-64x64.png');var _ethereumBlack64x2 = _interopRequireDefault(_ethereumBlack64x);var _bytecodes = require('./bytecodes');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;}var ETH_TOKEN = exports.ETH_TOKEN = { address: '', format: new _bignumber2.default(10).pow(18), id: getTokenId('eth_native_token'), image: _ethereumBlack64x2.default, name: 'Ethereum', native: true, tag: 'ETH' };function fetchTokenIds(tokenregInstance) {return tokenregInstance.tokenCount.call().then(function (numTokens) {var tokenIndexes = (0, _lodash.range)(numTokens.toNumber());return tokenIndexes;});}function fetchTokensBasics(api, tokenReg) {var start = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;var limit = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 100;var tokenAddressesCallData = encode(api, ['address', 'uint', 'uint'], [tokenReg.address, start, limit]);return api.eth.call({ data: _bytecodes.tokenAddresses + tokenAddressesCallData }).then(function (result) {var tokenAddresses = decodeArray(api, 'address[]', result);return tokenAddresses.map(function (tokenAddress, index) {var tokenIndex = start + index;return { address: tokenAddress, id: getTokenId(tokenAddress, tokenIndex), index: tokenIndex, fetched: false };});});}function fetchTokensInfo(api, tokenReg, tokenIndexes) {var requests = tokenIndexes.map(function (tokenIndex) {var tokenCalldata = tokenReg.getCallData(tokenReg.instance.token, {}, [tokenIndex]);return { to: tokenReg.address, data: tokenCalldata };});var calls = requests.map(function (req) {return api.eth.call(req);});var imagesPromise = fetchTokensImages(api, tokenReg, tokenIndexes);return Promise.all(calls).then(function (results) {return imagesPromise.then(function (images) {return [results, images];});}).then(function (_ref) {var _ref2 = _slicedToArray(_ref, 2),results = _ref2[0],images = _ref2[1];return results.map(function (rawTokenData, index) {var tokenIndex = tokenIndexes[index];var tokenData = tokenReg.instance.token.decodeOutput(rawTokenData).map(function (t) {return t.value;});var _tokenData = _slicedToArray(tokenData, 4),address = _tokenData[0],tag = _tokenData[1],format = _tokenData[2],name = _tokenData[3];var image = images[index];var token = { address: address, id: getTokenId(address, tokenIndex), index: tokenIndex, format: format.toString(), image: image, name: name, tag: tag, fetched: true };return token;});});}function fetchTokensImages(api, tokenReg, tokenIndexes) {var requests = tokenIndexes.map(function (tokenIndex) {var metaCalldata = tokenReg.getCallData(tokenReg.instance.meta, {}, [tokenIndex, 'IMG']);return { to: tokenReg.address, data: metaCalldata };});var calls = requests.map(function (req) {return api.eth.call(req);});return Promise.all(calls).then(function (results) {return results.map(function (rawImage) {var image = tokenReg.instance.meta.decodeOutput(rawImage)[0].value;return _ui.IconCache.hashToImage(image);});});} /**
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            * `updates` should be in the shape:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            *   {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            *     [ who ]: [ tokenId ]  // Array of tokens to updates
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            *   }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            *
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            * Returns a Promise resolved with the balances in the shape:
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            *   {
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            *     [ who ]: { [ tokenId ]: BigNumber } // The balances of `who`
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            *   }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            */function fetchAccountsBalances(api, tokens, updates) {var accountAddresses = Object.keys(updates); // Updates for the ETH balances
  var ethUpdates = accountAddresses.filter(function (accountAddress) {return updates[accountAddress].find(function (tokenId) {return tokenId === ETH_TOKEN.id;});}).reduce(function (nextUpdates, accountAddress) {nextUpdates[accountAddress] = [ETH_TOKEN.id];return nextUpdates;}, {});

  // Updates for Tokens balances
  var tokenUpdates = Object.keys(updates).
  reduce(function (nextUpdates, accountAddress) {
    var tokenIds = updates[accountAddress].filter(function (tokenId) {return tokenId !== ETH_TOKEN.id;});

    if (tokenIds.length > 0) {
      nextUpdates[accountAddress] = tokenIds;
    }

    return nextUpdates;
  }, {});

  var ethBalances = {};
  var tokensBalances = {};

  var ethPromise = fetchEthBalances(api, Object.keys(ethUpdates)).
  then(function (_ethBalances) {
    ethBalances = _ethBalances;
  });

  var tokenPromise = Object.keys(tokenUpdates).
  reduce(function (tokenPromise, accountAddress) {
    var tokenIds = tokenUpdates[accountAddress];
    var updateTokens = tokens.
    filter(function (t) {return tokenIds.includes(t.id);});

    return tokenPromise.
    then(function () {return fetchTokensBalances(api, updateTokens, [accountAddress]);}).
    then(function (balances) {
      tokensBalances[accountAddress] = balances[accountAddress];
    });
  }, Promise.resolve());

  return Promise.all([ethPromise, tokenPromise]).
  then(function () {
    var balances = Object.assign({}, tokensBalances);

    Object.keys(ethBalances).forEach(function (accountAddress) {
      if (!balances[accountAddress]) {
        balances[accountAddress] = {};
      }

      balances[accountAddress] = Object.assign(
      {},
      balances[accountAddress],
      ethBalances[accountAddress]);

    });

    return balances;
  });
}

function fetchEthBalances(api, accountAddresses) {
  var promises = accountAddresses.
  map(function (accountAddress) {return api.eth.getBalance(accountAddress);});

  return Promise.all(promises).
  then(function (balancesArray) {
    return balancesArray.reduce(function (balances, balance, index) {
      balances[accountAddresses[index]] = _defineProperty({},
      ETH_TOKEN.id, balance);


      return balances;
    }, {});
  });
}

function fetchTokensBalances(api, tokens, accountAddresses) {
  var tokenAddresses = tokens.map(function (t) {return t.address;});
  var tokensBalancesCallData = encode(
  api,
  ['address[]', 'address[]'],
  [accountAddresses, tokenAddresses]);


  return api.eth.
  call({ data: _bytecodes.tokensBalances + tokensBalancesCallData }).
  then(function (result) {
    var rawBalances = decodeArray(api, 'uint[]', result);
    var balances = {};

    accountAddresses.forEach(function (accountAddress, accountIndex) {
      var balance = {};
      var preIndex = accountIndex * tokenAddresses.length;

      tokenAddresses.forEach(function (tokenAddress, tokenIndex) {
        var index = preIndex + tokenIndex;
        var token = tokens[tokenIndex];

        balance[token.id] = rawBalances[index];
      });

      balances[accountAddress] = balance;
    });

    return balances;
  });
}

function getTokenId() {for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {args[_key] = arguments[_key];}
  return (0, _sha.sha3)(args.join('')).slice(0, 10);
}

function encode(api, types, values) {
  return api.util.abiEncode(
  null,
  types,
  values).
  replace('0x', '');
}

function decodeArray(api, type, data) {
  return api.util.
  abiDecode(
  [type],
  [
  '0x',
  32 .toString(16).padStart(64, 0),
  data.replace('0x', '')].
  join(''))[
  0].
  map(function (t) {return t.value;});
}