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/spec/order_spec.rb
CHANGED
data/spec/payment_spec.rb
CHANGED
@@ -1,21 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Bitex::Payment do
|
4
|
-
before
|
5
|
-
Bitex.api_key = 'valid_api_key'
|
6
|
-
end
|
4
|
+
before(:each) { Bitex.api_key = 'valid_api_key' }
|
7
5
|
|
8
6
|
let(:params_for_create) do
|
9
7
|
{
|
10
8
|
currency_id: 3,
|
11
9
|
amount: 1000,
|
12
|
-
callback_url:
|
10
|
+
callback_url: 'https://example.com/ipn',
|
13
11
|
keep: 25.0,
|
14
|
-
customer_reference:
|
15
|
-
merchant_reference:
|
12
|
+
customer_reference: 'An Alto latte, no sugar',
|
13
|
+
merchant_reference: 'invoice#1234'
|
16
14
|
}
|
17
15
|
end
|
18
|
-
|
16
|
+
|
19
17
|
let(:as_json) do
|
20
18
|
{
|
21
19
|
id: 1,
|
@@ -29,21 +27,23 @@ describe Bitex::Payment do
|
|
29
27
|
valid_until: 1430226201,
|
30
28
|
quote_valid_until: 1430226201,
|
31
29
|
last_quoted_on: 1430220201,
|
32
|
-
status:
|
33
|
-
address: {
|
34
|
-
|
35
|
-
|
30
|
+
status: 'pending',
|
31
|
+
address: {
|
32
|
+
'id': 4,
|
33
|
+
'public_address': '1ABC...',
|
36
34
|
},
|
37
35
|
settlement_currency_id: 2,
|
38
36
|
settlement_amount: 100,
|
39
37
|
keep: 1.5,
|
40
|
-
merchant_reference:
|
41
|
-
customer_reference:
|
38
|
+
merchant_reference: 'Invoice#1234',
|
39
|
+
customer_reference: 'Frappuchino',
|
42
40
|
}
|
43
41
|
end
|
44
|
-
|
42
|
+
|
43
|
+
let(:as_malformed_json) { { bad_key: 'i should not be setted' } }
|
44
|
+
|
45
45
|
let(:callback_params) do
|
46
|
-
{
|
46
|
+
{ 'api_key' => 'valid_api_key', 'payment' => as_json }
|
47
47
|
end
|
48
48
|
|
49
49
|
{
|
@@ -56,64 +56,70 @@ describe Bitex::Payment do
|
|
56
56
|
confirmed_quantity: 0.0,
|
57
57
|
unconfirmed_quantity: 0.0,
|
58
58
|
valid_until: Time.at(1430226201),
|
59
|
-
quote_valid_until: Time.at(
|
60
|
-
last_quoted_on: Time.at(
|
61
|
-
status:
|
62
|
-
address: {
|
63
|
-
|
64
|
-
|
59
|
+
quote_valid_until: Time.at(1_430_226_201),
|
60
|
+
last_quoted_on: Time.at(1_430_220_201),
|
61
|
+
status: 'pending',
|
62
|
+
address: {
|
63
|
+
'id': 4,
|
64
|
+
'public_address': '1ABC...',
|
65
65
|
},
|
66
66
|
settlement_currency_id: 2,
|
67
67
|
settlement_amount: 100,
|
68
68
|
keep: 1.5,
|
69
|
-
merchant_reference:
|
70
|
-
customer_reference:
|
69
|
+
merchant_reference: 'Invoice#1234',
|
70
|
+
customer_reference: 'Frappuchino'
|
71
71
|
}.each do |field, value|
|
72
|
-
|
73
|
-
|
72
|
+
it "sets #{field}" do
|
73
|
+
subject.class.from_json(as_json).send(field).should eq value
|
74
|
+
end
|
75
|
+
|
76
|
+
it "not sets #{field}" do
|
77
|
+
subject.class.from_json(as_malformed_json).send(field).should be_nil
|
78
|
+
end
|
74
79
|
end
|
75
|
-
end
|
76
80
|
|
77
81
|
it 'creates a new payment' do
|
78
|
-
stub_private(:post,
|
79
|
-
|
80
|
-
Bitex::Payment.create!(params_for_create)
|
81
|
-
.should be_a Bitex::Payment
|
82
|
+
stub_private(:post, '/private/payments', 'payment', params_for_create)
|
83
|
+
|
84
|
+
Bitex::Payment.create!(params_for_create).should be_a Bitex::Payment
|
82
85
|
end
|
83
|
-
|
86
|
+
|
84
87
|
it 'finds a single payment' do
|
85
88
|
stub_private(:get, '/private/payments/1', 'payment')
|
89
|
+
|
86
90
|
Bitex::Payment.find(1).should be_a Bitex::Payment
|
87
91
|
end
|
88
|
-
|
92
|
+
|
89
93
|
it 'lists all payments' do
|
90
94
|
stub_private(:get, '/private/payments', 'payments')
|
95
|
+
|
91
96
|
payments = Bitex::Payment.all
|
97
|
+
|
92
98
|
payments.should be_an Array
|
93
|
-
payments.
|
99
|
+
payments.all? { |payment| payment.should be_a Bitex::Payment }
|
94
100
|
end
|
95
|
-
|
101
|
+
|
96
102
|
it 'accepts a callback' do
|
97
103
|
Bitex::Payment
|
98
104
|
.from_callback(callback_params)
|
99
105
|
.should be_a Bitex::Payment
|
100
106
|
end
|
101
|
-
|
107
|
+
|
102
108
|
it 'raises exception if invalid api key' do
|
103
109
|
Bitex::Payment
|
104
|
-
.from_callback(callback_params.merge(
|
110
|
+
.from_callback(callback_params.merge('api_key' => 'bogus'))
|
105
111
|
.should be_nil
|
106
112
|
end
|
107
|
-
|
113
|
+
|
108
114
|
it 'configures store' do
|
109
|
-
pos_params = {
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
115
|
+
pos_params = {
|
116
|
+
'merchant_name' => 'Tierra Buena',
|
117
|
+
'merchant_slug' => 'tierrabuena',
|
118
|
+
'merchant_logo' => 'https://t.co/logo.png',
|
119
|
+
'merchant_keep' => 0
|
114
120
|
}
|
115
|
-
stub_private(:post,
|
116
|
-
|
117
|
-
|
121
|
+
stub_private(:post, '/private/payments/pos_setup', 'pos_setup', pos_params.dup)
|
122
|
+
|
123
|
+
Bitex::Payment.pos_setup!(pos_params).should == pos_params
|
118
124
|
end
|
119
125
|
end
|
data/spec/sell_spec.rb
CHANGED
@@ -2,14 +2,24 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Bitex::Sell do
|
4
4
|
let(:as_json) do
|
5
|
-
[
|
5
|
+
[
|
6
|
+
3, # 0 - API class reference
|
7
|
+
12_345_678, # 1 - id
|
8
|
+
946685400, # 2 - created_at
|
9
|
+
1, # 3 - orderbook
|
10
|
+
100.5, # 4 - quantity
|
11
|
+
201, # 5 - amount
|
12
|
+
0.05, # 6 - fee
|
13
|
+
2, # 7 - price
|
14
|
+
123 # 8 - ask_id
|
15
|
+
]
|
6
16
|
end
|
7
|
-
|
17
|
+
|
8
18
|
it_behaves_like 'API class'
|
9
|
-
it_behaves_like 'API class with a
|
19
|
+
it_behaves_like 'API class with a orderbook'
|
10
20
|
it_behaves_like 'JSON deserializable match'
|
11
21
|
|
12
|
-
it
|
22
|
+
it 'sets the ask id' do
|
13
23
|
thing = subject.class.from_json(as_json).ask_id
|
14
24
|
thing.should == 123
|
15
25
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,27 +2,28 @@ require 'bundler/setup'
|
|
2
2
|
Bundler.setup
|
3
3
|
|
4
4
|
require 'bitex'
|
5
|
+
require 'byebug'
|
5
6
|
require 'webmock/rspec'
|
6
7
|
require 'shoulda/matchers'
|
7
8
|
require 'timecop'
|
8
9
|
|
9
|
-
Dir[File.expand_path(
|
10
|
+
Dir[File.expand_path('support/**/*.rb', __dir__)].each { |f| require f }
|
10
11
|
|
11
12
|
RSpec.configure do |config|
|
12
13
|
config.include RequestStubs
|
13
14
|
|
14
15
|
config.mock_with :rspec do |mocks|
|
15
16
|
mocks.yield_receiver_to_any_instance_implementation_blocks = true
|
16
|
-
mocks.syntax = [
|
17
|
+
mocks.syntax = %i[expect should]
|
17
18
|
end
|
19
|
+
|
18
20
|
config.expect_with :rspec do |c|
|
19
|
-
c.syntax = [
|
21
|
+
c.syntax = %i[expect should]
|
20
22
|
end
|
21
|
-
|
23
|
+
|
22
24
|
config.after(:each) do
|
23
25
|
Timecop.return
|
24
26
|
end
|
25
27
|
|
26
|
-
config.order =
|
28
|
+
config.order = 'random'
|
27
29
|
end
|
28
|
-
|
data/spec/specie_deposit_spec.rb
CHANGED
@@ -1,18 +1,24 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Bitex::SpecieDeposit do
|
4
|
-
before :each do
|
4
|
+
before :each do
|
5
5
|
Bitex.api_key = 'valid_api_key'
|
6
6
|
end
|
7
7
|
|
8
8
|
let(:as_json) do
|
9
|
-
[
|
9
|
+
[
|
10
|
+
5, # 0 - API class reference
|
11
|
+
12_345_678, # 1 - id
|
12
|
+
9_466_854, # 2 - created_at
|
13
|
+
1, # 3 - specie { 0 => :btc }
|
14
|
+
100.5 # 4 - quantity
|
15
|
+
]
|
10
16
|
end
|
11
17
|
|
12
18
|
it_behaves_like 'API class'
|
13
19
|
it_behaves_like 'API class with a specie'
|
14
20
|
|
15
|
-
it
|
21
|
+
it 'sets quantity as BigDecimal' do
|
16
22
|
thing = Bitex::SpecieDeposit.from_json(as_json).quantity
|
17
23
|
thing.should be_a BigDecimal
|
18
24
|
thing.should == 100.5
|
@@ -24,7 +30,7 @@ describe Bitex::SpecieDeposit do
|
|
24
30
|
deposit.should be_a Bitex::SpecieDeposit
|
25
31
|
deposit.specie.should == :btc
|
26
32
|
end
|
27
|
-
|
33
|
+
|
28
34
|
it 'lists all btc deposits' do
|
29
35
|
stub_private(:get, '/private/btc/deposits', 'specie_deposits')
|
30
36
|
deposits = Bitex::SpecieDeposit.all(:btc)
|
@@ -1,81 +1,82 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Bitex::SpecieWithdrawal do
|
4
|
-
before :each do
|
4
|
+
before :each do
|
5
5
|
Bitex.api_key = 'valid_api_key'
|
6
6
|
end
|
7
7
|
|
8
8
|
let(:as_json) do
|
9
|
-
[
|
9
|
+
[
|
10
|
+
6, # 0 - API class reference
|
11
|
+
12_345_678, # 1 - id
|
12
|
+
946_685_400, # 2 - created_at
|
13
|
+
1, # 3 - specie { 0 => :btc }
|
14
|
+
100.0, # 4 - quantity
|
15
|
+
1, # 5 - status { 1 => :received, 2 => :pending, 3 => :done, 4 => :cancelled }
|
16
|
+
0, # 6 - reason { 0 => :not_cancelled, 1 => :insufficient_funds, 2 => :destination_invalid }
|
17
|
+
'1helloworld', # 7 - to_address
|
18
|
+
'label', # 8 - label
|
19
|
+
1, # 9 - kyc_profile_id
|
20
|
+
'ABC1' # 10 - transaction_id
|
21
|
+
]
|
10
22
|
end
|
11
23
|
|
12
24
|
it_behaves_like 'API class'
|
13
25
|
it_behaves_like 'API class with a specie'
|
14
26
|
|
15
|
-
it
|
27
|
+
it 'sets quantity as BigDecimal' do
|
16
28
|
thing = Bitex::SpecieWithdrawal.from_json(as_json).quantity
|
17
29
|
thing.should be_a BigDecimal
|
18
30
|
thing.should == 100.0
|
19
31
|
end
|
20
32
|
|
21
|
-
|
22
|
-
2 => :pending,
|
23
|
-
3 => :done,
|
24
|
-
4 => :cancelled,
|
25
|
-
}.each do |code, symbol|
|
33
|
+
Bitex::SpecieWithdrawal.statuses.each do |code, symbol|
|
26
34
|
it "sets status #{code} to #{symbol}" do
|
27
35
|
as_json[5] = code
|
28
36
|
Bitex::SpecieWithdrawal.from_json(as_json).status.should == symbol
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
32
|
-
|
33
|
-
1 => :insufficient_funds,
|
34
|
-
2 => :destination_invalid,
|
35
|
-
}.each do |code, symbol|
|
40
|
+
Bitex::SpecieWithdrawal.reasons.each do |code, symbol|
|
36
41
|
it "sets reason #{code} to #{symbol}" do
|
37
42
|
as_json[6] = code
|
38
43
|
Bitex::SpecieWithdrawal.from_json(as_json).reason.should == symbol
|
39
44
|
end
|
40
45
|
end
|
41
46
|
|
42
|
-
it
|
47
|
+
it 'sets label' do
|
43
48
|
thing = Bitex::SpecieWithdrawal.from_json(as_json).label
|
44
49
|
thing.should == 'label'
|
45
50
|
end
|
46
51
|
|
47
|
-
it
|
52
|
+
it 'sets to_address' do
|
48
53
|
thing = Bitex::SpecieWithdrawal.from_json(as_json).to_address
|
49
|
-
thing.should ==
|
54
|
+
thing.should == '1helloworld'
|
50
55
|
end
|
51
56
|
|
52
|
-
it
|
57
|
+
it 'sets transaction id' do
|
53
58
|
thing = Bitex::SpecieWithdrawal.from_json(as_json).transaction_id
|
54
|
-
thing.should ==
|
59
|
+
thing.should == 'ABC1'
|
55
60
|
end
|
56
61
|
|
57
|
-
it
|
62
|
+
it 'sets the kyc profile id' do
|
58
63
|
Bitex::SpecieWithdrawal.from_json(as_json).kyc_profile_id.should == 1
|
59
64
|
end
|
60
65
|
|
61
66
|
it 'creates a new withdrawal' do
|
62
|
-
stub_private(:post,
|
63
|
-
address: '1ADDR',
|
64
|
-
amount: 110,
|
65
|
-
label: 'thelabel',
|
66
|
-
})
|
67
|
+
stub_private(:post, '/private/btc/withdrawals', 'specie_withdrawal', address: '1ADDR', amount: 110, label: 'thelabel')
|
67
68
|
withdrawal = Bitex::SpecieWithdrawal.create!(:btc, '1ADDR', 110, 'thelabel')
|
68
69
|
withdrawal.should be_a Bitex::SpecieWithdrawal
|
69
70
|
withdrawal.status.should == :received
|
70
71
|
end
|
71
|
-
|
72
|
+
|
72
73
|
it 'finds a single usd deposit' do
|
73
74
|
stub_private(:get, '/private/btc/withdrawals/1', 'specie_withdrawal')
|
74
75
|
deposit = Bitex::SpecieWithdrawal.find(:btc, 1)
|
75
76
|
deposit.should be_a Bitex::SpecieWithdrawal
|
76
77
|
deposit.status.should == :received
|
77
78
|
end
|
78
|
-
|
79
|
+
|
79
80
|
it 'lists all usd deposits' do
|
80
81
|
stub_private(:get, '/private/btc/withdrawals', 'specie_withdrawals')
|
81
82
|
deposits = Bitex::SpecieWithdrawal.all(:btc)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
shared_examples_for 'API class' do
|
2
2
|
it 'stores the unique id' do
|
3
|
-
as_json[1] =
|
4
|
-
subject.class.from_json(as_json).id.should ==
|
3
|
+
as_json[1] = 12_345_678
|
4
|
+
subject.class.from_json(as_json).id.should == 12_345_678
|
5
5
|
end
|
6
6
|
|
7
7
|
it 'makes creation times into Time' do
|
@@ -9,16 +9,23 @@ shared_examples_for 'API class' do
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
shared_examples_for 'API class with a orderbook' do
|
13
|
+
it 'makes orderbook 1 into btc_usd' do
|
14
|
+
as_json[3] = 1
|
15
|
+
subject.class.from_json(as_json).orderbook.should == :btc_usd
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'makes specie 5 into btc_ars' do
|
19
|
+
as_json[3] = 5
|
20
|
+
subject.class.from_json(as_json).orderbook.should == :btc_ars
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
12
24
|
shared_examples_for 'API class with a specie' do
|
13
25
|
it 'makes specie 1 into btc' do
|
14
26
|
as_json[3] = 1
|
15
27
|
subject.class.from_json(as_json).specie.should == :btc
|
16
28
|
end
|
17
|
-
|
18
|
-
it 'makes specie 2 into ltc' do
|
19
|
-
as_json[3] = 2
|
20
|
-
subject.class.from_json(as_json).specie.should == :ltc
|
21
|
-
end
|
22
29
|
end
|
23
30
|
|
24
31
|
shared_examples_for 'JSON deserializable match' do
|
@@ -32,35 +39,26 @@ shared_examples_for 'JSON deserializable match' do
|
|
32
39
|
end
|
33
40
|
|
34
41
|
shared_examples_for 'JSON deserializable order' do
|
35
|
-
it
|
42
|
+
it 'sets price as BigDecimal' do
|
36
43
|
thing = subject.class.from_json(as_json).price
|
37
44
|
thing.should be_a BigDecimal
|
38
|
-
thing.should ==
|
45
|
+
thing.should == 1_000.0
|
39
46
|
end
|
40
|
-
|
41
|
-
{ 1 => :received,
|
42
|
-
2 => :executing,
|
43
|
-
3 => :cancelling,
|
44
|
-
4 => :cancelled,
|
45
|
-
5 => :completed,
|
46
|
-
}.each do |code, symbol|
|
47
|
+
|
48
|
+
{ 1 => :received, 2 => :executing, 3 => :cancelling, 4 => :cancelled, 5 => :completed }.each do |code, symbol|
|
47
49
|
it "sets status #{code} to #{symbol}" do
|
48
50
|
as_json[7] = code
|
49
51
|
subject.class.from_json(as_json).status.should == symbol
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
53
|
-
{ 0 => :not_cancelled,
|
54
|
-
1 => :not_enough_funds,
|
55
|
-
2 => :user_cancelled,
|
56
|
-
3 => :system_cancelled,
|
57
|
-
}.each do |code, symbol|
|
55
|
+
{ 0 => :not_cancelled, 1 => :not_enough_funds, 2 => :user_cancelled, 3 => :system_cancelled }.each do |code, symbol|
|
58
56
|
it "sets reason #{code} to #{symbol}" do
|
59
57
|
as_json[8] = code
|
60
58
|
subject.class.from_json(as_json).reason.should == symbol
|
61
59
|
end
|
62
60
|
end
|
63
|
-
|
61
|
+
|
64
62
|
it 'sets the issuer' do
|
65
63
|
as_json[10] = 'User#22'
|
66
64
|
subject.class.from_json(as_json).issuer.should == 'User#22'
|