bitstamp 0.2.8 → 0.3.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.
@@ -0,0 +1 @@
1
+ bitstamp
@@ -0,0 +1 @@
1
+ ruby-1.9.3
data/Gemfile CHANGED
@@ -6,9 +6,8 @@ source "http://rubygems.org"
6
6
  # gem "activesupport", ">= 2.3.5"
7
7
  gem "activemodel", ">= 3.1"
8
8
  gem "activesupport", ">= 3.1"
9
-
10
9
  gem 'curb', '> 0.8.1'
11
-
10
+ gem "ruby-hmac", "0.4.0"
12
11
 
13
12
  # Add dependencies to develop your gem here.
14
13
  # Include everything needed to run rake, tests, features, etc.
@@ -18,3 +17,8 @@ group :development do
18
17
  gem "bundler", "~> 1.3.5"
19
18
  gem "jeweler", "~> 1.8.4"
20
19
  end
20
+
21
+ group :test do
22
+ gem "vcr", "2.6.0"
23
+ gem "webmock", "1.13.0"
24
+ end
@@ -10,8 +10,11 @@ GEM
10
10
  multi_json (~> 1.3)
11
11
  thread_safe (~> 0.1)
12
12
  tzinfo (~> 0.3.33)
13
+ addressable (2.3.5)
13
14
  atomic (1.1.7)
14
15
  builder (3.1.4)
16
+ crack (0.4.1)
17
+ safe_yaml (~> 0.9.0)
15
18
  curb (0.8.3)
16
19
  diff-lcs (1.2.4)
17
20
  git (1.2.5)
@@ -35,9 +38,15 @@ GEM
35
38
  rspec-expectations (2.13.0)
36
39
  diff-lcs (>= 1.1.3, < 2.0)
37
40
  rspec-mocks (2.13.1)
41
+ ruby-hmac (0.4.0)
42
+ safe_yaml (0.9.7)
38
43
  thread_safe (0.1.0)
39
44
  atomic
40
45
  tzinfo (0.3.37)
46
+ vcr (2.6.0)
47
+ webmock (1.13.0)
48
+ addressable (>= 2.2.7)
49
+ crack (>= 0.3.2)
41
50
 
42
51
  PLATFORMS
43
52
  ruby
@@ -50,3 +59,6 @@ DEPENDENCIES
50
59
  jeweler (~> 1.8.4)
51
60
  rdoc (~> 3.12)
52
61
  rspec
62
+ ruby-hmac (= 0.4.0)
63
+ vcr (= 2.6.0)
64
+ webmock (= 1.13.0)
data/README.md CHANGED
@@ -7,17 +7,22 @@ Feel free to fork, modify & redistribute under the MIT license.
7
7
  Add this line to your application's Gemfile:
8
8
 
9
9
  gem 'bitstamp'
