bitex 0.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +63 -0
  3. data/.rubocop.yml +32 -0
  4. data/.ruby-version +1 -0
  5. data/bitex.gemspec +21 -18
  6. data/lib/bitex.rb +7 -1
  7. data/lib/bitex/api.rb +34 -41
  8. data/lib/bitex/ask.rb +74 -0
  9. data/lib/bitex/base_order.rb +106 -0
  10. data/lib/bitex/bid.rb +72 -0
  11. data/lib/bitex/buy.rb +8 -5
  12. data/lib/bitex/kyc_file.rb +31 -9
  13. data/lib/bitex/kyc_profile.rb +113 -38
  14. data/lib/bitex/{market.rb → market_data.rb} +3 -3
  15. data/lib/bitex/match.rb +30 -15
  16. data/lib/bitex/order.rb +6 -238
  17. data/lib/bitex/payment.rb +30 -18
  18. data/lib/bitex/rates.rb +6 -8
  19. data/lib/bitex/sell.rb +5 -5
  20. data/lib/bitex/specie_deposit.rb +9 -4
  21. data/lib/bitex/specie_withdrawal.rb +29 -28
  22. data/lib/bitex/trade.rb +4 -5
  23. data/lib/bitex/transaction.rb +7 -8
  24. data/lib/bitex/usd_deposit.rb +46 -47
  25. data/lib/bitex/usd_withdrawal.rb +33 -34
  26. data/lib/bitex/version.rb +1 -1
  27. data/spec/ask_spec.rb +17 -5
  28. data/spec/bid_spec.rb +17 -5
  29. data/spec/buy_spec.rb +14 -4
  30. data/spec/kyc_file_spec.rb +34 -18
  31. data/spec/kyc_profile_spec.rb +158 -122
  32. data/spec/order_spec.rb +1 -1
  33. data/spec/payment_spec.rb +51 -45
  34. data/spec/sell_spec.rb +14 -4
  35. data/spec/spec_helper.rb +7 -6
  36. data/spec/specie_deposit_spec.rb +10 -4
  37. data/spec/specie_withdrawal_spec.rb +26 -25
  38. data/spec/support/from_json_shared_examples.rb +20 -22
  39. data/spec/support/order_shared_examples.rb +14 -17
  40. data/spec/support/request_stubs.rb +18 -12
  41. data/spec/trade_spec.rb +5 -5
  42. data/spec/transaction_spec.rb +12 -13
  43. data/spec/usd_deposit_spec.rb +120 -105
  44. data/spec/usd_withdrawal_spec.rb +89 -79
  45. metadata +57 -10
@@ -1,49 +1,61 @@
1
1
  module Bitex
2
+ ##
3
+ # Documentation here!
4
+ #
2
5
  class Payment
3
- attr_accessor :id, :user_id, :amount, :currency_id, :expected_quantity,
4
- :previous_expected_quantity, :confirmed_quantity, :unconfirmed_quantity,
5
- :valid_until, :quote_valid_until, :last_quoted_on, :status, :address,
6
- :settlement_currency_id, :settlement_amount, :keep, :merchant_reference,
7
- :customer_reference
6
+ attr_accessor :id, :user_id, :amount, :currency_id, :expected_quantity, :previous_expected_quantity, :confirmed_quantity,
7
+ :unconfirmed_quantity, :valid_until, :quote_valid_until, :last_quoted_on, :status, :address,
8
+ :settlement_currency_id, :settlement_amount, :keep, :merchant_reference, :customer_reference
8
9
 
9
10
  # @visibility private
10
11
  def self.from_json(json)
11
12
  new.tap do |thing|
12
- json.each do |key,raw_value|
13
+ json.each do |key, raw_value|
13
14
  next if raw_value.nil?
14
15
 
15
- value = if [:valid_until, :quote_valid_until, :last_quoted_on].include?(key.to_sym)
16
- Time.at(raw_value)
17
- else
18
- raw_value
16
+ value =
17
+ if %i[valid_until quote_valid_until last_quoted_on].include?(key)
18
+ Time.at(raw_value)
19
+ else
20
+ raw_value
21
+ end
22
+
23
+ begin
24
+ thing.send("#{key}=", value)
25
+ rescue NoMethodError
26
+ nil
19
27
  end
20
- thing.send("#{key}=", value) rescue nil
21
28
  end
22
29
  end
23
30
  end
24
31
 
25
32
  def self.create!(params)
