bitstamp-client 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/bitstamp/account_balance.rb +13 -0
- data/lib/bitstamp/client.rb +142 -0
- data/lib/bitstamp/conversion_rates.rb +7 -0
- data/lib/bitstamp/deposit.rb +15 -0
- data/lib/bitstamp/exception.rb +35 -0
- data/lib/bitstamp/order_book.rb +11 -0
- data/lib/bitstamp/orders.rb +71 -0
- data/lib/bitstamp/subaccount_transfer.rb +25 -0
- data/lib/bitstamp/ticker.rb +19 -0
- data/lib/bitstamp/trading_pairs.rb +7 -0
- data/lib/bitstamp/transactions.rb +11 -0
- data/lib/bitstamp/user_transactions.rb +13 -0
- data/lib/bitstamp/version.rb +3 -0
- data/lib/bitstamp/withdrawal.rb +19 -0
- data/lib/bitstamp.rb +2 -0
- metadata +153 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 277a98625be62200060a4f297f2f2bc7bb29afa6
|
4
|
+
data.tar.gz: 709f85f9b64331d4fee44c47bf9b8273ca52a389
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e96ba05efb1ea4eb4b62dff5974060a0cc8bf4e1b118f5f8a3555554f5b3577a184076f1e6366166da5fe6bce6b0c3a5cede411a0e65f03fe62e75d9b8de7ba2
|
7
|
+
data.tar.gz: ff6473e3df8d94e583c35dc327e36ae7d7f02863c72c477e7b2ff48a5bff6f2e042e346a91b7c431b93b71f657d59a537375473fb7e1e1ddc215f341a9feaa86
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Bitstamp
|
2
|
+
module AccountBalance
|
3
|
+
def account_balance(nonce: nil, currency_pair: nil)
|
4
|
+
params = { nonce: nonce }
|
5
|
+
|
6
|
+
if currency_pair == nil
|
7
|
+
call(request_uri('v2', 'balance'), 'POST', params)
|
8
|
+
else
|
9
|
+
call(request_uri('v2', 'balance', currency_pair), 'POST', params)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'json'
|
3
|
+
require 'openssl'
|
4
|
+
require 'typhoeus'
|
5
|
+
|
6
|
+
require_relative './account_balance'
|
7
|
+
require_relative './deposit'
|
8
|
+
require_relative './conversion_rates'
|
9
|
+
require_relative './exception'
|
10
|
+
require_relative './order_book'
|
11
|
+
require_relative './orders'
|
12
|
+
require_relative './subaccount_transfer'
|
13
|
+
require_relative './ticker'
|
14
|
+
require_relative './trading_pairs'
|
15
|
+
require_relative './transactions'
|
16
|
+
require_relative './user_transactions'
|
17
|
+
require_relative './withdrawal'
|
18
|
+
|
19
|
+
module Bitstamp
|
20
|
+
class Client
|
21
|
+
extend Forwardable
|
22
|
+
|
23
|
+
BASE_URI = 'https://www.bitstamp.net/api'
|
24
|
+
|
25
|
+
def initialize(customer_id:, api_key:, secret:)
|
26
|
+
@customer_id = customer_id
|
27
|
+
@api_key = api_key
|
28
|
+
@secret = secret
|
29
|
+
|
30
|
+
@connecttimeout = 1
|
31
|
+
@timeout = 10
|
32
|
+
end
|
33
|
+
|
34
|
+
class << self
|
35
|
+
include ::Bitstamp::ConversionRates
|
36
|
+
include ::Bitstamp::OrderBook
|
37
|
+
include ::Bitstamp::Ticker
|
38
|
+
include ::Bitstamp::TradingPairs
|
39
|
+
include ::Bitstamp::Transactions
|
40
|
+
|
41
|
+
def request_uri(*parts)
|
42
|
+
uri = BASE_URI
|
43
|
+
|
44
|
+
parts.each do |part|
|
45
|
+
uri += "/"
|
46
|
+
uri += part
|
47
|
+
end
|
48
|
+
|
49
|
+
return uri + "/"
|
50
|
+
end
|
51
|
+
|
52
|
+
def call(request_uri, method, body)
|
53
|
+
request_hash = {
|
54
|
+
method: method,
|
55
|
+
body: body,
|
56
|
+
headers: {
|
57
|
+
'User-Agent' => "Bitstamp::Client Ruby v#{::Bitstamp::VERSION}"
|
58
|
+
},
|
59
|
+
connecttimeout: @connecttimeout,
|
60
|
+
timeout: @timeout,
|
61
|
+
}
|
62
|
+
|
63
|
+
request = ::Typhoeus::Request.new(request_uri, request_hash)
|
64
|
+
response = request.run
|
65
|
+
|
66
|
+
return handle_response(response)
|
67
|
+
end
|
68
|
+
|
69
|
+
def handle_response(response)
|
70
|
+
body = JSON.parse(response.body)
|
71
|
+
|
72
|
+
if body.kind_of?(Hash) && body.has_key?('error')
|
73
|
+
raise ::Bitstamp::Exception::ServiceError(body)
|
74
|
+
end
|
75
|
+
|
76
|
+
return body
|
77
|
+
rescue JSON::ParserError
|
78
|
+
raise ::Bitstamp::Exception::InvalidContent.new(response.body)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def_delegators "Bitstamp::Client", :request_uri, :handle_response
|
83
|
+
|
84
|
+
include ::Bitstamp::AccountBalance
|
85
|
+
include ::Bitstamp::Deposit
|
86
|
+
include ::Bitstamp::Orders
|
87
|
+
include ::Bitstamp::SubaccountTransfer
|
88
|
+
include ::Bitstamp::UserTransactions
|
89
|
+
include ::Bitstamp::Withdrawal
|
90
|
+
|
91
|
+
def call(request_uri, method, body)
|
92
|
+
body = params_with_signature(body)
|
93
|
+
|
94
|
+
::Bitstamp::Client.call(request_uri, method, body)
|
95
|
+
end
|
96
|
+
|
97
|
+
def params_with_signature(params = {})
|
98
|
+
if params[:nonce] == nil
|
99
|
+
params[:nonce] = (Time.now.to_f * 1000000).to_i.to_s # Microseconds
|
100
|
+
end
|
101
|
+
|
102
|
+
params[:key] = @api_key
|
103
|
+
params[:signature] = build_signature(params[:nonce])
|
104
|
+
|
105
|
+
return params
|
106
|
+
end
|
107
|
+
|
108
|
+
def build_signature(nonce)
|
109
|
+
message = nonce + @customer_id + @api_key
|
110
|
+
|
111
|
+
return OpenSSL::HMAC.hexdigest("SHA256", @secret, message).upcase
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def run_request(path:, nonce:, request_params: {})
|
117
|
+
body = request_params.merge(
|
118
|
+
{
|
119
|
+
key: key,
|
120
|
+
signature: signature(nonce),
|
121
|
+
nonce: nonce
|
122
|
+
}
|
123
|
+
)
|
124
|
+
|
125
|
+
request_uri = BASE_URI + path
|
126
|
+
|
127
|
+
request_hash = {
|
128
|
+
method: 'POST',
|
129
|
+
body: body
|
130
|
+
}
|
131
|
+
|
132
|
+
request = ::Typhoeus::Request.new(request_uri, request_hash)
|
133
|
+
response = request.run
|
134
|
+
end
|
135
|
+
|
136
|
+
def signature(nonce)
|
137
|
+
message = nonce + @customer_id + @api_key
|
138
|
+
|
139
|
+
return OpenSSL::HMAC.hexdigest("SHA256", @secret, message)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Bitstamp
|
2
|
+
module Deposit
|
3
|
+
def bitcoin_deposit_address(nonce: nil)
|
4
|
+
params = { nonce: nonce }
|
5
|
+
|
6
|
+
call(request_uri('bitcoin_deposit_address'), 'POST', params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def unconfirmed_bitcoin_deposits(nonce: nil)
|
10
|
+
params = { nonce: nonce }
|
11
|
+
|
12
|
+
call(request_uri('unconfirmed_btc'), 'POST', params)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Bitstamp
|
2
|
+
module Exception
|
3
|
+
class ServiceError < StandardError
|
4
|
+
attr_reader :body
|
5
|
+
|
6
|
+
def initialize(body)
|
7
|
+
@body = body
|
8
|
+
end
|
9
|
+
|
10
|
+
def message
|
11
|
+
@body.fetch('error')
|
12
|
+
end
|
13
|
+
|
14
|
+
alias_method :to_s, :message
|
15
|
+
end
|
16
|
+
|
17
|
+
class InvalidContent < StandardError
|
18
|
+
attr_reader :body
|
19
|
+
|
20
|
+
def initialize(body)
|
21
|
+
@body = body
|
22
|
+
end
|
23
|
+
|
24
|
+
def message
|
25
|
+
"Failed to parse body as 'json': '#{@body}'"
|
26
|
+
end
|
27
|
+
|
28
|
+
def inspect
|
29
|
+
"#{self.class.name}: #{message}"
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method :to_s, :message
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Bitstamp
|
2
|
+
module Orders
|
3
|
+
def open_orders(nonce: nil, currency_pair: nil)
|
4
|
+
params = { nonce: nonce }
|
5
|
+
|
6
|
+
if currency_pair == nil
|
7
|
+
call(request_uri('v2', 'open_orders', 'all'), 'POST', params)
|
8
|
+
else
|
9
|
+
call(request_uri('v2', 'open_orders', currency_pair), 'POST', params)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def order_status(nonce: nil, id:)
|
14
|
+
params = { nonce: nonce, id: id }
|
15
|
+
|
16
|
+
call(request_uri('v2', 'order_status'), 'POST', params)
|
17
|
+
end
|
18
|
+
|
19
|
+
def cancel_order(nonce: nil, id:)
|
20
|
+
params = { nonce: nonce, id: id }
|
21
|
+
|
22
|
+
call(request_uri('v2', 'cancel_order'), 'POST', params)
|
23
|
+
end
|
24
|
+
|
25
|
+
def cancel_all_orders(nonce: nil)
|
26
|
+
params = { nonce: nonce }
|
27
|
+
|
28
|
+
call(request_uri('cancel_all_orders'), 'POST', params)
|
29
|
+
end
|
30
|
+
|
31
|
+
def buy_limit_order(nonce: nil, amount:, price:, limit_price:, currency_pair:)
|
32
|
+
params = {
|
33
|
+
nonce: nonce,
|
34
|
+
amount: amount,
|
35
|
+
price: price,
|
36
|
+
limit_price: limit_price
|
37
|
+
}
|
38
|
+
|
39
|
+
call(request_uri('v2', 'buy', currency_pair), 'POST', params)
|
40
|
+
end
|
41
|
+
|
42
|
+
def buy_market_order(nonce: nil, amount:)
|
43
|
+
params = {
|
44
|
+
nonce: nonce,
|
45
|
+
amount: amount,
|
46
|
+
}
|
47
|
+
|
48
|
+
call(request_uri('v2', 'buy', 'market', currency_pair), 'POST', params)
|
49
|
+
end
|
50
|
+
|
51
|
+
def sell_limit_order(nonce: nil, amount:, price:, limit_price:, currency_pair:)
|
52
|
+
params = {
|
53
|
+
nonce: nonce,
|
54
|
+
amount: amount,
|
55
|
+
price: price,
|
56
|
+
limit_price: limit_price
|
57
|
+
}
|
58
|
+
|
59
|
+
call(request_uri('v2', 'sell', currency_pair), 'POST', params)
|
60
|
+
end
|
61
|
+
|
62
|
+
def sell_market_order(nonce: nil, amount:)
|
63
|
+
params = {
|
64
|
+
nonce: nonce,
|
65
|
+
amount: amount,
|
66
|
+
}
|
67
|
+
|
68
|
+
call(request_uri('v2', 'sell', 'market', currency_pair), 'POST', params)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Bitstamp
|
2
|
+
module SubaccountTransfer
|
3
|
+
def transfer_to_main(nonce: nil, amount:, currency:, sub_account:)
|
4
|
+
params = {
|
5
|
+
nonce: nonce,
|
6
|
+
amount: amount,
|
7
|
+
currency: currency,
|
8
|
+
subAccount: sub_account
|
9
|
+
}
|
10
|
+
|
11
|
+
call(request_uri('v2', 'transfer-to-main'), 'POST', params)
|
12
|
+
end
|
13
|
+
|
14
|
+
def transfer_from_main(nonce: nil, amount:, currency:, sub_account:)
|
15
|
+
params = {
|
16
|
+
nonce: nonce,
|
17
|
+
amount: amount,
|
18
|
+
currency: currency,
|
19
|
+
subAccount: sub_account
|
20
|
+
}
|
21
|
+
|
22
|
+
call(request_uri('v2', 'transfer-from-main'), 'POST', params)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bitstamp
|
2
|
+
module Ticker
|
3
|
+
def ticker(currency_pair: nil)
|
4
|
+
if currency_pair == nil
|
5
|
+
return call(request_uri('ticker'), 'GET', nil)
|
6
|
+
else
|
7
|
+
return call(request_uri('v2', 'ticker', currency_pair), 'GET', nil)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def hourly_ticker(currency_pair: nil)
|
12
|
+
if currency_pair == nil
|
13
|
+
return call(request_uri('ticker_hour'), 'GET', nil)
|
14
|
+
else
|
15
|
+
return call(request_uri('v2', 'ticker_hour', currency_pair), 'GET', nil)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Bitstamp
|
2
|
+
module Transactions
|
3
|
+
def transactions(currency_pair: nil)
|
4
|
+
if currency_pair == nil
|
5
|
+
return call(request_uri('transactions'), 'GET', nil)
|
6
|
+
else
|
7
|
+
return call(request_uri('v2', 'transactions', currency_pair, ''), 'GET', nil)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Bitstamp
|
2
|
+
module UserTransactions
|
3
|
+
def user_transactions(nonce: nil, offset: 0, limit: 100, sort: 'desc', currency_pair: nil)
|
4
|
+
params = { nonce: nonce }
|
5
|
+
|
6
|
+
if currency_pair == nil
|
7
|
+
call(request_uri('v2', 'user_transactions'), 'POST', params)
|
8
|
+
else
|
9
|
+
call(request_uri('v2', 'user_transactions', currency_pair), 'POST', params)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bitstamp
|
2
|
+
module Withdrawal
|
3
|
+
def withdrawal_requests(nonce: nil, timedelta: 86400)
|
4
|
+
params = { nonce: nonce, timedelta: timedelta }
|
5
|
+
|
6
|
+
call(request_uri('v2', 'withdrawal-requests'), 'POST', params)
|
7
|
+
end
|
8
|
+
|
9
|
+
def bitcoin_withdrawal(nonce: nil, amount:, address:)
|
10
|
+
params = {
|
11
|
+
nonce: nonce,
|
12
|
+
amount: amount,
|
13
|
+
address: address,
|
14
|
+
}
|
15
|
+
|
16
|
+
call(request_uri('bitcoin_withdrawal'), 'POST', params)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/bitstamp.rb
ADDED
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bitstamp-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tobias Schoknecht
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '12.3'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 12.3.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '12.3'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 12.3.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rspec
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '3.7'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 3.7.0
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '3.7'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 3.7.0
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: builder
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '3.2'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 3.2.3
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.2'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 3.2.3
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: rack-test
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 0.8.2
|
80
|
+
type: :development
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 0.8.2
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: typhoeus
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '1.3'
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.3.0
|
97
|
+
type: :runtime
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.3'
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 1.3.0
|
107
|
+
description: Bitstamp Exchange API Client
|
108
|
+
email:
|
109
|
+
- tobias.schoknecht@gmail.com
|
110
|
+
executables: []
|
111
|
+
extensions: []
|
112
|
+
extra_rdoc_files: []
|
113
|
+
files:
|
114
|
+
- lib/bitstamp.rb
|
115
|
+
- lib/bitstamp/account_balance.rb
|
116
|
+
- lib/bitstamp/client.rb
|
117
|
+
- lib/bitstamp/conversion_rates.rb
|
118
|
+
- lib/bitstamp/deposit.rb
|
119
|
+
- lib/bitstamp/exception.rb
|
120
|
+
- lib/bitstamp/order_book.rb
|
121
|
+
- lib/bitstamp/orders.rb
|
122
|
+
- lib/bitstamp/subaccount_transfer.rb
|
123
|
+
- lib/bitstamp/ticker.rb
|
124
|
+
- lib/bitstamp/trading_pairs.rb
|
125
|
+
- lib/bitstamp/transactions.rb
|
126
|
+
- lib/bitstamp/user_transactions.rb
|
127
|
+
- lib/bitstamp/version.rb
|
128
|
+
- lib/bitstamp/withdrawal.rb
|
129
|
+
homepage: https://github.com/tobischo/bitstamp
|
130
|
+
licenses:
|
131
|
+
- MIT
|
132
|
+
metadata: {}
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 2.6.14
|
150
|
+
signing_key:
|
151
|
+
specification_version: 4
|
152
|
+
summary: Very generic client for REST API with basic error handling
|
153
|
+
test_files: []
|