class Cobinhood::Client::REST

Public: Client with methods mirroring the Cobinhood REST APIs

Constants

API_ENDPOINTS
BASE_URL

Public: String base url for REST client to use

Public Class Methods

new(api_key: default_api_key, adapter: Faraday.default_adapter) click to toggle source

Public: Initialize a REST Client

:api_key - The String API key to authenticate (Default = '').

:adapter - The Faraday::Adapter to be used for the client

(Default = Faraday.default_adapter).
# File lib/cobinhood/client/rest.rb, line 40
def initialize api_key: default_api_key, adapter: Faraday.default_adapter

  @library = {
      system: public_client(adapter),
      market: public_client(adapter),
       chart: public_client(adapter),
     trading: auth_client(api_key, adapter),
      wallet: auth_client(api_key, adapter),
  }
end

Public Instance Methods

assert_param_is_one_of(options, param, valid_values) click to toggle source
# File lib/cobinhood/client/rest.rb, line 56
def assert_param_is_one_of options, param, valid_values
  return if valid_values.include? options[param].to_s
  raise Cobinhood::InvalidParamError.new("#{param} must be one of #{valid_values.inspect}")
end
assert_required_param(options, param, valid_values=nil) click to toggle source
# File lib/cobinhood/client/rest.rb, line 51
def assert_required_param options, param, valid_values=nil
  raise Cobinhood::MissingParamError.new("#{param} is required") unless options.has_key?(param)
  assert_param_is_one_of options, param, valid_values if valid_values
end
default_api_key() click to toggle source
# File lib/cobinhood/client/rest.rb, line 30
def default_api_key
  ENV["COBINHOOD_API_KEY"].to_s
end

Private Instance Methods

adapt_price_param(params) click to toggle source
# File lib/cobinhood/client/rest.rb, line 143
def adapt_price_param params
  return unless params.has_key? :price
  params[:price] = '%0.8f' % params[:price].to_f
end
adapt_size_param(params) click to toggle source
# File lib/cobinhood/client/rest.rb, line 148
def adapt_size_param params
  return unless params.has_key? :size
  params[:size] = params[:size].to_s
end
adapt_timestamp_param(key, params) click to toggle source

TODO: This needs more testing! I'm not sure about precision of the epoche nor if adjustments are needed to account for timezone differences. Currently only used for params of Cobinhood::Client::REST.candles

# File lib/cobinhood/client/rest.rb, line 137
def adapt_timestamp_param key, params
  return unless params.has_key? key
  return if params[key].is_a?(Integer)
  params[key] = (params[key].to_time.to_f * 1000).ceil
end
auth_client(api_key, adapter) click to toggle source
# File lib/cobinhood/client/rest.rb, line 72
def auth_client api_key, adapter
  Faraday.new(url: BASE_URL) do |conn|
    conn.request :json
    conn.response :json, content_type: /\bjson\z/
    conn.use NonceRequestMiddleware
    conn.use AuthRequestMiddleware, api_key
    conn.adapter adapter
  end
end
public_client(adapter) click to toggle source
# File lib/cobinhood/client/rest.rb, line 63
def public_client adapter
  Faraday.new(url: BASE_URL) do |conn|
    conn.request :json
    conn.response :json, content_type: /\bjson\z/
    conn.use NonceRequestMiddleware
    conn.adapter adapter
  end
end
request(api, method, endpoint, options = {}) click to toggle source

Internal: Create a request that hits one of the REST APIs

api - The Symbol that represents which API to use.

method - The Symbol that represents which HTTP method to use.

endpoint - The String that represents which API endpoint to request

from.

options - The Hash which hosts various REST query params. (Default = {})

Each endpoint will have their own required and optional
params.
# File lib/cobinhood/client/rest.rb, line 94
def request api, method, endpoint, options = {}
  response = @library[api].public_send(method) do |req|

    # substitute path parameters and remove from options hash
    endpoint_url = API_ENDPOINTS[api][endpoint].dup
    options.each do |option, value|
      path_param = /":#{option}"/
      if endpoint_url match? path_param
        options.delete(option)
        endpoint_url.gsub!(path_param, value)
      end
    end

    # Cobinhood wants certain parameters a certain way.
    adapt_price_param options
    adapt_size_param options
    [:start_time, :end_time].each{|key| adapt_timestamp_param key, options}

    req.url endpoint_url

    # parameters go into request body, not headers on POSTs
    if method == :post
      req.body = options.to_json
    else
      req.params.merge!(options)
    end
  end
  success_or_error response
end
success_or_error(response) click to toggle source
# File lib/cobinhood/client/rest.rb, line 126
def success_or_error response
  return response.body["result"] if response.body.is_a?(Hash) && response.body["success"]
  json = JSON.parse(response.body)
  raise Cobinhood::ClientError.new("Cobinhood Error: " + json["error"]["error_code"] + " for REQUEST ID: #{json["request_id"]}")
rescue
  raise Cobinhood::ClientError.new("Cobinhood Error: " + response.body)
end