26
- from_json(Api.private(:post, "/private/payments", params))
33
+ from_json(Api.private(:post, base_uri, params))
27
34
  end
28
35
 
29
36
  def self.find(id)
30
- from_json(Api.private(:get, "/private/payments/#{id}"))
37
+ from_json(Api.private(:get, "#{base_uri}/#{id}"))
31
38
  end
32
39
 
33
40
  def self.all
34
- Api.private(:get, "/private/payments").collect{|x| from_json(x) }
41
+ Api.private(:get, base_uri).map { |payment| from_json(payment) }
35
42
  end
36
-
43
+
37
44
  # Validate a callback and parse the given payment from it.
38
45
  # Returns nil if the callback was invalid.
39
46
  def self.from_callback(callback_params)
40
- from_json(callback_params["payment"]) if callback_params["api_key"] == Bitex.api_key
47
+ from_json(callback_params['payment']) if callback_params['api_key'] == Bitex.api_key
41
48
  end
42
49
 
43
50
  # Sets up the web-pos
44
51
  def self.pos_setup!(params)
45
- Api.private(:post, "/private/payments/pos_setup", params)
52
+ Api.private(:post, "#{base_uri}/pos_setup", params)
53
+ end
54
+
55
+ private_class_method
56
+
57
+ def self.base_uri
58
+ '/private/payments'
46
59
  end
47
60
  end
48
61
  end
49
-
@@ -8,18 +8,17 @@ module Bitex
8
8
  # Bitex::Rates.calculate_back([:ars, :cash, :usd, :bitex, :more_mt], 200)
9
9
  # @see https://bitex.la/developers#rates
10
10
  class Rates
11
-
12
11
  # Full exchange rates tree, gets cached locally for 60 seconds.
13
12
  def self.tree
14
13
  if @tree.nil? || @last_tree_fetch.to_i < (Time.now.to_i - 60)
15
- @tree = Api.public("/rates/tree").deep_symbolize_keys
14
+ @tree = Api.public('/rates/tree').deep_symbolize_keys
16
15
  @last_tree_fetch = Time.now.to_i
17
16
  end
18
17
  @tree
19
18
  end
20
-
19
+
21
20
  def self.clear_tree_cache
22
- @tree = nil
21
+ @tree = nil
23
22
  @last_tree_fetch = nil
24
23
  end
25
24
 
@@ -40,7 +39,7 @@ module Bitex
40
39
  end
41
40
  value
42
41
  end
43
-
42
+
44
43
  def self.calculate_path_backwards(path, value)
45
44
  value = value.to_d
46
45
  path_to_calculator(path).each do |step|
@@ -53,13 +52,12 @@ module Bitex
53
52
  when :fixed_fee
54
53
  value += step[:amount].to_d
55
54
  when :minimum_fee
56
- value = [value + step[:minimum].to_d,
57
- value / (1 - (step[:percentage].to_d / 100.to_d))].max
55
+ value = [value + step[:minimum].to_d, value / (1 - (step[:percentage].to_d / 100.to_d))].max
58
56
  end
59
57
  end
60
58
  value
61
59
  end
62
-
60
+
63
61
  def self.path_to_calculator(path)
64
62
  steps = tree
65
63
  begin
@@ -7,18 +7,18 @@ module Bitex
7
7
  # @!attribute created_at
8
8
  # @return [Time] Time when this Sell happened.
9
9
 
10
- # @!attribute specie
11
- # @return [Symbol] :btc or :ltc
12
-
10
+ # @!attribute orderbook
11
+ # @return [Symbol] :btc_usd or :btc_ars
12
+
13
13
  # @!attribute quantity
14
14
  # @return [BigDecimal] Quantity of specie sold
15
-
15
+
16
16
  # @!attribute amount
17
17
  # @return [BigDecimal] Amount of USD earned
18
18
 
19
19
  # @!attribute fee
20
20
  # @return [BigDecimal] USD amount paid as transaction fee.
21
-
21
+
22
22
  # @!attribute price
23
23
  # @return [BigDecimal] Price charged per unit
24
24
 
@@ -10,7 +10,7 @@ module Bitex
10
10
  attr_accessor :created_at
11
11
 
12
12
  # @!attribute specie
13
- # @return [Symbol] :btc or :ltc
13
+ # @return [Symbol] :btc
14
14
  attr_accessor :specie
15
15
 
16
16
  # @!attribute quantity
@@ -19,8 +19,9 @@ module Bitex
19
19
 
20
20
  # @visibility private
21
21
  def self.from_json(json)
