{"version":3,"sources":["jsdelivr-header.js","/npm/robinhood@1.8.0/src/robinhood.js"],"names":[],"mappings":"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","file":"/npm/robinhood@1.8.0/src/robinhood.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/robinhood@1.8.0/src/robinhood.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n * Robinhood API NodeJS Wrapper\n * @author Alejandro U. Alvarez\n * @license AGPLv3 - See LICENSE file for more details\n * @version 1.1.2\n */\n\n'use strict';\n\n// Dependencies\nvar request = require('request');\nvar Promise = require('promise');\nvar _ = require('lodash');\nvar queryString = require('query-string');\nvar { v4: uuidv4 } = require('uuid');\n\nfunction RobinhoodWebApi(opts, callback) {\n  /* +--------------------------------+ *\n   * |      Internal variables        | *\n   * +--------------------------------+ */\n  var _apiUrl = 'https://api.robinhood.com/';\n\n  var _currencyPairsUrl = 'https://nummus.robinhood.com/currency_pairs/';\n\n  var _options = opts || {},\n    // Private API Endpoints\n    _endpoints = {\n      login: 'oauth2/token/',\n      logout: 'oauth2/revoke_token/',\n      investment_profile: 'user/investment_profile/',\n      accounts: 'accounts/',\n      ach_iav_auth: 'ach/iav/auth/',\n      ach_relationships: 'ach/relationships/',\n      ach_transfers: 'ach/transfers/',\n      ach_deposit_schedules: 'ach/deposit_schedules/',\n      applications: 'applications/',\n      dividends: 'dividends/',\n      edocuments: 'documents/',\n      earnings: 'marketdata/earnings/',\n      instruments: 'instruments/',\n      margin_upgrade: 'margin/upgrades/',\n      markets: 'markets/',\n      notifications: 'notifications/',\n      notifications_devices: 'notifications/devices/',\n      orders: 'orders/',\n      cancel_order: 'orders/', //API expects https://api.robinhood.com/orders/{{orderId}}/cancel/\n      password_reset: 'password_reset/request/',\n      quotes: 'quotes/',\n      document_requests: 'upload/document_requests/',\n      user: 'user/',\n\n      user_additional_info: 'user/additional_info/',\n      user_basic_info: 'user/basic_info/',\n      user_employment: 'user/employment/',\n      user_investment_profile: 'user/investment_profile/',\n\n      options_chains: 'options/chains/',\n      options_positions: 'options/aggregate_positions/',\n      options_orders: 'options/orders/',\n      options_instruments: 'options/instruments/',\n      options_marketdata: 'marketdata/options/',\n\n      watchlists: 'watchlists/',\n      positions: 'positions/',\n      fundamentals: 'fundamentals/',\n      sp500_up: 'midlands/movers/sp500/?direction=up',\n      sp500_down: 'midlands/movers/sp500/?direction=down',\n      news: 'midlands/news/',\n      tag: 'midlands/tags/tag/',\n\n      crypto: 'marketdata/forex/quotes/'\n    },\n    _clientId = 'c82SH0WZOsabOXGP2sxqcj34FxkvfnWRZBKlBjFS',\n    _deviceToken = 'ea9fa5c6-01e0-46c9-8430-5b422c99bd16',\n    _isInit = false,\n    _request = request.defaults(),\n    _private = {\n      session: {},\n      account: null,\n      username: null,\n      password: null,\n      headers: null,\n      auth_token: null,\n      refresh_token: null,\n      device_token: null\n    },\n    api = {};\n\n  function _init() {\n    _private.username = _.has(_options, 'username') ? _options.username : null;\n    _private.password = _.has(_options, 'password') ? _options.password : null;\n    _private.device_token = _.has(_options, 'device_token') ? _options.device_token : uuidv4();\n    _private.auth_token = _.has(_options, 'token') ? _options.token : null;\n    _private.headers = {\n      Host: 'api.robinhood.com',\n      Accept: '*/*',\n      'Accept-Encoding': 'gzip, deflate',\n      Referer: 'https://robinhood.com/',\n      Origin: 'https://robinhood.com'\n    };\n    _setHeaders();\n    if (!_private.auth_token) {\n      _login(function (err, data) {\n        _isInit = true;\n\n        if (callback) {\n          if(err) {\n            return callback(err);\n          } else {\n            return callback(null, data);\n          }\n        }\n      });\n    } else {\n      _build_auth_header(_private.auth_token);\n      _setHeaders();\n      _set_account()\n        .then(function () {\n          callback.call();\n        })\n        .catch(function (err) {\n          callback(err);\n        });\n    }\n  }\n\n  function _setHeaders() {\n    _request = request.defaults({\n      headers: _private.headers,\n      json: true,\n      gzip: true\n    });\n  }\n\n  function _login(callback) {\n    var form = {\n      grant_type: 'password',\n      scope: 'internal',\n      client_id: _clientId,\n      expires_in: 86400,\n      password: _private.password,\n      username: _private.username,\n      device_token: _private.device_token\n    };\n    if(_private.mfa_code) {\n      form.mfa_code = _private.mfa_code;\n    }\n    _request.post(\n      {\n        form,\n        uri: _apiUrl + _endpoints.login,\n      },\n      function (err, httpResponse, body) {\n        if (err) {\n          return callback(err);\n        }\n\n        if (!body.access_token && !body.mfa_required) {\n          return callback(new Error('token not found ' + JSON.stringify(httpResponse)));\n        } else if (body.mfa_required) {\n          return callback(null, body);\n        }\n        _private.auth_token = body.access_token;\n        _private.refresh_token = body.refresh_token;\n        _build_auth_header(_private.auth_token);\n\n        _setHeaders();\n\n        // Set account\n        _set_account()\n          .then(function () {\n            callback.call();\n          })\n          .catch(function (err) {\n            callback(err);\n          });\n      }\n    );\n  }\n\n  api.set_mfa_code = function(mfa_code, callback) {\n    _private.mfa_code = mfa_code;\n    _login(callback);\n  }\n\n  function _set_account() {\n    return new Promise(function (resolve, reject) {\n      api.accounts(function (err, httpResponse, body) {\n        if (err) {\n          reject(err);\n        }\n        // Being defensive when user credentials are valid but RH has not approved an account yet\n        if (\n          body.results &&\n          body.results instanceof Array &&\n          body.results.length > 0\n        ) {\n          _private.account = body.results[0].url;\n        }\n        resolve();\n      });\n    });\n  }\n\n  function _build_auth_header(token) {\n    _private.headers.Authorization = 'Bearer ' + token;\n  }\n\n  function options_from_chain({ next, results }) {\n    return new Promise((resolve, reject) => {\n      if (!next) return resolve(results);\n      _request.get(\n        {\n          url: next\n        },\n        (err, response, body) =>\n          resolve(\n            options_from_chain({\n              next: body.next,\n              results: results.concat(body.results)\n            })\n          )\n      );\n    });\n  }\n\n  function filter_bad_options(options) {\n    return options.filter(option => option.tradability == 'tradable');\n  }\n\n  function stitch_options_with_details([details, options]) {\n    let paired = details.map(detail => {\n      let match = options.find(option => option.url == detail.instrument);\n      if (match) {\n        Object.keys(match).forEach(key => (detail[key] = match[key]));\n      }\n      return detail;\n    });\n    // Remove nulls\n    return paired.filter(item => item);\n  }\n\n  function get_options_details(options) {\n    let grouped_options = group_options_by_max_per_request(options);\n    return Promise.all(\n      grouped_options.map(group => {\n        let option_urls = group.map(option => encodeURIComponent(option.url));\n        return new Promise((resolve, reject) => {\n          let request = _request.get(\n            {\n              uri:\n                _apiUrl +\n                _endpoints.options_marketdata +\n                '?instruments=' +\n                option_urls.join('%2C')\n            },\n            (err, response, { results }) => {\n              resolve(results);\n            }\n          );\n        });\n      })\n    ).then(options_details => {\n      return [options_details.flat(), grouped_options.flat()];\n    });\n  }\n\n  const max_options_details_per_request = 17;\n  function group_options_by_max_per_request(options) {\n    let filtered = filter_bad_options(options);\n    let groups = [];\n    for (\n      let i = 0;\n      i < filtered.length - 1;\n      i += max_options_details_per_request\n    ) {\n      groups.push(filtered.slice(i, i + max_options_details_per_request));\n    }\n    return groups;\n  }\n\n  /* +--------------------------------+ *\n   * |      Define API methods        | *\n   * +--------------------------------+ */\n\n  api.auth_token = function () {\n    return _private.auth_token;\n  };\n\n  // Invoke robinhood logout.  Note: User will need to reintantiate\n  // this package to get a new token!\n  api.expire_token = function (callback) {\n    return _request.post(\n      {\n        uri: _apiUrl + _endpoints.logout,\n        form: {\n          client_id: _clientId,\n          token: _private.refresh_token\n        }\n      },\n      callback\n    );\n  };\n\n  api.investment_profile = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.investment_profile\n      },\n      callback\n    );\n  };\n\n  api.fundamentals = function (ticker, callback) {\n    return _request.get(\n      {\n        uri:\n          _apiUrl +\n          [_endpoints.fundamentals, '/'].join(String(ticker).toUpperCase())\n      },\n      callback\n    );\n  };\n\n  api.instruments = function (symbol, callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.instruments,\n        qs: { query: symbol.toUpperCase() }\n      },\n      callback\n    );\n  };\n\n  api.popularity = function (symbol, callback) {\n    return api.quote_data(symbol, function (error, response, body) {\n      if (error) {\n        return callback(error, response, body);\n      }\n\n      // ex. https://api.robinhood.com/instruments/edf89445-db53-4f97-9de9-a599a293c63f/\n      var symbol_uuid = body.results[0].instrument.split('/')[4];\n\n      return _request.get(\n        {\n          uri: _apiUrl + _endpoints.instruments + symbol_uuid + '/popularity/'\n        },\n        callback\n      );\n    });\n  };\n\n  api.quote_data = function (symbol, callback) {\n    symbol = Array.isArray(symbol) ? (symbol = symbol.join(',')) : symbol;\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.quotes,\n        qs: { symbols: symbol.toUpperCase() }\n      },\n      callback\n    );\n  };\n\n  api.accounts = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.accounts\n      },\n      callback\n    );\n  };\n\n  api.user = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.user\n      },\n      callback\n    );\n  };\n\n  api.dividends = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.dividends\n      },\n      callback\n    );\n  };\n\n  api.earnings = function (options, callback) {\n    return _request.get(\n      {\n        uri:\n          _apiUrl +\n          _endpoints.earnings +\n          (options.instrument\n            ? '?instrument=' + options.instrument\n            : options.symbol\n              ? '?symbol=' + options.symbol\n              : '?range=' + (options.range ? options.range : 1) + 'day')\n      },\n      callback\n    );\n  };\n\n  api.orders = function () {\n    var options = {},\n      callback = new Function(),\n      args = _.values(arguments),\n      id = null;\n    args.forEach(function (arg) {\n      if (typeof arg === 'function') callback = arg;\n      if (typeof arg === 'string') id = arg;\n      if (typeof arg === 'object') options = arg; // Keep in mind, instrument option must be the full instrument url!\n    });\n\n    var hasId = typeof id !== 'undefined' && id !== null;\n    var hasOptions = _.keys(options).length > 0;\n\n    if (hasId && hasOptions) {\n      // remove ambiguitiy from choosing both an id and options\n      console.warn(\n        'Warning : both id and options were defined for robinhood.orders(). Options are mutually exclusive. Defaulting to id only.'\n      );\n      hasOptions = false;\n    }\n\n    if (hasOptions) {\n      options['updated_at[gte]'] = options.updated_at;\n      _.unset(options, 'updated_at');\n    }\n    return _request.get(\n      {\n        uri:\n          _apiUrl +\n          _endpoints.orders +\n          (hasId ? id + '/' : '') +\n          (hasOptions ? '?' + queryString.stringify(options) : '')\n      },\n      callback\n    );\n  };\n\n  api.cancel_order = function (order, callback) {\n    var cancel_url = false;\n    if (typeof order == 'string') {\n      // if string, the string is the id of the order\n      cancel_url = _apiUrl + _endpoints.cancel_order + order + '/cancel/'; // e.g., https://api.robinhood.com/orders/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/cancel/\n    } else if (order.cancel) {\n      // if the order object was passed, we can extract the cancel url from the object\n      cancel_url = order.cancel; // note, if cancel is not posible this will return null\n    }\n    if (cancel_url) {\n      // if we have a non null, non false url, make the request\n      return _request.post(\n        {\n          uri: cancel_url // use the cancel url provided by the order object\n        },\n        callback\n      );\n    } else {\n      return callback(\n        {\n          message:\n            order.state == 'cancelled'\n              ? 'Order already cancelled.'\n              : 'Order cannot be cancelled.',\n          order: order\n        },\n        null,\n        null\n      ); // else the order is alread\n    }\n  };\n\n  var _place_order = function (options, callback) {\n    return _request.post(\n      {\n        uri: _apiUrl + _endpoints.orders,\n        form: {\n          account: _private.account,\n          instrument: options.instrument.url,\n          price: options.bid_price,\n          stop_price: options.stop_price,\n          quantity: options.quantity,\n          side: options.transaction,\n          symbol: options.instrument.symbol.toUpperCase(),\n          time_in_force: options.time || 'gfd',\n          trigger: options.trigger || 'immediate',\n          type: options.type || 'market'\n        }\n      },\n      callback\n    );\n  };\n\n  api.place_buy_order = function (options, callback) {\n    options.transaction = 'buy';\n    return _place_order(options, callback);\n  };\n\n  api.place_sell_order = function (options, callback) {\n    options.transaction = 'sell';\n    return _place_order(options, callback);\n  };\n\n  api.positions = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.positions\n      },\n      callback\n    );\n  };\n\n  api.nonzero_positions = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.positions,\n        qs: { nonzero: true }\n      },\n      callback\n    );\n  };\n\n  api.options_positions = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.options_positions\n      },\n      callback\n    );\n  };\n\n  api.options_orders = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.options_orders\n      },\n      callback\n    );\n  };\n\n  api.options_dates = function (symbol, callback) {\n    api.instruments(symbol, function (err, response, { results }) {\n      if (err) throw err;\n      let [{ tradable_chain_id }] = results;\n      _request.get(\n        {\n          uri:\n            _apiUrl + [_endpoints.options_chains, '/'].join(tradable_chain_id)\n        },\n        function (err, response, { expiration_dates }) {\n          if (err) throw err;\n          callback({ expiration_dates, tradable_chain_id });\n        }\n      );\n    });\n  };\n\n  api.options_available = function (\n    chain_id,\n    expiration_date,\n    type = 'put'\n  ) {\n    return new Promise((resolve, reject) => {\n      let request = _request.get(\n        {\n          uri: _apiUrl + _endpoints.options_instruments,\n          qs: {\n            chain_id,\n            type,\n            expiration_date,\n            state: 'active',\n            tradability: 'tradable'\n          }\n        },\n        (err, response, body) =>\n          options_from_chain(body)\n            .then(get_options_details)\n            .then(stitch_options_with_details)\n            .then(resolve)\n      );\n      console.log();\n    });\n  };\n\n  api.news = function (symbol, callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + [_endpoints.news, '/'].join(symbol)\n      },\n      callback\n    );\n  };\n\n  api.tag = function (tag, callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.tag + tag\n      },\n      callback\n    );\n  };\n\n  api.markets = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.markets\n      },\n      callback\n    );\n  };\n\n  api.sp500_up = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.sp500_up\n      },\n      callback\n    );\n  };\n\n  api.sp500_down = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.sp500_down\n      },\n      callback\n    );\n  };\n\n  api.create_watch_list = function (name, callback) {\n    return _request.post(\n      {\n        uri: _apiUrl + _endpoints.watchlists,\n        form: {\n          name: name\n        }\n      },\n      callback\n    );\n  };\n\n  api.watchlists = function (callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + _endpoints.watchlists\n      },\n      callback\n    );\n  };\n\n  api.splits = function (instrument, callback) {\n    return _request.get(\n      {\n        uri: _apiUrl + [_endpoints.instruments, '/splits/'].join(instrument)\n      },\n      callback\n    );\n  };\n\n  api.historicals = function (symbol, intv, span, callback) {\n    return _request.get(\n      {\n        uri:\n          _apiUrl +\n          [\n            _endpoints.quotes + 'historicals/',\n            '/?interval=' + intv + '&span=' + span\n          ].join(symbol)\n      },\n      callback\n    );\n  };\n\n  api.url = function (url, callback) {\n    return _request.get(\n      {\n        uri: url\n      },\n      callback\n    );\n  };\n\n  api.get_currency_pairs = function(callback) {\n    return request.get(\n      {\n        uri: _currencyPairsUrl,\n      },\n      callback\n    )\n  }\n\n  api.get_crypto = function(symbol, callback) {\n    return api.get_currency_pairs(function (error, response, body) {\n      if(error) {\n        return callback(error, response, body);\n      }\n\n      var assets = JSON.parse(body).results;\n      var asset = assets.find(a => a.asset_currency.code.toLowerCase() === symbol.toLowerCase());\n      if(!asset) {\n        var codes = assets.map(a => a.asset_currency.code);\n        return callback(new Error(\"Symbol not found. Only these codes are allowed: \" + JSON.stringify(codes)));\n      }\n\n      return _request.get(\n        {\n          uri: _apiUrl + _endpoints.crypto + asset.id + '/'\n        },\n        callback\n      );\n    });\n  }\n\n  _init(_options);\n\n  return api;\n}\n\nmodule.exports = RobinhoodWebApi;\n"]}