{"size": 14616, "ext": "js", "max_stars_repo_path": "node_modules/uport-connect/lib/Connect.js", "max_stars_repo_name": "mbvivek/asset-registry", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "node_modules/uport-connect/lib/Connect.js", "max_issues_repo_name": "mbvivek/asset-registry", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "node_modules/uport-connect/lib/Connect.js", "max_forks_repo_name": "mbvivek/asset-registry", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 42.121037464, "max_line_length": 615, "alphanum_fraction": 0.6448412698}
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // Can use http provider from ethjs in the future.


// Remove this after or find a better place for it


var _uport = require('uport');

var _mobileDetect = require('mobile-detect');

var _mobileDetect2 = _interopRequireDefault(_mobileDetect);

var _httpprovider = require('web3/lib/web3/httpprovider');

var _httpprovider2 = _interopRequireDefault(_httpprovider);

var _mnid = require('mnid');

var _uportCore = require('uport-core');

var _pubsubJs = require('pubsub-js');

var _pubsubJs2 = _interopRequireDefault(_pubsubJs);

var _uportDidResolver = require('uport-did-resolver');

var _uportDidResolver2 = _interopRequireDefault(_uportDidResolver);

var _ethrDidResolver = require('ethr-did-resolver');

var _ethrDidResolver2 = _interopRequireDefault(_ethrDidResolver);

var _didJwt = require('did-jwt');

var _uportLite = require('uport-lite');

