class CoinTools::CoinMarketCap

Constants

BASE_URL
FIAT_CURRENCIES

Public Instance Methods

get_all_prices(convert_to: nil, &block) click to toggle source
# File lib/cointools/coinmarketcap.rb, line 170
def get_all_prices(convert_to: nil, &block)
  url = URI("#{BASE_URL}/v2/ticker/?structure=array&sort=id&limit=100")

  if convert_to
    validate_fiat_currency(convert_to)
    url.query += "&convert=#{convert_to.upcase}"
  else
    url.query += "&convert=BTC"
  end

  coins = []

  loop do
    new_batch = fetch_full_ticker_page(url, convert_to, coins.length + 1, &block)

    if new_batch.empty?
      break
    else
      coins.concat(new_batch)
    end
  end

  coins.sort_by(&:rank)
end
get_price(coin_name, convert_to: nil) click to toggle source
# File lib/cointools/coinmarketcap.rb, line 119
def get_price(coin_name, convert_to: nil)
  raise InvalidSymbolError if coin_name.to_s.empty?

  validate_fiat_currency(convert_to) if convert_to

  listing = id_map[coin_name.to_s]
  raise InvalidSymbolError if listing.nil?

  get_price_for_listing(listing, convert_to: convert_to)
end
get_price_by_symbol(coin_symbol, convert_to: nil) click to toggle source
# File lib/cointools/coinmarketcap.rb, line 130
def get_price_by_symbol(coin_symbol, convert_to: nil)
  raise InvalidSymbolError if coin_symbol.to_s.empty?

  validate_fiat_currency(convert_to) if convert_to

  listing = symbol_map[coin_symbol.to_s]
  raise InvalidSymbolError if listing.nil?

  get_price_for_listing(listing, convert_to: convert_to)
end
get_price_for_listing(listing, convert_to: nil) click to toggle source
# File lib/cointools/coinmarketcap.rb, line 141
def get_price_for_listing(listing, convert_to: nil)
  url = URI("#{BASE_URL}/v2/ticker/#{listing.numeric_id}/")

  if convert_to
    url.query = "convert=#{convert_to.upcase}"
  else
    url.query = "convert=BTC"
  end

  response = Request.get(url)

  case response
  when Net::HTTPSuccess
    record = parse_response(response, Hash)

    begin
      return CoinData.new(record, convert_to)
    rescue ArgumentError => e
      raise JSONError.new(response, e.message)
    end
  when Net::HTTPNotFound
    raise UnknownCoinError.new(response)
  when Net::HTTPClientError
    raise BadRequestError.new(response)
  else
    raise ServiceUnavailableError.new(response)
  end
end
id_map() click to toggle source
# File lib/cointools/coinmarketcap.rb, line 82
def id_map
  load_listings if @id_map.nil?
  @id_map
end
load_listings() click to toggle source
# File lib/cointools/coinmarketcap.rb, line 87
def load_listings
  url = URI("#{BASE_URL}/v2/listings/")

  response = Request.get(url)

  case response
  when Net::HTTPSuccess
    data = parse_response(response, Array)

    @id_map = {}
    @symbol_map = {}

    begin
      data.each do |record|
        listing = Listing.new(record)

        @id_map[listing.text_id] = listing
        @symbol_map[listing.symbol] = listing
      end
    rescue ArgumentError => e
      # TODO: JSONError vs. NoDataError? + error class docs
      raise JSONError.new(response, e.message)
    end

    data.length
  when Net::HTTPClientError
    raise BadRequestError.new(response)
  else
    raise ServiceUnavailableError.new(response)
  end
end
symbol_map() click to toggle source
# File lib/cointools/coinmarketcap.rb, line 77
def symbol_map
  load_listings if @symbol_map.nil?
  @symbol_map
end

Private Instance Methods

fetch_full_ticker_page(base_url, convert_to, start) { |new_batch| ... } click to toggle source
# File lib/cointools/coinmarketcap.rb, line 198
def fetch_full_ticker_page(base_url, convert_to, start)
  url = base_url.clone
  url.query += "&start=#{start}"
  response = Request.get(url)

  case response
  when Net::HTTPSuccess
    data = parse_response(response, Array)

    begin
      new_batch = data.map { |record| CoinData.new(record, convert_to) }
    rescue ArgumentError => e
      raise JSONError.new(response, e.message)
    end

    yield new_batch if block_given? && !new_batch.empty?

    new_batch
  when Net::HTTPNotFound
    []
  when Net::HTTPClientError
    raise BadRequestError.new(response)
  else
    raise ServiceUnavailableError.new(response)
  end
end
parse_response(response, expected_data_type) click to toggle source
# File lib/cointools/coinmarketcap.rb, line 229
def parse_response(response, expected_data_type)
  json = Utils.parse_json(response.body)

  raise JSONError.new(response) unless json.is_a?(Hash) && json['metadata']
  raise BadRequestError.new(response, json['metadata']['error']) if json['metadata']['error']
  raise JSONError.new(response) unless json['data'].is_a?(expected_data_type)

  json['data']
end
validate_fiat_currency(fiat_currency) click to toggle source
# File lib/cointools/coinmarketcap.rb, line 225
def validate_fiat_currency(fiat_currency)
  raise InvalidFiatCurrencyError unless FIAT_CURRENCIES.include?(fiat_currency.upcase)
end