bibox 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +15 -0
  4. data/.rspec +3 -0
  5. data/.travis.yml +5 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +6 -0
  8. data/Gemfile.lock +67 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +67 -0
  11. data/Rakefile +6 -0
  12. data/bibox.gemspec +36 -0
  13. data/bin/console +31 -0
  14. data/bin/setup +8 -0
  15. data/bin/websocket +71 -0
  16. data/credentials.yml.example +7 -0
  17. data/lib/.DS_Store +0 -0
  18. data/lib/bibox.rb +74 -0
  19. data/lib/bibox/.DS_Store +0 -0
  20. data/lib/bibox/configuration.rb +21 -0
  21. data/lib/bibox/constants.rb +6 -0
  22. data/lib/bibox/errors.rb +17 -0
  23. data/lib/bibox/extensions/string.rb +13 -0
  24. data/lib/bibox/models/asset.rb +29 -0
  25. data/lib/bibox/models/base.rb +26 -0
  26. data/lib/bibox/models/bill.rb +26 -0
  27. data/lib/bibox/models/ohlcv.rb +16 -0
  28. data/lib/bibox/models/order.rb +38 -0
  29. data/lib/bibox/models/order_book.rb +29 -0
  30. data/lib/bibox/models/pair.rb +24 -0
  31. data/lib/bibox/models/ticker.rb +18 -0
  32. data/lib/bibox/models/trade.rb +13 -0
  33. data/lib/bibox/models/transfer.rb +26 -0
  34. data/lib/bibox/models/user_assets.rb +23 -0
  35. data/lib/bibox/rest/client.rb +97 -0
  36. data/lib/bibox/rest/errors.rb +16 -0
  37. data/lib/bibox/rest/private/assets.rb +33 -0
  38. data/lib/bibox/rest/private/bills.rb +31 -0
  39. data/lib/bibox/rest/private/order_book.rb +21 -0
  40. data/lib/bibox/rest/private/orders.rb +131 -0
  41. data/lib/bibox/rest/private/transfers.rb +49 -0
  42. data/lib/bibox/rest/public/klines.rb +22 -0
  43. data/lib/bibox/rest/public/order_book.rb +16 -0
  44. data/lib/bibox/rest/public/pairs.rb +23 -0
  45. data/lib/bibox/rest/public/ticker.rb +16 -0
  46. data/lib/bibox/rest/public/trades.rb +16 -0
  47. data/lib/bibox/utilities.rb +68 -0
  48. data/lib/bibox/version.rb +3 -0
  49. data/lib/bibox/websocket/client.rb +149 -0
  50. metadata +232 -0
