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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31c39b5d8c6657a3cfc9a059fb853bd1d9d84d58
4
- data.tar.gz: 6dfa0c3f9b5ffaa5e4d6426052468f8ea9a9eb0a
3
+ metadata.gz: 02f394328c79650fe7c8400394ea033c0b09e4fa
4
+ data.tar.gz: e5d07d4b718c506b61c4e8ddc8c49003734f8cbd
5
5
  SHA512:
6
- metadata.gz: fceeb97882bb299241430ff18b6b0e6fbe2a7b75329b79a085794d54bfff724817d2aa91768a5a797c25b115d68e733afbe8840f7a0b32468f2e7ee986fecb12
7
- data.tar.gz: cb0d5ca770d8fec2bcb20876896c331e877cf73c6e87d458daef07c781822d517986896acc02d1d980183347b90e4c5cb05e9df8bff7a29b83624374f8ed7c6b
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", "base_currency"=>"BTC", "quote_currency"=>"USD", "base_min_size"=>0.01, "base_max_size"=>10000, "quote_increment"=>0.01, "display_name"=>"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.book(1, 'BTC-USD')
42
- => {"sequence"=>29349454, "bids"=>[["285.22000000", "0.34800000", 3]], "asks"=>[["285.33000000", "0.28930000", 4]]}
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, "price"=>"226.20000000", "size"=>"0.01570000", "time"=>"2015-02-08T04:46:17.352746Z"}
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", "trade_id"=>774500, "price"=>"285.44000000", "size"=>"0.01000000", "side"=>"sell"},
51
- {"time"=>"2015-03-15 04:42:54.432661+00", "trade_id"=>774499, "price"=>"285.47000000", "size"=>"0.05340000", "side"=>"sell"},
52
- {"time"=>"2015-03-15 04:42:54.432306+00", "trade_id"=>774498, "price"=>"285.45000000", "size"=>"0.09100000", "side"=>"sell"}]
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...", "currency"=>"USD", "balance"=>"90.0000114750000000", "hold"=>"0.0000000000000000", "available"=>"0.9000114750000000", "profile_id"=>"4409df27..."}, {"id"=>"8bfe", "currency"=>"BTC", "balance"=>"9.4426882700000000", "hold"=>"0.0000000000000000", "available"=>"5.4426882700000000", "profile_id"=>"a8f2d8..."}]
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
@@ -1,16 +1,16 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'cbx'
3
- s.version = '0.1.1'
4
- s.date = '2015-03-16'
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"]
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 = { "parent_project_homepage" => "https://github.com/dan-silver/coinbase_exchange"}
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 "base64"
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 request(method, uri, json=nil)
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'=> @coinbaseExchange.signature('/'+uri, params, nil, method),
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
- return r.body
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
@@ -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
- def initialize(on_message, on_close=nil, on_error=nil)
5
- subscription_request = { "type" => "subscribe", "product_id" => "BTC-USD" }
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 subscription_request.to_json
16
+ ws.send SUBSCRIPTION_REQUEST.to_json
15
17
  end
16
18
 
17
19
  ws.on :close do |e|
18
- if on_close
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
- if on_error
26
- on_error.call(e)
27
- end
25
+ on_error && on_error.call(e)
28
26
  end
29
27
  end
30
28
 
@@ -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(level='1', product_id='BTC-USD', &block)
24
+ def candles(product_id = 'BTC-USD', &block)
22
25
  get('products/' + product_id + '/candles', nil, &block)
23
26
  end
24
27
 
@@ -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
- hash.keys.each do |key|
8
- string << "&#{key}=#{hash.fetch(key)}"
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
@@ -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? then
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? then
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 = { 'size' => size, 'price' => price, 'side' => side, 'product_id' => product_id}
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
- # Transfer funds methods
52
+ # Deposit funds into your Exchange account from a Coinbase wallet.
47
53
  #
48
54
  def deposit(amount, coinbase_account_id, &block)
49
- order = { 'type' => 'deposit', 'amount' => amount, 'coinbase_account_id' => coinbase_account_id }
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 = { 'type' => 'withdraw', 'amount' => amount, 'coinbase_account_id' => coinbase_account_id }
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
@@ -1,3 +1,3 @@
1
1
  class CBX
2
- VERSION="0.1.1"
2
+ VERSION = '0.1.2'
3
3
  end
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.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-03-16 00:00:00.000000000 Z
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.4.5
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