var _uportLite2 = _interopRequireDefault(_uportLite);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Connect = function () {
  /**
   * Instantiates a new uPort Connect object.
   *
   * @example
   * import { Connect } from 'uport-connect'
   * const uPort = new ConnectCore('Mydapp')
   * @param       {String}            appName                the name of your app
   * @param       {Object}            [opts]                 optional parameters
   * @param       {String}            opts.clientId          uport identifier for your application this will be used in the default credentials object
   * @param       {Object}            [opts.network='rinkeby'] network config object or string name, ie. { id: '0x1', registry: '0xab5c8051b9a1df1aab0149f8b0630848b7ecabf6', rpcUrl: 'https://mainnet.infura.io' } or 'kovan', 'mainnet', 'ropsten', 'rinkeby'.
   * @param       {String}            opts.infuraApiKey      Infura API Key (register here http://infura.io/register.html)
   * @param       {Function}          opts.topicFactory      function which generates topics and deals with requests and response
   * @param       {Function}          opts.uriHandler        default function to consume generated URIs for requests, can be used to display QR codes or other custom UX
   * @param       {Function}          opts.mobileUriHandler  default function to consume generated URIs for requests on mobile
   * @param       {Function}          opts.closeUriHandler   default function called after a request receives a response, can be to close QR codes or other custom UX
   * @param       {String}            opts.accountType       Ethereum account type: "general", "segregated", "keypair", "devicekey" or "none"
   * @param       {Object}            opts.ethrConfig        Configuration object for ethr did resolver. See [ethr-did-resolver](https://github.com/uport-project/ethr-did-resolver)
   * @return      {Connect}                                  self
   */
  function Connect(appName) {
    var _this = this;

    var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

    _classCallCheck(this, Connect);

    // Config
    this.appName = appName || 'uport-connect-app';
    this.network = _uportCore.network.config.network(opts.network);
    this.infuraApiKey = opts.infuraApiKey || this.appName.replace(/\W+/g, '-'); //TODO Not used right now, still needed?
    this.provider = opts.provider || new _httpprovider2.default(this.network.rpcUrl);
    this.accountType = opts.accountType;
    this.isOnMobile = opts.isMobile === undefined ? isMobile() : opts.isMobile;
    // State
    this.address = null;
    this.firstReq = true;
    // Transports
    this.transport = opts.transport || connectTransport;
    this.mobileTransport = opts.mobileTransport || _uportCore.transport.url.send();
    this.PubSub = _pubsubJs2.default;
    this.onloadResponse = _uportCore.transport.url.getResponse();
    _uportCore.transport.url.listenResponse(function (err, res) {
      if (res) _this.PubSub.publish(res.id, { res: res.res, data: res.data }); // TODO pass errors
    });
    // TODO need a nicer way configure resolvers, lines below should be temporary
    // TODO would be nice to have some uncoupled funct for parsing/verifying in uport-core-js rather than require config a credential object, nice to require aud either here
    this.credentials = new _uport.Credentials();
    (0, _uportDidResolver2.default)((0, _uportLite2.default)({ networks: _uportCore.network.config.networkToNetworkSet(this.network) }));
    (0, _ethrDidResolver2.default)(opts.ethrConfig || {});
    var verifyResponse = function verifyResponse(res) {
      var decodedToken = (0, _didJwt.decodeJWT)(res).payload;
      return (0, _didJwt.verifyJWT)(res, { audience: decodedToken.aud }).then(_this.credentials.processDisclosurePayload);
    };
    this.verifyResponse = opts.verifyResponse || verifyResponse;
  }

  /**
   *  Instantiates and returns a web3 styple provider wrapped with uPort functionality.
   *  For more details see uportSubprovider. uPort overrides eth_coinbase and eth_accounts
   *  to start a get address flow or to return an already received address. It also
   *  overrides eth_sendTransaction to start the send transaction flow to pass the
   *  transaction to the uPort app.
   *
   *  @return          {UportSubprovider}    A web3 style provider wrapped with uPort functionality
   */


  _createClass(Connect, [{
    key: 'getProvider',
    value: function getProvider() {
      var _this2 = this;

      // TODO remove defaults, fix import
      var subProvider = new _uportCore.provider.default({
        requestAddress: function requestAddress() {
          _this2.requestAddress('addressReqProvider');
          // TODO can this be parsed to readable name (ie nad) address or network address or mnid
          return _this2.onResponse('addressReqProvider').then(function (res) {
            return (0, _mnid.decode)(res.res.payload.nad).address;
          });
        },
        sendTransaction: function sendTransaction(txObj) {
          txObj.bytecode = txObj.data;
          _this2.sendTransaction(txObj, 'txReqProvider');
          return _this2.onResponse('txReqProvider');
        },
        provider: this.provider,
        networkId: this.network.id
      });
      if (this.address) subProvider.setAccount(this.address);
      return subProvider;
    }

    // TODO where to return MNID and where to return address, should this be named differently, will return entire response obj now, not just address
    /**
     *  Creates a request for only the address/id of the uPort identity.
     *
     *  @param    {String}    [id='addressReq']    string to identify request, later used to get response
     */

  }, {
    key: 'requestAddress',
    value: function requestAddress() {
      var id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'addressReq';

      this.request(simpleRequest(), id);
    }

    // TODO offer listener and single resolve? or other both for this funct, by allowing optional cb instead
    /**
     *  Get response by id of earlier request, returns promise which resolves when first reponse with given id is avaialable. Listen instead, if looking for multiple responses of same id.
     *
     *  @param    {String}    id             id of request you are looking for a response for
     *  @return   {Promise<Object, Error>}   promise resolves once valid response for given id is avaiable, otherwise rejects with error
     */

  }, {
    key: 'onResponse',
    value: function onResponse(id) {
      var _this3 = this;

      var parseResponse = function parseResponse(resObj) {
        if (isJWT(resObj.res)) {
          return _this3.verifyResponse(resObj.res).then(function (res) {
            return { id: id, res: res, data: resObj.data };
          });
        } else {
          return Promise.resolve(Object.assign({ id: id }, resObj));
        }
      };

      if (this.onloadResponse && this.onloadResponse.id === id) {
        var onloadResponse = this.onloadResponse;
        this.onloadResponse = null;
        return parseResponse(onloadResponse);
      }

      return new Promise(function (resolve, reject) {
        _this3.PubSub.subscribe(id, function (msg, res) {
          _this3.PubSub.unsubscribe(id);
          parseResponse(res).then(function (res) {
            resolve(res);
          }, function (err) {
            reject(err);
          });
        });
      });
    }

    // NOTE interface, some are cancellable?, maybe just allow devs to pass in cancel func instead?
    //  TODO Name? request, transport? send?
    /**
     *  Send a request URI string to a uport client
     *
     *  @param    {String}     uri            a request URI to send to a uport client
     *  @param    {String}     id             id of request you are looking for a response for
     *  @param    {Object}     [opts]         optional parameters for a callback
     *  @param    {String}     opts.callback  callback TODO ref specs here for cb, data, type and diff between signed and unsigned req
     *  @param    {String}     opts.data
     *  @param    {String}     opts.type
     *  @return   {Promise<Object, Error>}   promise resolves once valid response for given id is avaiable, otherwise rejects with error
     */

  }, {
    key: 'request',
    value: function request(uri, id) {
      var _this4 = this;

      var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
          callback = _ref.callback,
          data = _ref.data,
          type = _ref.type;

      this.isOnMobile ? this.mobileTransport(uri, { id: id, data: data, callback: callback, type: type }) : this.transport(uri, { data: data }).then(function (res) {
        _this4.PubSub.publish(id, res);
      });
    }

    /**
     *  Builds and returns a contract object which can be used to interact with
     *  a given contract. Similar to web3.eth.contract but with promises. Once specifying .at(address)
     *  you can call the contract functions with this object. It will create a request,
     *  call the uirHandler with the URI, and return a promise which resolves with
     *  a transtaction ID.
     *
     *  @param    {Object}       abi                                   contract ABI
     *  @return   {Object}                                             contract object
     */

  }, {
    key: 'contract',
    value: function contract(abi) {
      var _this5 = this;

      var txObjectHandler = function txObjectHandler(methodTxObject, id) {
        return _this5.sendTransaction(methodTxObject, id);
      };
      return (0, _uport.ContractFactory)(txObjectHandler)(abi);
    }

    /**
     *  Given a transaction object, similarly defined as the web3 transaction object,
     *  it creates a URI which is passes to the uirHandler. It will create request
     *  and returns a promise which resolves with the transaction id.
     *
     *  @example
     *  const txobject = {
     *    to: '0xc3245e75d3ecd1e81a9bfb6558b6dafe71e9f347',
     *    value: '0.1',
     *    function: "setStatus(string 'hello', bytes32 '0xc3245e75d3ecd1e81a9bfb6558b6dafe71e9f347')",
     *    appName: 'MyDapp'
     *  }
     *  connect.sendTransaction(txobject).then(txID => {
     *    ...
     *  })
     *
     *  @param    {Object}    txObj
     *  @param    {String}    [id='addressReq']    string to identify request, later used to get response
     */

  }, {
    key: 'sendTransaction',
    value: function sendTransaction(txObj) {
      var _this6 = this;

      var id = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'txReq';

      var txRequest = function txRequest(txObj) {
        return _uportCore.message.util.paramsToQueryString('https://id.uport.me/' + ((0, _mnid.isMNID)(txObj.to) ? txObj.to : (0, _mnid.encode)({ network: _this6.network.id, address: txObj.to })), txObj);
      };
      this.request(txRequest(txObj), id);
    }

    //  serialize() {
    //    const connectJSONState = {
    //      address = connectObj.address
    //      mnid = connectObj.mnid
    //      did = connectObj.did
    //      doc = connectObj.doc
    //      firstReq = connectObj.firstReq
    //      keypair = connectObj.keypair
    //    }
    //    return JSON.stringify(connectJSONState)
    //  }
    //
    //  deserialize(str) {
    //    const connectJSONState = JSON.parse(str)
    //    this.address = connectObj.address
    //    this.mnid = connectObj.mnid
    //    this.did = connectObj.did
    //    this.doc = connectObj.doc
    //    this.firstReq = connectObj.firstReq
    //    this.keypair = connectObj.keypair
    //  }

  }]);

  return Connect;
}();

var simpleRequest = function simpleRequest() {
  return 'https://id.uport.me/me';
};
var isJWT = function isJWT(jwt) {
  return (/^([a-zA-Z0-9_=]+)\.([a-zA-Z0-9_=]+)\.([a-zA-Z0-9_\-\+\/=]*)/.test(jwt)
  );
};

var connectTransport = function connectTransport(uri, _ref2) {
  var data = _ref2.data;

  // This will change if all request URIs are JWTs, then check for chasqui callback, or allow some other config.
  if (/accessToken/.test(uri)) {
    _uportCore.transport.qr.send()(uri);
    // return closeQR ??
    return Promise.resolve({ data: data });
  } else {
    return _uportCore.transport.qr.chasquiSend()(uri).then(function (res) {
      return { res: res, data: data };
    });
  }
};

/**
 *  Detects if this library is called on a mobile device or tablet.
 *
 *  @param    {Object}     params    A object of params known to uPort
 *  @return   {Boolean}              Returns true if on mobile or tablet, false otherwise.
 *  @private
 */
function isMobile() {
  if (typeof navigator !== 'undefined') {
    return !!new _mobileDetect2.default(navigator.userAgent).mobile();
  } else return false;
}

// export { Connect, serialize, deserialize }
exports.default = Connect;