10
+
11
+ ## Create API Key
12
+
13
+ More info at: [https://www.bitstamp.net/article/api-key-implementation/](https://www.bitstamp.net/article/api-key-implementation/)
10
14
 
11
15
  ## Setup
12
16
 
13
17
  ```ruby
14
18
  Bitstamp.setup do |config|
15
- config.key = YOUR_BITSTAMP_USERNAME
16
- config.secret = YOUR_BITSTAMP_PASSWORD
19
+ config.key = YOUR_API_KEY
20
+ config.secret = YOUR_API_SECRET
21
+ config.client_id = YOUR_BITSTAMP_USERNAME
17
22
  end
18
23
  ```
19
24
 
20
- If you fail to set your `key` or `secret` a `MissingConfigExecption`
25
+ If you fail to set your `key` or `secret` or `client_id` a `MissingConfigExeception`
21
26
  will be raised.
22
27
 
23
28
  ## Bitstamp ticker
@@ -71,14 +76,12 @@ Bitstamp.user_transactions.all
71
76
 
72
77
  # Tests
73
78
 
74
- If you'd like to run the tests you need to create a yaml file in the
75
- root of the gem `bit_stamp_details.yml` which holds your authentication
76
- details for Bitstamp.
79
+ If you'd like to run the tests you need to set the following environment variables:
77
80
 
78
- ```yaml
79
- bitstamp:
80
- id: 'bitstamp id'
81
- password: 'bitstamp password'
81
+ ```
82
+ export BITSTAMP_KEY=xxx
83
+ export BITSTAMP_SECRET=yyy
84
+ export BITSTAMP_CLIENT_ID=zzz
82
85
  ```
83
86
 
84
87
  ## Contributing
data/Rakefile CHANGED
@@ -25,14 +25,18 @@ Jeweler::Tasks.new do |gem|
25
25
  end
26
26
  Jeweler::RubygemsDotOrgTasks.new
27
27
 
28
- require 'rake/testtask'
29
- Rake::TestTask.new(:test) do |test|
30
- test.libs << 'lib' << 'test'
31
- test.pattern = 'test/**/test_*.rb'
32
- test.verbose = true
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
33
32
  end
34
33
 
35
- task :default => :test
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
36
40
 
37
41
  require 'rdoc/task'
38
42
  Rake::RDocTask.new do |rdoc|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.8
1
+ 0.3.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{bitstamp}
8
- s.version = "0.2.8"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = [%q{Jeffrey Wilcke}]
12
- s.date = %q{2013-08-27}
12
+ s.date = %q{2013-11-19}
13
13
  s.description = %q{Ruby API for use with bitstamp.}
14
14
  s.email = %q{stygeo@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -18,6 +18,8 @@ Gem::Specification.new do |s|
18
18
  ]
19
19
  s.files = [
20
20
  ".rspec",
21
+ ".ruby-gemset",
22
+ ".ruby-version",
21
23
  "Gemfile",
22
24
  "Gemfile.lock",
23
25
  "LICENSE.txt",
@@ -35,8 +37,18 @@ Gem::Specification.new do |s|
35
37
  "lib/bitstamp/transactions.rb",
36
38
  "spec/bitstamp_spec.rb",
37
39
  "spec/collection_spec.rb",
40
+ "spec/fixtures/vcr_cassettes/bitstamp/balance.yml",
41
+ "spec/fixtures/vcr_cassettes/bitstamp/order_book.yml",
42
+ "spec/fixtures/vcr_cassettes/bitstamp/orders/all.yml",
43
+ "spec/fixtures/vcr_cassettes/bitstamp/orders/buy.yml",
44
+ "spec/fixtures/vcr_cassettes/bitstamp/orders/sell/failure.yml",
45
+ "spec/fixtures/vcr_cassettes/bitstamp/ticker.yml",
46
+ "spec/fixtures/vcr_cassettes/bitstamp/transactions.yml",
47
+ "spec/fixtures/vcr_cassettes/bitstamp/user_transactions/all.yml",
38
48
  "spec/orders_spec.rb",
39
49
  "spec/spec_helper.rb",
50
+ "spec/support/bitstamp_setup.rb",
51
+ "spec/support/vcr.rb",
40
52
  "spec/transactions_spec.rb"
41
53
  ]
42
54
  s.homepage = %q{http://github.com/kojnapp/bitstamp}
@@ -52,6 +64,7 @@ Gem::Specification.new do |s|
52
64
  s.add_runtime_dependency(%q<activemodel>, [">= 3.1"])
53
65
  s.add_runtime_dependency(%q<activesupport>, [">= 3.1"])
54
66
  s.add_runtime_dependency(%q<curb>, ["> 0.8.1"])
67
+ s.add_runtime_dependency(%q<ruby-hmac>, ["= 0.4.0"])
55
68
  s.add_development_dependency(%q<rspec>, [">= 0"])
56
69
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
57
70
  s.add_development_dependency(%q<bundler>, ["~> 1.3.5"])
@@ -60,6 +73,7 @@ Gem::Specification.new do |s|
60
73
  s.add_dependency(%q<activemodel>, [">= 3.1"])
61
74
  s.add_dependency(%q<activesupport>, [">= 3.1"])
62
75
  s.add_dependency(%q<curb>, ["> 0.8.1"])
76
+ s.add_dependency(%q<ruby-hmac>, ["= 0.4.0"])
63
77
  s.add_dependency(%q<rspec>, [">= 0"])
64
78
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
65
79
  s.add_dependency(%q<bundler>, ["~> 1.3.5"])
@@ -69,6 +83,7 @@ Gem::Specification.new do |s|
69
83
  s.add_dependency(%q<activemodel>, [">= 3.1"])
70
84
  s.add_dependency(%q<activesupport>, [">= 3.1"])
71
85
  s.add_dependency(%q<curb>, ["> 0.8.1"])
86
+ s.add_dependency(%q<ruby-hmac>, ["= 0.4.0"])
72
87
  s.add_dependency(%q<rspec>, [">= 0"])
73
88
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
74
89
  s.add_dependency(%q<bundler>, ["~> 1.3.5"])
@@ -2,6 +2,7 @@ require 'active_support/core_ext'
2
2
  require 'active_support/inflector'
3
3
  require 'active_model'
4
4
  require 'curb'
5
+ require 'hmac-sha2'
5
6
 
6
7
  require 'bitstamp/net'
7
8
  require 'bitstamp/helper'
@@ -20,6 +21,9 @@ module Bitstamp
20
21
 
21
22
  # Bitstamp secret
22
23
  mattr_accessor :secret
24
+
25
+ # Bitstamp client ID
26
+ mattr_accessor :client_id
23
27
 
24
28
  # Currency
25
29
  mattr_accessor :currency
@@ -37,6 +41,10 @@ module Bitstamp
37
41
  @@transactions ||= Bitstamp::UserTransactions.new
38
42
  end
39
43
 
44
+ def self.transactions
45
+ return Bitstamp::Transactions.from_api
46
+ end
47
+
40
48
  def self.balance
41
49
  self.sanity_check!
42
50
 
@@ -48,18 +56,22 @@ module Bitstamp
48
56
  end
49
57
 
50
58
  def self.order_book
51
- return JSON.parse Bitstamp::Net.post('/order_book/').body_str
59
+ return JSON.parse Bitstamp::Net.get('/order_book/').body_str
52
60
  end
53
61
 
54
62
  def self.setup
55
63
  yield self
56
64
  end
65
+
66
+ def self.configured?
67
+ self.key && self.secret && self.client_id
68
+ end
57
69
 
58
70
  def self.sanity_check!
59
- unless self.key || self.secret
60
- raise MissingConfigExecption.new("Bitstamp Gem not properly configured")
71
+ unless configured?
72
+ raise MissingConfigExeception.new("Bitstamp Gem not properly configured")
61
73
  end
62
74
  end
63
75
 
64
- class MissingConfigExecption<Exception;end;
76
+ class MissingConfigExeception<Exception;end;
65
77
  end
@@ -9,8 +9,11 @@ module Bitstamp
9
9
 
10
10
  c = Curl::Easy.new(self.to_uri(path))
11
11
 
12
- options[:user] = Bitstamp.key
13
- options[:password] = Bitstamp.secret
12
+ if Bitstamp.configured?
13
+ options[:key] = Bitstamp.key
14
+ options[:nonce] = Time.now.to_i.to_s
15
+ options[:signature] = HMAC::SHA256.hexdigest(Bitstamp.secret, options[:nonce]+Bitstamp.client_id+options[:key]).upcase
16
+ end
14
17
 
15
18
  c.post_body = options.to_query
16
19
 
@@ -22,6 +22,16 @@ module Bitstamp
22
22
  end
23
23
 
24
24
  class UserTransaction < Bitstamp::Model
25
- attr_accessor :datetime, :id, :type, :usd, :btc, :fee, :order_id, :btc_usd
25
+ attr_accessor :datetime, :id, :type, :usd, :btc, :fee, :order_id, :btc_usd, :nonce
26
+ end
27
+
28
+ # adding in methods to pull the last public trades list
29
+ class Transactions < Bitstamp::Model
30
+ attr_accessor :date, :price, :tid, :amount
31
+
32
+ def self.from_api
33
+ Bitstamp::Helper.parse_objects! Bitstamp::Net::get("/transactions").body_str, self
34
+ end
35
+
26
36
  end
27
37
  end
@@ -2,42 +2,56 @@ require 'spec_helper'
2
2
 
3
3
  describe Bitstamp do
4
4
 
5
- it 'should raise if not properly configured' do
6
- -> { Bitstamp.sanity_check! }.should raise_error
7
- end
8
-
9
- it 'should not raise if properly configured' do
10
- Bitstamp.setup do |config|
11
- config.key = 'test'
12
- config.secret = 'test'
5
+ describe :sanity_check! do
6
+ context 'not properly configured' do
7
+ it { -> { Bitstamp.sanity_check! }.should raise_error }
8
+ end
9
+ context 'properly configured' do
10
+ before {
11
+ Bitstamp.setup do |config|
12
+ config.key = 'test'
13
+ config.secret = 'test'
14
+ config.client_id = 'test'
15
+ end
16
+ }
17
+ it { -> { Bitstamp.sanity_check! }.should_not raise_error }
13
18
  end
14
-
15
- -> { Bitstamp.sanity_check! }.should_not raise_error
16
- end
17
-
18
- it 'should have a orders helper method' do
19
- Bitstamp.should respond_to :orders
20
19
  end
21
20
 
22
- it 'should have a ticker helper method' do
23
- Bitstamp.ticker.should be_kind_of Bitstamp::Ticker
21
+ describe :orders do
22
+ it { should respond_to :orders }
24
23
  end
25
24
 
26
- it 'should list information about your balance' do
27
- read_bitstamp_yaml
28
-
29
- Bitstamp.balance.should be_kind_of Hash
25
+ describe :ticket, vcr: {cassette_name: 'bitstamp/ticker'} do
26
+ subject { Bitstamp.ticker }
27
+ it { should be_kind_of Bitstamp::Ticker }
28
+ its(:high) { should == "124.90" }
29
+ its(:last) { should == "124.55" }
30
+ its(:timestamp) { should == "1380237724" }
31
+ its(:bid) { should == "124.55" }
32
+ its(:volume) { should == "7766.46908740" }
33
+ its(:low) { should == "123.00" }
34
+ its(:ask) { should == "124.56" }
30
35
  end
31
36
 
32
- it 'should have a order_book method' do
33
- Bitstamp.order_book.should be_kind_of Hash
37
+ describe :balance, vcr: {cassette_name: 'bitstamp/balance'} do
38
+ context "configured" do
39
+ subject { Bitstamp.balance }
40
+ before { setup_bitstamp }
41
+ it { should == {"btc_reserved"=>"0", "fee"=>"0.4000", "btc_available"=>"0", "usd_reserved"=>"1.02", "btc_balance"=>"0", "usd_balance"=>"6953.07", "usd_available"=>"6952.05"} }
42
+ end
43
+ context "not configured" do
44
+ it { expect { Bitstamp.balance }.to raise_exception(Bitstamp::MissingConfigExeception, "Bitstamp Gem not properly configured") }
45
+ end
34
46
  end
35
47
 
36
- it 'should have bids and asks in the order_book' do
37
- order_book = Bitstamp.order_book
38
- order_book.should have_key("asks")
39
- order_book.should have_key("bids")
40
- order_book["asks"].should be_kind_of Array
41
- order_book["bids"].should be_kind_of Array
48
+ describe :order_book, vcr: {cassette_name: 'bitstamp/order_book'} do
49
+ let(:order_book) { Bitstamp.order_book }
50
+ subject { order_book }
51
+ it { should be_kind_of Hash }
52
+ it { should have_key("asks") }
53
+ it { should have_key("bids") }
54
+ it { order_book["asks"].should be_kind_of Array }
55
+ it { order_book["bids"].should be_kind_of Array }
42
56
  end
43
57
  end
@@ -4,21 +4,9 @@ class Bitstamp::Coin < Bitstamp::Model;end
4
4
  class Bitstamp::Coins < Bitstamp::Collection;end
5
5
 
6
6
  describe Bitstamp::Coins do
7
- let(:kojns) { Bitstamp::Coins.new }
8
-
9
- it 'should have a name representing the class his name but not modules' do
10
- kojns.name.should eq 'coin'
11
- end
12
-
13
- it 'module should reflect a singular form' do
14
- kojns.module.should eq "bitstamp/coin"
15
- end
16
-
17
- it 'should have a model' do
18
- kojns.model.should be Bitstamp::Coin
19
- end
20
-
21
- it 'should have an api end point' do
22
- kojns.path.should eq "/api/coins"
23
- end
7
+ subject { Bitstamp::Coins.new }
8
+ its(:name) { should eq 'coin' }
9
+ its(:module) { should eq "bitstamp/coin" }
10
+ its(:model) { should be Bitstamp::Coin }
11
+ its(:path) { should eq "/api/coins" }
24
12
  end
@@ -0,0 +1,63 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://www.bitstamp.net/api/balance/
6
+ body:
7
+ encoding: US-ASCII
8
+ string: key=BITSTAMP_KEY&nonce=1380237671&signature=67768DD1BBDF45203840CC8688847A2DF5D224CA15B3ABDDC804EA251AC12211
9
+ headers: {}
10
+ response:
11
+ status:
12
+ code: 200
13
+ message: !binary |-
14
+ T0s=
15
+ headers:
16
+ !binary "U2VydmVy":
17
+ - !binary |-
18
+ Y2xvdWRmbGFyZS1uZ2lueA==
19
+ !binary "RGF0ZQ==":
20
+ - !binary |-
21
+ VGh1LCAyNiBTZXAgMjAxMyAyMzoyMToxOCBHTVQ=
22
+ !binary "Q29udGVudC1UeXBl":
23
+ - !binary |-
24
+ YXBwbGljYXRpb24vanNvbg==
25
+ !binary "VHJhbnNmZXItRW5jb2Rpbmc=":
26
+ - !binary |-
27
+ Y2h1bmtlZA==
28
+ !binary "Q29ubmVjdGlvbg==":
29
+ - !binary |-
30
+ a2VlcC1hbGl2ZQ==
31
+ !binary "U2V0LUNvb2tpZQ==":
32
+ - !binary |-
33
+ X19jZmR1aWQ9ZDg2ZTkzYTIxNzY5Y2UxZDQzODc2YzQ1N2ZjNTU3ZmNjMTM4
34
+ MDIzNzY3Nzk1ODsgZXhwaXJlcz1Nb24sIDIzLURlYy0yMDE5IDIzOjUwOjAw
35
+ IEdNVDsgcGF0aD0vOyBkb21haW49LmJpdHN0YW1wLm5ldA==
36
+ !binary "Q29udGVudC1MYW5ndWFnZQ==":
37
+ - !binary |-
38
+ ZW4=
39
+ !binary "RXhwaXJlcw==":
40
+ - !binary |-
41
+ VGh1LCAyNiBTZXAgMjAxMyAyMzoyMToxOCBHTVQ=
42
+ !binary "VmFyeQ==":
43
+ - !binary |-
44
+ QWNjZXB0LUxhbmd1YWdl
45
+ !binary "Q2FjaGUtQ29udHJvbA==":
46
+ - !binary |-
47
+ bWF4LWFnZT0w
48
+ !binary "TGFzdC1Nb2RpZmllZA==":
49
+ - !binary |-
50
+ VGh1LCAyNiBTZXAgMjAxMyAyMzoyMToxOCBHTVQ=
51
+ !binary "Q2YtUmF5":
52
+ - !binary |-
53
+ YjQzYjA4ZjM5ZDgwMDk3
54
+ body:
55
+ encoding: ASCII-8BIT
56
+ string: !binary |-
57
+ eyJidGNfcmVzZXJ2ZWQiOiAiMCIsICJmZWUiOiAiMC40MDAwIiwgImJ0Y19h
58
+ dmFpbGFibGUiOiAiMCIsICJ1c2RfcmVzZXJ2ZWQiOiAiMS4wMiIsICJidGNf
59
+ YmFsYW5jZSI6ICIwIiwgInVzZF9iYWxhbmNlIjogIjY5NTMuMDciLCAidXNk
60
+ X2F2YWlsYWJsZSI6ICI2OTUyLjA1In0=
61
+ http_version:
62
+ recorded_at: Thu, 26 Sep 2013 23:21:18 GMT
63
+ recorded_with: VCR 2.6.0