Binary file
@@ -0,0 +1,74 @@
1
+ # Rest API
2
+ require "faraday"
3
+ require "faraday_middleware"
4
+ require "openssl"
5
+
6
+ # Websockets
7
+ require "faye/websocket"
8
+ require "eventmachine"
9
+
10
+ # Shared
11
+ require "json"
12
+ require "date"
13
+ require "bigdecimal"
14
+
15
+ # Library
16
+ require "bibox/version"
17
+
18
+ require "bibox/configuration"
19
+ require "bibox/errors"
20
+ require "bibox/constants"
21
+ require "bibox/utilities"
22
+
23
+ require "bibox/models/base"
24
+ require "bibox/models/ticker"
25
+ require "bibox/models/pair"
26
+ require "bibox/models/trade"
27
+ require "bibox/models/order_book"
28
+ require "bibox/models/ohlcv"
29
+ require "bibox/models/order"
30
+ require "bibox/models/asset"
31
+ require "bibox/models/user_assets"
32
+ require "bibox/models/transfer"
33
+ require "bibox/models/bill"
34
+
35
+ require "bibox/rest/public/ticker"
36
+ require "bibox/rest/public/pairs"
37
+ require "bibox/rest/public/trades"
38
+ require "bibox/rest/public/order_book"
39
+ require "bibox/rest/public/klines"
40
+
41
+ require "bibox/rest/private/orders"
42
+ require "bibox/rest/private/order_book"
43
+ require "bibox/rest/private/assets"
44
+ require "bibox/rest/private/transfers"
45
+ require "bibox/rest/private/bills"
46
+
47
+ require "bibox/rest/errors"
48
+ require "bibox/rest/client"
49
+
50
+ require "bibox/websocket/client"
51
+
52
+ if !String.instance_methods(false).include?(:underscore)
53
+ require "bibox/extensions/string"
54
+ end
55
+
56
+ module Bibox
57
+
58
+ class << self
59
+ attr_writer :configuration
60
+ end
61
+
62
+ def self.configuration
63
+ @configuration ||= ::Bibox::Configuration.new
64
+ end
65
+
66
+ def self.reset
67
+ @configuration = ::Bibox::Configuration.new
68
+ end
69
+
70
+ def self.configure
71
+ yield(configuration)
72
+ end
73
+
74
+ end
Binary file
@@ -0,0 +1,21 @@
1
+ module Bibox
2
+ class Configuration
3
+ attr_accessor :key, :secret, :faraday
4
+
5
+ def initialize
6
+ self.key = nil
7
+ self.secret = nil
8
+
9
+ self.faraday = {
10
+ adapter: :net_http,
11
+ user_agent: 'Bibox Ruby',
12
+ verbose: false
13
+ }
14
+ end
15
+
16
+ def verbose_faraday?
17
+ self.faraday.fetch(:verbose, false)
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,6 @@
1
+ module Bibox
2
+ module Constants
3
+ BUY_ORDER = 1
4
+ SELL_ORDER = 2
5
+ end
6
+ end
@@ -0,0 +1,17 @@
1
+ module Bibox
2
+ module Errors
3
+ class Error < StandardError; end;
4
+ class MissingConfigError < Bibox::Errors::Error; end;
5
+ class ParameterError < Bibox::Errors::Error; end;
6
+ class InvalidOrderError < Bibox::Errors::Error; end;
7
+ class ApiNotSupportedError < Bibox::Errors::Error; end;
8
+ class WebsocketError < Bibox::Errors::Error; end;
9
+
10
+ MAPPING = {
11
+ "2033" => -> { raise ::Bibox::Errors::InvalidOrderError.new("Order operation failed! Order has already completed or has already been revoked (code 2033)") },
12
+ "3000" => -> { raise ::Bibox::Errors::ParameterError.new("Invalid parameters specified (code 3000)") },
13
+ "3011" => -> { raise ::Bibox::Errors::ApiNotSupportedError.new("This method isn't available via the API (code 3011)") },
14
+ }
15
+
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ class String
2
+
3
+ def underscore
4
+ word = self.dup
5
+ word.gsub!(/::/, '/')
6
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
7
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
8
+ word.tr!("-", "_")
9
+ word.downcase!
10
+ word
11
+ end
12
+
13
+ end
@@ -0,0 +1,29 @@
1
+ module Bibox
2
+ module Models
3
+ class Asset < Base
4
+ MAPPING = {
5
+ id: :string,
6
+ symbol: :string,
7
+ icon_url: :string,
8
+ describe_url: :string,
9
+ name: :string,
10
+ enable_withdraw: :boolean,
11
+ enable_deposit: :boolean,
12
+ confirm_count: :integer,
13
+ total_balance: :float,
14
+ balance: :float,
15
+ freeze: :float,
16
+ btc_value: :float,
17
+ cny_value: :float,
18
+ usd_value: :float
19
+ }
20
+
21
+ def initialize(hash)
22
+ super(hash)
23
+
24
+ self.symbol = hash.fetch("coin_symbol", nil) if self.symbol.to_s.empty? && hash.has_key?("coin_symbol")
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ module Bibox
2
+ module Models
3
+ class Base
4
+
5
+ def initialize(hash)
6
+ self.class::MAPPING.keys.each { |key| self.class.send(:attr_accessor, key) }
7
+
8
+ hash.each do |key, value|
9
+ key = key.underscore.to_sym
10
+ type = self.class::MAPPING.fetch(key, nil)
11
+ value = value && type ? ::Bibox::Utilities::convert_value(value, type, use_ms_for_time: true) : value
12
+ self.send("#{key}=", value) if self.respond_to?(key)
13
+ end
14
+ end
15
+
16
+ def attributes
17
+ Hash[instance_variables.map { |name| [name.to_s.gsub(/^@/, "").to_sym, instance_variable_get(name)] }]
18
+ end
19
+
20
+ def self.parse(data)
21
+ data&.collect { |item| self.new(item) }
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ module Bibox
2
+ module Models
3
+ class Bill < Base
4
+ MAPPING = {
5
+ created_at: :datetime,
6
+ symbol: :string,
7
+ change_amount: :float,
8
+ result_amount: :float,
9
+ fee: :float,
10
+ fee_symbol: :string,
11
+ comment: :string,
12
+ bill_type: {enum: {-1 => :all, 0 => :deposit, 2 => :withdrawal, 3 => :sell, 5 => :buy, 31 => :transfer_in, 32 => :transfer_out}},
13
+ }
14
+
15
+ BILL_TYPES = {
16
+ all: -1,
17
+ deposit: 0,
18
+ withdrawal: 2,
19
+ sell: 3,
20
+ buy: 5,
21
+ transfer_in: 31,
22
+ transfer_out: 32
23
+ }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ module Bibox
2
+ module Models
3
+ class OHLCV < Base
4
+
5
+ MAPPING = {
6
+ time: :time,
7
+ open: :float,
8
+ high: :float,
9
+ low: :float,
10
+ close: :float,
11
+ vol: :float
12
+ }
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,38 @@
1
+ module Bibox
2
+ module Models
3
+ class Order < Base
4
+ MAPPING = {
5
+ id: :string,
6
+ created_at: :time,
7
+ account_type: :integer,
8
+ coin_symbol: :string,
9
+ currency_symbol: :string,
10
+ fee_symbol: :string,
11
+ order_side: {enum: {1 => :buy, 2 => :sell}},
12
+ order_type: :integer,
13
+ price: :float,
14
+ amount: :float,
15
+ money: :float,
16
+ fee: :float,
17
+ pay_bix: :boolean,
18
+ deal_price: :float,
19
+ deal_amount: :float,
20
+ deal_money: :float,
21
+ deal_percent: :string,
22
+ status: :integer,
23
+ unexecuted: :float
24
+ }
25
+
26
+ ORDER_SIDES = {
27
+ buy: 1,
28
+ sell: 2
29
+ }
30
+
31
+ ORDER_TYPES = {
32
+ market: 1, # NOT VERIFIED! There's no API documentation so it's just a guess for now.
33
+ limit: 2
34
+ }
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,29 @@
1
+ module Bibox
2
+ module Models
3
+ class OrderBook
4
+ attr_accessor :pair, :update_time, :asks, :bids
5
+
6
+ def initialize(hash)
7
+ self.pair = hash.fetch("pair", nil)
8
+ self.update_time = ::Bibox::Utilities.epoch_to_time(hash.fetch("update_time", nil), ms: true) if hash.has_key?("update_time") && !hash.fetch("update_time", nil).to_s.empty?
9
+
10
+ self.bids = []
11
+ self.asks = []
12
+
13
+ process(hash)
14
+ end
15
+
16
+ def process(hash)
17
+ [:bids, :asks].each do |type|
18
+ hash.fetch(type.to_s, []).each do |item|
19
+ price = ::Bibox::Utilities.convert_value(item.fetch("price", nil), :float)
20
+ volume = ::Bibox::Utilities.convert_value(item.fetch("volume", nil), :float)
21
+ value = !price.nil? && !volume.nil? ? price * volume : nil
22
+ self.send(type).send(:<<, {price: price, volume: volume, value: value})
23
+ end
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ module Bibox
2
+ module Models
3
+ class Pair < Base
4
+ MAPPING = {
5
+ id: :string,
6
+ coin_symbol: :string,
7
+ currency_symbol: :string,
8
+ high: :float,
9
+ low: :float,
10
+ last: :float,
11
+ vol24h: :float,
12
+ amount: :float,
13
+ change: :string,
14
+ percent: :string,
15
+ low_cny: :float,
16
+ high_cny: :float,
17
+ last_cny: :float,
18
+ low_usd: :float,
19
+ high_usd: :float,
20
+ last_usd: :float
21
+ }
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ module Bibox
2
+ module Models
3
+ class Ticker < Base
4
+ MAPPING = {
5
+ buy: :float,
6
+ sell: :float,
7
+ high: :float,
8
+ low: :float,
9
+ last: :float,
10
+ vol: :float,
11
+ timestamp: :time,
12
+ last_cny: :float,
13
+ last_usd: :float,
14
+ percent: :string,
15
+ }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ module Bibox
2
+ module Models
3
+ class Trade < Base
4
+ MAPPING = {
5
+ pair: :string,
6
+ price: :float,
7
+ amount: :float,
8
+ time: :time,
9
+ side: {enum: {1 => :buy, 2 => :sell}}
10
+ }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ module Bibox
2
+ module Models
3
+ class Transfer < Base
4
+ MAPPING = {
5
+ user_id: :string,
6
+ coin_id: :string,
7
+ to: :string,
8
+ coin_symbol: :string,
9
+ confirm_count: :string,
10
+ amount: :float,
11
+ updated_at: :datetime,
12
+ created_at: :datetime,
13
+ url: :string,
14
+ icon_url: :string,
15
+ status: {enum: {1 => :pending, 2 => :success, 3 => :failed}},
16
+ }
17
+
18
+ STATUSES = {
19
+ all: 0,
20
+ pending: 1,
21
+ success: 2,
22
+ failed: 3
23
+ }
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ module Bibox
2
+ module Models
3
+ class UserAssets < Base
4
+ attr_accessor :assets
5
+
6
+ MAPPING = {
7
+ total_btc: :float,
8
+ total_cny: :float,
9
+ total_usd: :float,
10
+ }
11
+
12
+ def initialize(hash)
13
+ super(hash)
14
+ process(hash.fetch("assets_list", []))
15
+ end
16
+
17
+ def process(assets)
18
+ self.assets = ::Bibox::Models::Asset.parse(assets)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,97 @@
1
+ module Bibox
2
+ module Rest
3
+ class Client
4
+ attr_accessor :url, :configuration
5
+
6
+ def initialize(configuration: ::Bibox.configuration)
7
+ self.url = "https://api.bibox.com/v1"
8
+ self.configuration = configuration
9
+ end
10
+
11
+ include ::Bibox::Rest::Errors
12
+
13
+ include ::Bibox::Rest::Public::Ticker
14
+ include ::Bibox::Rest::Public::Pairs
15
+ include ::Bibox::Rest::Public::Trades
16
+ include ::Bibox::Rest::Public::OrderBook
17
+ include ::Bibox::Rest::Public::Klines
18
+
19
+ include ::Bibox::Rest::Private::Orders
20
+ include ::Bibox::Rest::Private::OrderBook
21
+ include ::Bibox::Rest::Private::Assets
22
+ include ::Bibox::Rest::Private::Transfers
23
+ include ::Bibox::Rest::Private::Bills
24
+
25
+ def configured?
26
+ !self.configuration.key.to_s.empty? && !self.configuration.secret.to_s.empty?
27
+ end
28
+
29
+ def check_credentials!
30
+ unless configured?
31
+ raise ::Bibox::Errors::MissingConfigError.new("Bibox gem hasn't been properly configured.")
32
+ end
33
+ end
34
+
35
+ def to_uri(path)
36
+ "#{self.url}#{path}"
37
+ end
38
+
39
+ def parse(response)
40
+ error?(response)
41
+ response
42
+ end
43
+
44
+ def get(path, params: {}, options: {})
45
+ request path, method: :get, params: params, options: options
46
+ end
47
+
48
+ def post(path, params: {}, data: {}, options: {})
49
+ request path, method: :post, params: params, data: auth(data), options: options
50
+ end
51
+
52
+ def auth(payload = {})
53
+ data = {}
54
+ data[:cmds] = payload.to_json
55
+
56
+ if configured?
57
+ data[:apikey] = self.configuration.key
58
+ data[:sign] = ::OpenSSL::HMAC.hexdigest('md5', self.configuration.secret, payload.to_json)
59
+ end
60
+
61
+ return data
62
+ end
63
+
64
+ def request(path, method: :get, params: {}, data: {}, options: {})
65
+ user_agent = options.fetch(:user_agent, self.configuration.faraday.fetch(:user_agent, nil))
66
+ proxy = options.fetch(:proxy, nil)
67
+
68
+ connection = Faraday.new(url: to_uri(path)) do |builder|
69
+ builder.headers[:user_agent] = user_agent if !user_agent.to_s.empty?
70
+ builder.request :url_encoded if method.eql?(:post)
71
+ builder.response :logger if self.configuration.verbose_faraday?
72
+ builder.response :json
73
+
74
+ if proxy
75
+ puts "[Bibox::Rest::Client] - Will connect to Bibox using proxy: #{proxy.inspect}" if self.configuration.verbose_faraday?
76
+ builder.proxy = proxy
77
+ end
78
+
79
+ builder.adapter self.configuration.faraday.fetch(:adapter, :net_http)
80
+ end
81
+
82
+ case method
83
+ when :get
84
+ connection.get do |request|
85
+ request.params = params if params && !params.empty?
86
+ end&.body
87
+ when :post
88
+ connection.post do |request|
89
+ request.body = data
90
+ request.params = params if params && !params.empty?
91
+ end&.body
92
+ end
93
+ end
94
+
95
+ end
96
+ end
97
+ end