22
- Api.from_json(new, json, true) do |thing|
23
- thing.quantity = BigDecimal.new(json[4].to_s)
22
+ Api.from_json(new, json) do |thing|
23
+ thing.specie = { 1 => :btc }[json[3]]
24
+ thing.quantity = (json[4] || 0).to_d
24
25
  end
25
26
  end
26
27
 
@@ -29,7 +30,11 @@ module Bitex
29
30
  end
30
31
 
31
32
  def self.all(specie)
32
- Api.private(:get, "/private/#{specie}/deposits").collect{|x| from_json(x) }
33
+ Api.private(:get, "/private/#{specie}/deposits").map { |sd| from_json(sd) }
34
+ end
35
+
36
+ def self.species
37
+ { 0 => :btc }
33
38
  end
34
39
  end
35
40
  end
@@ -10,13 +10,13 @@ module Bitex
10
10
  attr_accessor :created_at
11
11
 
12
12
  # @!attribute specie
13
- # @return [Symbol] :btc or :ltc
13
+ # @return [Symbol] :btc
14
14
  attr_accessor :specie
15
15
 
16
16
  # @!attribute quantity
17
17
  # @return [BigDecimal] Quantity deposited
18
18
  attr_accessor :quantity
19
-
19
+
20
20
  # @!attribute status
21
21
  # Returns the status of this withdrawal.
22
22
  # * :received Our engine is checking if you have enough funds.
@@ -40,32 +40,22 @@ module Bitex
40
40
  # @!attribute label
41
41
  # @return [String] A custom label you gave to this address.
42
42
  attr_accessor :label
43
-
43
+
44
44
  # @!attribute kyc_profile_id
45
45
  # @return [Integer] Kyc profile id for which this request was made.
46
46
  attr_accessor :kyc_profile_id
47
47
 
48
48
  # @!attribute transaction_id
49
- # @return [String] Network transaction id, if available.
49
+ # @return [String] Network transaction id, if available.
50
50
  attr_accessor :transaction_id
51
51
 
52
52
  # @visibility private
53
53
  def self.from_json(json)
54
- status_lookup = {
55
- 1 => :received,
56
- 2 => :pending,
57
- 3 => :done,
58
- 4 => :cancelled,
59
- }
60
- reason_lookup = {
61
- 0 => :not_cancelled,
62
- 1 => :insufficient_funds,
63
- 2 => :destination_invalid,
64
- }
65
- Api.from_json(new, json, true) do |thing|
66
- thing.quantity = BigDecimal.new(json[4].to_s)
67
- thing.status = status_lookup[json[5]]
68
- thing.reason = reason_lookup[json[6]]
54
+ Api.from_json(new, json) do |thing|
55
+ thing.specie = { 1 => :btc }[json[3]]
56
+ thing.quantity = (json[4].presence || 0).to_d
57
+ thing.status = statuses[json[5]]
58
+ thing.reason = reasons[json[6]]
69
59
  thing.to_address = json[7]
70
60
  thing.label = json[8]
71
61
  thing.kyc_profile_id = json[9]
@@ -73,13 +63,17 @@ module Bitex
73
63
  end
74
64
  end
75
65
 
76
- def self.create!(specie, address, amount, label, kyc_profile_id=nil)
77
- from_json(Api.private(:post, "/private/#{specie}/withdrawals", {
78
- address: address,
79
- amount: amount,
80
- label: label,
81
- kyc_profile_id: kyc_profile_id
82
- }))
66
+ def self.create!(specie, address, amount, label, kyc_profile_id = nil)
67
+ from_json(
68
+ Api.private(
69
+ :post,
70
+ "/private/#{specie}/withdrawals",
71
+ address: address,
72
+ amount: amount,
73
+ label: label,
74
+ kyc_profile_id: kyc_profile_id
75
+ )
76
+ )
83
77
  end
84
78
 
85
79
  def self.find(specie, id)
@@ -87,8 +81,15 @@ module Bitex
87
81
  end
88
82
 
89
83
  def self.all(specie)
90
- Api.private(:get, "/private/#{specie}/withdrawals")
91
- .collect{|x| from_json(x) }
84
+ Api.private(:get, "/private/#{specie}/withdrawals").map { |sw| from_json(sw) }
85
+ end
86
+
87
+ def self.statuses
88
+ { 1 => :received, 2 => :pending, 3 => :done, 4 => :cancelled }
89
+ end
90
+
91
+ def self.reasons
92
+ { 0 => :not_cancelled, 1 => :insufficient_funds, 2 => :destination_invalid }
92
93
  end
