cbx 0.1.1 → 0.1.2
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/README.md +43 -11
- data/cbx.gemspec +6 -6
- data/lib/cbx.rb +34 -19
- data/lib/cbx/feed.rb +8 -10
- data/lib/cbx/market_data.rb +7 -4
- data/lib/cbx/pagination.rb +5 -4
- data/lib/cbx/trading.rb +43 -10
- data/lib/cbx/version.rb +1 -1
- metadata +3 -4
- data/lib/cbx/cbx_signature_maker.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02f394328c79650fe7c8400394ea033c0b09e4fa
|
4
|
+
data.tar.gz: e5d07d4b718c506b61c4e8ddc8c49003734f8cbd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cea5747f231581dce6afcba92bd87660910a762a76109965523adb4440fc0756e4d294facc9436250d4f3d9a7f564b560ba3e070fc34d9d383a11c3ba0111981
|
7
|
+
data.tar.gz: 7d2c645cad6473339bfb2a580f581d4dcb07e60afdfba88bc158c7fe016091a4d32cf5661d596656b1b6efde912f228868537ee85fe1c414a868c0d663cb2602
|
data/README.md
CHANGED
@@ -13,13 +13,11 @@ allows for unauthenticated access to Market Data and the WebSocket feed.
|
|
13
13
|
|
14
14
|
Create an account at https://exchange.coinbase.com to get started.
|
15
15
|
|
16
|
-
### NOTE - As a launch promo, there are [no Coinbase Exchange trading fees](http://blog.coinbase.com/post/109202118547/coinbase-launches-first-regulated-bitcoin-exchange) through the end of March.
|
17
|
-
|
18
16
|
## Installation
|
19
17
|
|
20
18
|
Include this in your gemfile for latest version from git:
|
21
19
|
|
22
|
-
```gem 'cbx', :git=> 'git://github.com/mikerodrigues/cbx.git'```
|
20
|
+
```gem 'cbx', :git => 'git://github.com/mikerodrigues/cbx.git'```
|
23
21
|
|
24
22
|
or from Rubygems, usually not far behind git master:
|
25
23
|
|
@@ -35,21 +33,44 @@ cbe = CBX.new
|
|
35
33
|
|
36
34
|
# List products
|
37
35
|
cbe.products
|
38
|
-
=> [{"id"=>"BTC-USD",
|
36
|
+
=> [{"id"=>"BTC-USD",
|
37
|
+
"base_currency"=>"BTC",
|
38
|
+
"quote_currency"=>"USD",
|
39
|
+
"base_min_size"=>0.01,
|
40
|
+
"base_max_size"=>10000,
|
41
|
+
"quote_increment"=>0.01,
|
42
|
+
"display_name"=>"BTC/USD"}]
|
39
43
|
|
40
44
|
# Get product order book at level 1, 2, or 3, (Defaults to level: 1, product_id "BTC-USD")
|
41
|
-
cbe.
|
42
|
-
=> {"sequence"=>29349454,
|
45
|
+
cbe.orderbook(1, 'BTC-USD')
|
46
|
+
=> {"sequence"=>29349454,
|
47
|
+
"bids"=>[["285.22000000","0.34800000", 3]],
|
48
|
+
"asks"=>[["285.33000000", "0.28930000", 4]]}
|
43
49
|
|
44
50
|
# Product tickers (defaults to 'BTC-USD')
|
45
51
|
cbe.ticker("BTC-USD")
|
46
|
-
=> {"trade_id"=>125681,
|
52
|
+
=> {"trade_id"=>125681,
|
53
|
+
"price"=>"226.20000000",
|
54
|
+
"size"=>"0.01570000",
|
55
|
+
"time"=>"2015-02-08T04:46:17.352746Z"}
|
47
56
|
|
48
57
|
# Product trades (defaults to 'BTC-USD')
|
49
58
|
cbe.trades('BTC-USD')
|
50
|
-
=> [{"time"=>"2015-03-15 04:43:48.7943+00"
|
51
|
-
|
52
|
-
|
59
|
+
=> [{"time"=>"2015-03-15 04:43:48.7943+00"
|
60
|
+
"trade_id"=>774500
|
61
|
+
"price"=>"285.44000000"
|
62
|
+
"size"=>"0.01000000"
|
63
|
+
"side"=>"sell"}
|
64
|
+
{"time"=>"2015-03-15 04:42:54.432661+00"
|
65
|
+
"trade_id"=>774499
|
66
|
+
"price"=>"285.47000000"
|
67
|
+
"size"=>"0.05340000"
|
68
|
+
"side"=>"sell"},
|
69
|
+
{"time"=>"2015-03-15 04:42:54.432306+00"
|
70
|
+
"trade_id"=>774498
|
71
|
+
"price"=>"285.45000000"
|
72
|
+
"size"=>"0.09100000"
|
73
|
+
"side"=>"sell"}]
|
53
74
|
|
54
75
|
|
55
76
|
# For authenticated access:
|
@@ -57,7 +78,18 @@ cbe = CBX.new API_KEY, API_SECRET, API_PASSPHRASE
|
|
57
78
|
|
58
79
|
# List accounts
|
59
80
|
cbe.accounts
|
60
|
-
=> [{"id"=>"000ea663...",
|
81
|
+
=> [{"id"=>"000ea663...",
|
82
|
+
"currency"=>"USD",
|
83
|
+
"balance"=>"90.0000114750000000",
|
84
|
+
"hold"=>"0.0000000000000000",
|
85
|
+
"available"=>"0.9000114750000000",
|
86
|
+
"profile_id"=>"4409df27..."},
|
87
|
+
{"id"=>"8bfe...",
|
88
|
+
"currency"=>"BTC",
|
89
|
+
"balance"=>"9.4426882700000000",
|
90
|
+
"hold"=>"0.0000000000000000",
|
91
|
+
"available"=>"5.4426882700000000",
|
92
|
+
"profile_id"=>"a8f2d8..."}]
|
61
93
|
|
62
94
|
# List orders
|
63
95
|
cbe.orders
|
data/cbx.gemspec
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'cbx'
|
3
|
-
s.version = '0.1.
|
4
|
-
s.date =
|
5
|
-
s.summary =
|
6
|
-
s.description =
|
7
|
-
s.authors = [
|
3
|
+
s.version = '0.1.2'
|
4
|
+
s.date = Date.today.to_s
|
5
|
+
s.summary = 'Ruby wrapper for the Coinbase Exchange API'
|
6
|
+
s.description = 'A complete interface to the Coinbase Exchange trading API.'
|
7
|
+
s.authors = ['Michael Rodrigues', 'Dan Silver']
|
8
8
|
s.email = ['mikebrodrigues@gmail.com', 'dannysilver3@gmail.com']
|
9
9
|
s.files = Dir.glob('{bin,config,lib,test,doc}/**/*') + ['cbx.gemspec']
|
10
10
|
s.extra_rdoc_files = ['README.md']
|
11
11
|
s.license = 'MIT'
|
12
12
|
s.homepage = 'https://github.com/mikerodrigues/cbx'
|
13
|
-
s.metadata = {
|
13
|
+
s.metadata = { 'parent_project_homepage' => 'https://github.com/dan-silver/coinbase_exchange' }
|
14
14
|
s.add_runtime_dependency 'unirest', '~> 1.1', '>= 1.1.2'
|
15
15
|
s.add_runtime_dependency 'websocket-client-simple'
|
16
16
|
end
|
data/lib/cbx.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'unirest'
|
2
|
-
require
|
2
|
+
require 'base64'
|
3
3
|
require 'openssl'
|
4
4
|
require 'json'
|
5
5
|
require 'websocket-client-simple'
|
@@ -7,36 +7,51 @@ require 'cbx/feed'
|
|
7
7
|
require 'cbx/pagination'
|
8
8
|
require 'cbx/trading'
|
9
9
|
require 'cbx/market_data'
|
10
|
-
require 'cbx/cbx_signature_maker'
|
11
10
|
require 'cbx/version'
|
12
11
|
|
12
|
+
# A CBX object exposes all of the functionality of the API through methods that
|
13
|
+
# return JSON objects.
|
14
|
+
#
|
13
15
|
class CBX
|
14
16
|
include MarketData
|
15
|
-
attr_reader :authenticated
|
16
17
|
|
17
18
|
API_URL = 'https://api.exchange.coinbase.com/'
|
18
19
|
|
19
|
-
def initialize(key=nil, secret=nil, passphrase=nil)
|
20
|
+
def initialize(key = nil, secret = nil, passphrase = nil)
|
20
21
|
if key && secret && passphrase
|
21
22
|
@key = key
|
22
23
|
@secret = secret
|
23
24
|
@passphrase = passphrase
|
24
|
-
@coinbaseExchange = CBXSignatureMaker.new(key, secret, passphrase)
|
25
25
|
@authenticated = true
|
26
26
|
extend Trading
|
27
|
-
else
|
27
|
+
else
|
28
28
|
@authenticated = false
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
32
|
+
def authenticated?
|
33
|
+
@authenticated
|
34
|
+
end
|
35
|
+
|
36
|
+
def sign(request_url = '', body = '', timestamp = nil, method = 'GET')
|
37
|
+
body = body.to_json if body.is_a?(Hash)
|
38
|
+
timestamp = Time.now.to_i unless timestamp
|
39
|
+
|
40
|
+
what = "#{timestamp}#{method.upcase}#{request_url}#{body}"
|
41
|
+
# create a sha256 hmac with the secret
|
42
|
+
secret = Base64.decode64(@secret)
|
43
|
+
hash = OpenSSL::HMAC.digest('sha256', secret, what)
|
44
|
+
Base64.strict_encode64(hash)
|
45
|
+
end
|
46
|
+
|
47
|
+
def request(method, uri, json = nil)
|
33
48
|
params = json.to_json if json
|
34
|
-
if authenticated
|
49
|
+
if authenticated?
|
35
50
|
headers = {
|
36
|
-
'CB-ACCESS-SIGN'=>
|
37
|
-
'CB-ACCESS-TIMESTAMP'=> Time.now.to_i,
|
38
|
-
'CB-ACCESS-KEY'=> @key,
|
39
|
-
'CB-ACCESS-PASSPHRASE'=> @passphrase,
|
51
|
+
'CB-ACCESS-SIGN' => sign('/' + uri, params, nil, method),
|
52
|
+
'CB-ACCESS-TIMESTAMP' => Time.now.to_i,
|
53
|
+
'CB-ACCESS-KEY' => @key,
|
54
|
+
'CB-ACCESS-PASSPHRASE' => @passphrase,
|
40
55
|
'Content-Type' => 'application/json'
|
41
56
|
}
|
42
57
|
else
|
@@ -44,25 +59,25 @@ class CBX
|
|
44
59
|
end
|
45
60
|
|
46
61
|
if method == :get
|
47
|
-
r=Unirest.get(API_URL + uri, headers: headers)
|
62
|
+
r = Unirest.get(API_URL + uri, headers: headers)
|
48
63
|
elsif method == :post
|
49
|
-
r=Unirest.post(API_URL + uri, headers: headers, parameters: params)
|
64
|
+
r = Unirest.post(API_URL + uri, headers: headers, parameters: params)
|
50
65
|
elsif method == :delete
|
51
|
-
r=Unirest.delete(API_URL + uri, headers: headers, parameters: params)
|
66
|
+
r = Unirest.delete(API_URL + uri, headers: headers, parameters: params)
|
52
67
|
end
|
53
68
|
yield r.body if block_given?
|
54
|
-
|
69
|
+
r.body
|
55
70
|
end
|
56
71
|
|
57
|
-
def get(uri, json=nil, &block)
|
72
|
+
def get(uri, json = nil, &block)
|
58
73
|
request(:get, uri, json, &block)
|
59
74
|
end
|
60
75
|
|
61
|
-
def post(uri, json=nil, &block)
|
76
|
+
def post(uri, json = nil, &block)
|
62
77
|
request(:post, uri, json, &block)
|
63
78
|
end
|
64
79
|
|
65
|
-
def delete(uri, json=nil, &block)
|
80
|
+
def delete(uri, json = nil, &block)
|
66
81
|
request(:delete, uri, json, &block)
|
67
82
|
end
|
68
83
|
end
|
data/lib/cbx/feed.rb
CHANGED
@@ -1,30 +1,28 @@
|
|
1
1
|
class CBX
|
2
|
+
# Provides an interface to the Coinbase Exchange WebSocket feed.
|
3
|
+
#
|
2
4
|
class Feed
|
3
5
|
API_URL = 'wss://ws-feed.exchange.coinbase.com'
|
4
|
-
|
5
|
-
|
6
|
+
SUBSCRIPTION_REQUEST = { 'type' => 'subscribe', 'product_id' => 'BTC-USD' }
|
7
|
+
def initialize(on_message, on_close = nil, on_error = nil)
|
6
8
|
ws = WebSocket::Client::Simple.connect API_URL
|
7
9
|
@ws = ws
|
8
10
|
ws.on :message do |event|
|
9
11
|
msg = JSON.parse event.data
|
10
|
-
on_message.call(msg)
|
12
|
+
on_message.call(msg)
|
11
13
|
end
|
12
14
|
|
13
15
|
ws.on :open do
|
14
|
-
ws.send
|
16
|
+
ws.send SUBSCRIPTION_REQUEST.to_json
|
15
17
|
end
|
16
18
|
|
17
19
|
ws.on :close do |e|
|
18
|
-
|
19
|
-
on_close.call(e)
|
20
|
-
end
|
20
|
+
on_close && on_close.call(e)
|
21
21
|
exit 1
|
22
22
|
end
|
23
23
|
|
24
24
|
ws.on :error do |e|
|
25
|
-
|
26
|
-
on_error.call(e)
|
27
|
-
end
|
25
|
+
on_error && on_error.call(e)
|
28
26
|
end
|
29
27
|
end
|
30
28
|
|
data/lib/cbx/market_data.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
class CBX
|
2
|
+
# Provides an interface to the Market Data section of the Coinbase Exchange
|
3
|
+
# API.
|
4
|
+
#
|
2
5
|
module MarketData
|
3
6
|
include ::CBX::Pagination
|
4
7
|
|
@@ -6,19 +9,19 @@ class CBX
|
|
6
9
|
get('products', nil, &block)
|
7
10
|
end
|
8
11
|
|
9
|
-
def orderbook(level='1', product_id='BTC-USD', &block)
|
12
|
+
def orderbook(level = '1', product_id = 'BTC-USD', &block)
|
10
13
|
get('products/' + product_id + '/book?level=' + String(level), nil, &block)
|
11
14
|
end
|
12
15
|
|
13
|
-
def ticker(product_id='BTC-USD', &block)
|
16
|
+
def ticker(product_id = 'BTC-USD', &block)
|
14
17
|
get('products/' + product_id + '/ticker', nil, &block)
|
15
18
|
end
|
16
19
|
|
17
|
-
def trades(product_id='BTC-USD', &block)
|
20
|
+
def trades(product_id = 'BTC-USD', &block)
|
18
21
|
get('products/' + product_id + '/trades', nil, &block)
|
19
22
|
end
|
20
23
|
|
21
|
-
def candles(
|
24
|
+
def candles(product_id = 'BTC-USD', &block)
|
22
25
|
get('products/' + product_id + '/candles', nil, &block)
|
23
26
|
end
|
24
27
|
|
data/lib/cbx/pagination.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
class CBX
|
2
|
+
# Handles constructing the pagination portion of a URL.
|
3
|
+
#
|
2
4
|
module Pagination
|
3
5
|
private
|
4
6
|
|
5
7
|
def paginate(hash)
|
6
|
-
string
|
7
|
-
|
8
|
-
string << "
|
8
|
+
hash.keys.each.with_index.reduce('?') do |string, (key, index)|
|
9
|
+
index > 0 ? string << '&' : ''
|
10
|
+
string << "#{key}=#{hash.fetch(key)}"
|
9
11
|
end
|
10
|
-
return string.sub(/^&/, '?')
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
data/lib/cbx/trading.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
class CBX
|
2
|
+
# Provides an interface to the Trading section of the Coinbase Exchange API.
|
3
|
+
#
|
2
4
|
module Trading
|
3
5
|
include ::CBX::Pagination
|
4
|
-
|
5
6
|
# Account methods
|
6
7
|
#
|
7
|
-
def accounts(account_id=nil, &block)
|
8
|
-
if account_id.nil?
|
8
|
+
def accounts(account_id = nil, &block)
|
9
|
+
if account_id.nil?
|
9
10
|
get('accounts', nil, &block)
|
10
11
|
else
|
11
12
|
get('accounts/' + account_id.to_s, nil, &block)
|
@@ -26,8 +27,8 @@ class CBX
|
|
26
27
|
get('orders' + paginate(pagination), nil, &block)
|
27
28
|
end
|
28
29
|
|
29
|
-
def order(order_id=nil, &block)
|
30
|
-
if order_id.nil?
|
30
|
+
def order(order_id = nil, &block)
|
31
|
+
if order_id.nil?
|
31
32
|
get('orders', nil, &block)
|
32
33
|
else
|
33
34
|
get('orders/' + order_id.to_s, nil, &block)
|
@@ -38,20 +39,35 @@ class CBX
|
|
38
39
|
delete('orders/' + order_id.to_s, nil, &block)
|
39
40
|
end
|
40
41
|
|
41
|
-
def place_order(size, price, side, product_id='BTC-USD', &block)
|
42
|
-
order = {
|
42
|
+
def place_order(size, price, side, product_id = 'BTC-USD', &block)
|
43
|
+
order = {
|
44
|
+
'size' => size,
|
45
|
+
'price' => price,
|
46
|
+
'side' => side,
|
47
|
+
'product_id' => product_id
|
48
|
+
}
|
43
49
|
post('orders', order, &block)
|
44
50
|
end
|
45
51
|
|
46
|
-
#
|
52
|
+
# Deposit funds into your Exchange account from a Coinbase wallet.
|
47
53
|
#
|
48
54
|
def deposit(amount, coinbase_account_id, &block)
|
49
|
-
order = {
|
55
|
+
order = {
|
56
|
+
'type' => 'deposit',
|
57
|
+
'amount' => amount,
|
58
|
+
'coinbase_account_id' => coinbase_account_id
|
59
|
+
}
|
50
60
|
post('orders', order, &block)
|
51
61
|
end
|
52
62
|
|
63
|
+
# Withdraw funds to your Coinbase wallet.
|
64
|
+
#
|
53
65
|
def withdraw(amount, coinbase_account_id, &block)
|
54
|
-
order = {
|
66
|
+
order = {
|
67
|
+
'type' => 'withdraw',
|
68
|
+
'amount' => amount,
|
69
|
+
'coinbase_account_id' => coinbase_account_id
|
70
|
+
}
|
55
71
|
post('orders', order, &block)
|
56
72
|
end
|
57
73
|
|
@@ -60,5 +76,22 @@ class CBX
|
|
60
76
|
def fills(pagination = {}, &block)
|
61
77
|
get('fills' + paginate(pagination), nil, &block)
|
62
78
|
end
|
79
|
+
|
80
|
+
# Create a report
|
81
|
+
#
|
82
|
+
def create_report(start_date = nil, end_date = nil, type = 'fill', &block)
|
83
|
+
params = {
|
84
|
+
'type' => type,
|
85
|
+
'start_date' => start_date,
|
86
|
+
'end_date' => end_date
|
87
|
+
}
|
88
|
+
post('reports', params, &block)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Get info about a report
|
92
|
+
#
|
93
|
+
def report_info(report_id, &block)
|
94
|
+
get('reports/' + report_id)
|
95
|
+
end
|
63
96
|
end
|
64
97
|
end
|
data/lib/cbx/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cbx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Rodrigues
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-05-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: unirest
|
@@ -57,7 +57,6 @@ files:
|
|
57
57
|
- README.md
|
58
58
|
- cbx.gemspec
|
59
59
|
- lib/cbx.rb
|
60
|
-
- lib/cbx/cbx_signature_maker.rb
|
61
60
|
- lib/cbx/feed.rb
|
62
61
|
- lib/cbx/market_data.rb
|
63
62
|
- lib/cbx/pagination.rb
|
@@ -84,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
83
|
version: '0'
|
85
84
|
requirements: []
|
86
85
|
rubyforge_project:
|
87
|
-
rubygems_version: 2.
|
86
|
+
rubygems_version: 2.2.2
|
88
87
|
signing_key:
|
89
88
|
specification_version: 4
|
90
89
|
summary: Ruby wrapper for the Coinbase Exchange API
|
@@ -1,18 +0,0 @@
|
|
1
|
-
class CBXSignatureMaker
|
2
|
-
def initialize(key, secret, passphrase)
|
3
|
-
@key = key
|
4
|
-
@secret = secret
|
5
|
-
@passphrase = passphrase
|
6
|
-
end
|
7
|
-
|
8
|
-
def signature(request_url='', body='', timestamp=nil, method='GET')
|
9
|
-
body = body.to_json if body.is_a?(Hash)
|
10
|
-
timestamp = Time.now.to_i if !timestamp
|
11
|
-
|
12
|
-
what = "#{timestamp}#{method.upcase}#{request_url}#{body}";
|
13
|
-
# create a sha256 hmac with the secret
|
14
|
-
secret = Base64.decode64(@secret)
|
15
|
-
hash = OpenSSL::HMAC.digest('sha256', secret, what)
|
16
|
-
Base64.strict_encode64(hash)
|
17
|
-
end
|
18
|
-
end
|