class CoinSync::Importers::BitBayAPI
Constants
- BASE_URL
- MAX_TIME_DIFFERENCE
- OP_FEE
- OP_PURCHASE
- OP_SALE
- POLISH_TIMEZONE
- TRANSACTION_TYPES
Public Class Methods
new(config, params = {})
click to toggle source
Calls superclass method
CoinSync::Importers::Base::new
# File lib/coinsync/importers/bitbay_api.rb, line 73 def initialize(config, params = {}) super # required permissions: # * for balance checks: # - "Crypto deposit" (shown as "Get and create cryptocurrency addresses" + "Funds deposit") # - "Updating a wallets list" (shown as "Pobieranie rachunków") # * for transaction history: # - "History" (shown as "Fetch history of transactions") @public_key = params['api_public_key'] @secret_key = params['api_private_key'] end
Public Instance Methods
can_import?(type)
click to toggle source
# File lib/coinsync/importers/bitbay_api.rb, line 87 def can_import?(type) @public_key && @secret_key && [:balances, :transactions].include?(type) end
import_balances()
click to toggle source
# File lib/coinsync/importers/bitbay_api.rb, line 126 def import_balances info = fetch_info info['balances'].select { |k, v| v['available'].to_f > 0 || v['locked'].to_f > 0 }.map { |k, v| Balance.new( CryptoCurrency.new(k), available: BigDecimal.new(v['available']), locked: BigDecimal.new(v['locked']) ) } end
import_transactions(filename)
click to toggle source
# File lib/coinsync/importers/bitbay_api.rb, line 91 def import_transactions(filename) info = fetch_info currencies = info['balances'].keys transactions = [] currencies.each do |currency| sleep 1 # rate limiting # TODO: does this limit really work? (no way to test it really and docs don't mention a max value) response = make_request('history', currency: currency, limit: 10000) case response when Net::HTTPSuccess json = JSON.parse(response.body) if !json.is_a?(Array) raise "BitBay API importer: Invalid response: #{response.body}" end transactions.concat(json) when Net::HTTPBadRequest raise "BitBay API importer: Bad request: #{response}" else raise "BitBay API importer: Bad response: #{response}" end end transactions.each_with_index { |tx, i| tx['i'] = i } transactions.sort_by! { |tx| [tx['time'], -tx['i']] } transactions.each_with_index { |tx, i| tx.delete('i') } File.write(filename, JSON.pretty_generate(transactions)) end
read_transaction_list(source)
click to toggle source
# File lib/coinsync/importers/bitbay_api.rb, line 140 def read_transaction_list(source) json = JSON.parse(source.read) matching = [] transactions = [] json.each do |hash| entry = HistoryEntry.new(hash) next unless TRANSACTION_TYPES.include?(entry.type) if !matching.empty? must_match = matching.any? { |e| (e.date - entry.date).abs > MAX_TIME_DIFFERENCE } transaction = process_matched(matching, must_match) transactions << transaction if transaction end matching << entry end if !matching.empty? transactions << process_matched(matching, true) end transactions end
Private Instance Methods
fetch_info()
click to toggle source
# File lib/coinsync/importers/bitbay_api.rb, line 219 def fetch_info response = make_request('info') case response when Net::HTTPSuccess json = JSON.parse(response.body) if json['success'] != 1 || json['code'] || json['balances'].nil? raise "BitBay API importer: Invalid response: #{response.body}" end json when Net::HTTPBadRequest raise "BitBay API importer: Bad request: #{response}" else raise "BitBay API importer: Bad response: #{response}" end end
make_request(method, params = {})
click to toggle source
# File lib/coinsync/importers/bitbay_api.rb, line 201 def make_request(method, params = {}) (@public_key && @secret_key) or raise "Public and secret API keys must be provided" url = URI(BASE_URL) params['method'] = method params['moment'] = Time.now.to_i param_string = URI.encode_www_form(params) hmac = OpenSSL::HMAC.hexdigest('sha512', @secret_key, param_string) Request.post(url) do |request| request.body = param_string request['API-Key'] = @public_key request['API-Hash'] = hmac end end
process_matched(matching, must_match)
click to toggle source
# File lib/coinsync/importers/bitbay_api.rb, line 170 def process_matched(matching, must_match) if matching.length % 3 == 0 purchases = matching.select { |tx| tx.type == OP_PURCHASE } sales = matching.select { |tx| tx.type == OP_SALE } fees = matching.select { |tx| tx.type == OP_FEE } if purchases.length == sales.length && purchases.length == fees.length bought_currency = (purchases + fees).map(&:currency).uniq sold_currency = sales.map(&:currency).uniq if bought_currency.length == 1 && sold_currency.length == 1 matching.clear return Transaction.new( exchange: 'BitBay', bought_currency: bought_currency.first, sold_currency: sold_currency.first, time: (purchases + sales + fees).map(&:date).last, bought_amount: (purchases + fees).map(&:amount).reduce(&:+), sold_amount: -sales.map(&:amount).reduce(&:+) ) end end end if must_match raise "BitBay API importer error: Couldn't match some history lines: " + matching.map { |m| "\n#{m.inspect}" }.join end end