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.
- 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
|