93
94
  end
94
95
  end
@@ -1,13 +1,12 @@
1
1
  module Bitex
2
- # Utility class for fetching an heterogeneous list of objects that
3
- # compose your transaction history.
2
+ # Utility class for fetching an heterogeneous list of objects that compose your transaction history.
3
+ #
4
4
  class Trade
5
5
  # @return [Array<Bitex::Buy, Bitex::Sell]
6
- # Returns an heterogeneous array with all your transactions for the past
7
- # 30 days sorted by descending date.
6
+ # Returns an heterogeneous array with all your transactions for the past 30 days sorted by descending date.
8
7
  # @see https://bitex.la/developers#user-trades
9
8
  def self.all
10
- Api.private(:GET, '/private/trades').collect{|o| Api.deserialize(o) }
9
+ Api.private(:GET, '/private/trades').map { |t| Api.deserialize(t) }
11
10
  end
12
11
  end
13
12
  end
@@ -1,14 +1,13 @@
1
1
  module Bitex
2
- # Utility class for fetching an heterogeneous list of objects that
3
- # compose your transaction history.
4
- class Transaction
5
- # @return [Array<Bitex::Bid, Bitex::Ask, Bitex::SpecieDeposit,
6
- # Bitex::SpecieWithdrawal, Bitex::UsdDeposit, Bitex::UsdWithdrawal>]
7
- # Returns an heterogeneous array with all your transactions for the past
8
- # 15 days sorted by descending date.
2
+ # Utility class for fetching an heterogeneous list of objects that compose your transaction history.
3
+ #
4
+ class Transaction
5
+ # @return
6
+ # [Array<Bitex::Bid, Bitex::Ask, Bitex::SpecieDeposit, Bitex::SpecieWithdrawal, Bitex::UsdDeposit, Bitex::UsdWithdrawal>]
7
+ # Returns an heterogeneous array with all your transactions for the past 15 days sorted by descending date.
9
8
  # @see https://bitex.la/developers#user-account-summary
10
9
  def self.all
11
- Api.private(:GET, '/private/account_summary').collect{|o| Api.deserialize(o) }
10
+ Api.private(:GET, '/private/account_summary').map { |t| Api.deserialize(t) }
12
11
  end
13
12
  end
14
13
  end
@@ -1,5 +1,6 @@
1
1
  module Bitex
2
2
  # A deposit of USD to your bitex.la balance.
3
+ #
3
4
  class UsdDeposit
4
5
  # @!attribute id
5
6
  # @return [Integer] This UsdDeposit's unique ID.
@@ -10,14 +11,13 @@ module Bitex
10
11
  attr_accessor :created_at
11
12
 
12
13
  # @!attribute requested_amount
13
- # @return [BigDecimal] For pre-announced deposits, this is the amount you
14
- # requested to deposit.
14
+ # @return [BigDecimal] For pre-announced deposits, this is the amount you requested to deposit.
15
15
  attr_accessor :requested_amount
16
16
 
17
17
  # @!attribute amount
18
18
  # @return [BigDecimal] Final amount credited to your bitex USD balance.
19
19
  attr_accessor :amount
20
-
20
+
21
21
  # @!attribute deposit_method
22
22
  # The method used for this deposit
23
23
  # * :astropay
@@ -26,10 +26,8 @@ module Bitex
26
26
 
27
27
  # @!attribute status
28
28
  # The status of this deposit.
29
- # * :pending your deposit notice was received, we're waiting for the funds
30
- # to credit.
31
- # * :done your deposit credited correctly, the funds are available in your
32
- # balance.
29
+ # * :pending your deposit notice was received, we're waiting for the funds to credit.
30
+ # * :done your deposit credited correctly, the funds are available in your balance.
33
31
  # * :cancelled your deposit did not credit, check the 'reason' field.
34
32
  attr_accessor :status
35
33
 
@@ -37,28 +35,27 @@ module Bitex
37
35
  # The reason for cancellation of this deposit, if any.
38
36
  # * :not_cancelled.
39
37
  # * :did_not_credit funds never arrived to our end.
40
- # * :sender_unknown we could not accept these funds because you're not the
41
- # sender.
38
+ # * :sender_unknown we could not accept these funds because you're not the sender.
42
39
  # * :other we'll contact you regarding this deposit.
43
40
  # * :user_cancelled We cancelled this deposit per your request.
