bitex 0.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +63 -0
- data/.rubocop.yml +32 -0
- data/.ruby-version +1 -0
- data/bitex.gemspec +21 -18
- data/lib/bitex.rb +7 -1
- data/lib/bitex/api.rb +34 -41
- data/lib/bitex/ask.rb +74 -0
- data/lib/bitex/base_order.rb +106 -0
- data/lib/bitex/bid.rb +72 -0
- data/lib/bitex/buy.rb +8 -5
- data/lib/bitex/kyc_file.rb +31 -9
- data/lib/bitex/kyc_profile.rb +113 -38
- data/lib/bitex/{market.rb → market_data.rb} +3 -3
- data/lib/bitex/match.rb +30 -15
- data/lib/bitex/order.rb +6 -238
- data/lib/bitex/payment.rb +30 -18
- data/lib/bitex/rates.rb +6 -8
- data/lib/bitex/sell.rb +5 -5
- data/lib/bitex/specie_deposit.rb +9 -4
- data/lib/bitex/specie_withdrawal.rb +29 -28
- data/lib/bitex/trade.rb +4 -5
- data/lib/bitex/transaction.rb +7 -8
- data/lib/bitex/usd_deposit.rb +46 -47
- data/lib/bitex/usd_withdrawal.rb +33 -34
- data/lib/bitex/version.rb +1 -1
- data/spec/ask_spec.rb +17 -5
- data/spec/bid_spec.rb +17 -5
- data/spec/buy_spec.rb +14 -4
- data/spec/kyc_file_spec.rb +34 -18
- data/spec/kyc_profile_spec.rb +158 -122
- data/spec/order_spec.rb +1 -1
- data/spec/payment_spec.rb +51 -45
- data/spec/sell_spec.rb +14 -4
- data/spec/spec_helper.rb +7 -6
- data/spec/specie_deposit_spec.rb +10 -4
- data/spec/specie_withdrawal_spec.rb +26 -25
- data/spec/support/from_json_shared_examples.rb +20 -22
- data/spec/support/order_shared_examples.rb +14 -17
- data/spec/support/request_stubs.rb +18 -12
- data/spec/trade_spec.rb +5 -5
- data/spec/transaction_spec.rb +12 -13
- data/spec/usd_deposit_spec.rb +120 -105
- data/spec/usd_withdrawal_spec.rb +89 -79
- metadata +57 -10
data/lib/bitex/payment.rb
CHANGED
@@ -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
|
-
|
5
|
-
|
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 =
|
16
|
-
|
17
|
-
|
18
|
-
|
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,
|
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, "
|
37
|
+
from_json(Api.private(:get, "#{base_uri}/#{id}"))
|
31
38
|
end
|
32
39
|
|
33
40
|
def self.all
|
34
|
-
Api.private(:get,
|
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[
|
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, "/
|
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
|
-
|
data/lib/bitex/rates.rb
CHANGED
@@ -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(
|
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
|
data/lib/bitex/sell.rb
CHANGED
@@ -7,18 +7,18 @@ module Bitex
|
|
7
7
|
# @!attribute created_at
|
8
8
|
# @return [Time] Time when this Sell happened.
|
9
9
|
|
10
|
-
# @!attribute
|
11
|
-
# @return [Symbol] :
|
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
|
|
data/lib/bitex/specie_deposit.rb
CHANGED
@@ -10,7 +10,7 @@ module Bitex
|
|
10
10
|
attr_accessor :created_at
|
11
11
|
|
12
12
|
# @!attribute specie
|
13
|
-
# @return [Symbol] :btc
|
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
|
23
|
-
thing.
|
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").
|
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
|
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
|
-
|
55
|
-
1 => :
|
56
|
-
|
57
|
-
|
58
|
-
|
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(
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
-
|
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
|
data/lib/bitex/trade.rb
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
module Bitex
|
2
|
-
# Utility class for fetching an heterogeneous list of objects that
|
3
|
-
#
|
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').
|
9
|
+
Api.private(:GET, '/private/trades').map { |t| Api.deserialize(t) }
|
11
10
|
end
|
12
11
|
end
|
13
12
|
end
|
data/lib/bitex/transaction.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
module Bitex
|
2
|
-
# Utility class for fetching an heterogeneous list of objects that
|
3
|
-
#
|
4
|
-
class Transaction
|
5
|
-
# @return
|
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').
|
10
|
+
Api.private(:GET, '/private/account_summary').map { |t| Api.deserialize(t) }
|
12
11
|
end
|
13
12
|
end
|
14
13
|
end
|
data/lib/bitex/usd_deposit.rb
CHANGED
@@ -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
|
-
#
|
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 =
|
91
|
-
thing.amount =
|
92
|
-
thing.deposit_method =
|
93
|
-
thing.status =
|
94
|
-
thing.reason =
|
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(
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
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/#{
|
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,
|
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
|