44
41
  attr_accessor :reason
45
-
42
+
46
43
  # @!attribute country
47
44
  # Country of origin for this deposit.
48
45
  attr_accessor :country
49
-
46
+
50
47
  # @!attribute currency
51
48
  # Local currency for the country.
52
49
  attr_accessor :currency
53
-
50
+
54
51
  # @!attribute kyc_profile_id
55
52
  # KYC profile on whose behalf this deposit is being created.
56
53
  attr_accessor :kyc_profile_id
57
-
54
+
58
55
  # @!attribute request_details
59
56
  # Details for our account officers about this deposit.
60
57
  attr_accessor :request_details
61
-
58
+
62
59
  # @!attribute astropay_response_body
63
60
  # Response from astropay if selected as the deposit method.
64
61
  # The 'url' field should be the astropay payment url for this deposit.
@@ -69,29 +66,14 @@ module Bitex
69
66
  attr_accessor :third_party_reference
70
67
 
71
68
  # @visibility private
69
+ # rubocop:disable Metrics/AbcSize
72
70
  def self.from_json(json, deposit = nil)
73
- deposit_method_lookup = {
74
- 1 => :astropay,
75
- 2 => :other,
76
- }
77
- status_lookup = {
78
- 1 => :pending,
79
- 2 => :done,
80
- 3 => :cancelled,
81
- }
82
- reason_lookup = {
83
- 0 => :not_cancelled,
84
- 1 => :did_not_credit,
85
- 2 => :sender_unknown,
86
- 3 => :other,
87
- 4 => :user_cancelled,
88
- }
89
71
  Api.from_json(deposit || new, json) do |thing|
90
- thing.requested_amount = BigDecimal.new(json[3].to_s)
91
- thing.amount = BigDecimal.new(json[4].to_s)
92
- thing.deposit_method = deposit_method_lookup[json[5]]
93
- thing.status = status_lookup[json[6]]
94
- thing.reason = reason_lookup[json[7]]
72
+ thing.requested_amount = (json[3].presence || 0).to_d
73
+ thing.amount = (json[4].presence || 0).to_d
74
+ thing.deposit_method = deposit_methods[json[5]]
75
+ thing.status = statuses[json[6]]
76
+ thing.reason = reasons[json[7]]
95
77
  thing.country = json[8]
96
78
  thing.currency = json[9]
97
79
  thing.kyc_profile_id = json[10]
@@ -100,29 +82,46 @@ module Bitex
100
82
  thing.third_party_reference = json[13]
101
83
  end
102
84
  end
85
+ # rubocop:enable Metrics/AbcSize
103
86
 
104
- def self.create!(country, amount, currency, method, details, profile=nil)
105
- from_json(Api.private(:post, "/private/usd/deposits", {
106
- country: country,
107
- amount: amount,
108
- currency: currency,
109
- deposit_method: method,
110
- request_details: details,
111
- kyc_profile_id: profile,
112
- }))
87
+ def self.create!(country, amount, currency, method, details, profile = nil)
88
+ from_json(
89
+ Api.private(
90
+ :post,
91
+ '/private/usd/deposits',
92
+ country: country,
93
+ amount: amount,
94
+ currency: currency,
95
+ deposit_method: method,
96
+ request_details: details,
97
+ kyc_profile_id: profile
98
+ )
99
+ )
113
100
  end
114
-
101
+
115
102
  def self.find(id)
116
103
  from_json(Api.private(:get, "/private/usd/deposits/#{id}"))
117
104
  end
118
105
 
119
106
  def cancel!
120
- path = "/private/usd/deposits/#{self.id}/cancel"
107
+ path = "/private/usd/deposits/#{id}/cancel"
121
108
  self.class.from_json(Api.private(:post, path), self)
122
109
  end
123
110
 
124
111
  def self.all
125
- Api.private(:get, "/private/usd/deposits").collect{|x| from_json(x) }
112
+ Api.private(:get, '/private/usd/deposits').map { |d| from_json(d) }
113
+ end
114
+
115
+ def self.deposit_methods
116
+ { 1 => :astropay, 2 => :other }
117
+ end
118
+
119
+ def self.statuses
120
+ { 1 => :pending, 2 => :done, 3 => :cancelled }
121
+ end
122
+
123
+ def self.reasons
124
+ { 0 => :not_cancelled, 1 => :did_not_credit, 2 => :sender_unknown, 3 => :other, 4 => :user_cancelled }
126
125
  end
127
126
  end
128
127
  end