bitpay-client 2.0.1 → 2.2.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.
@@ -5,11 +5,6 @@ describe BitPay::KeyUtils do
5
5
 
6
6
 
7
7
  describe '.get_local_private_key' do
8
- it "should get the key from the ENV['PRIV_KEY'] variable" do
9
- stub_const('ENV', {'BITPAY_PEM' => PEM})
10
- expect(key_utils.get_local_pem_file).to eq(PEM)
11
- end
12
-
13
8
  it 'should get the key from ~/.bitpay/bitpay.pem if env variable is not set' do
14
9
  allow(File).to receive(:read).with(BitPay::PRIVATE_KEY_PATH) {PEM}
15
10
  expect(key_utils.get_local_pem_file).to eq(PEM)
@@ -17,17 +12,6 @@ describe BitPay::KeyUtils do
17
12
 
18
13
  end
19
14
 
20
- describe '.generate_pem' do
21
- it 'should write a new key to ~/.bitpay/bitpay.pem' do
22
- file = class_double("File").as_stubbed_const
23
- fileutils = class_double("FileUtils").as_stubbed_const
24
- allow(fileutils).to receive(:mkdir_p).with(BitPay::BITPAY_CREDENTIALS_DIR).and_return(nil)
25
- expect(file).to receive(:open).with(BitPay::PRIVATE_KEY_PATH, 'w')
26
- key_utils.generate_pem
27
- end
28
-
29
- end
30
-
31
15
  describe '.retrieve_or_generate_pem' do
32
16
  it 'should write a new key to ~/.bitpay/bitpay.pem if there is no existing file' do
33
17
  file = class_double("File").as_stubbed_const
@@ -37,51 +21,6 @@ describe BitPay::KeyUtils do
37
21
  expect(file).to receive(:open).with(BitPay::PRIVATE_KEY_PATH, 'w')
38
22
  key_utils.retrieve_or_generate_pem
39
23
  end
40
-
41
- it 'should retrieve the pem if there is an existing file' do
42
- file = class_double("File").as_stubbed_const
43
- fileutils = class_double("FileUtils").as_stubbed_const
44
- allow(fileutils).to receive(:mkdir_p).with(BitPay::BITPAY_CREDENTIALS_DIR).and_return(nil)
45
- expect(file).to receive(:open).with(BitPay::PRIVATE_KEY_PATH, 'w')
46
- key_utils.generate_pem
47
- end
48
- end
49
-
50
- describe '.get_public_key_from_pem' do
51
- it 'should generate the right public key' do
52
- expect(key_utils.get_public_key_from_pem(PEM)).to eq(PUB_KEY)
53
- end
54
-
55
- it 'should get pem from the env if none is passed' do
56
- expect(key_utils.get_public_key_from_pem(PEM)).to eq(PUB_KEY)
57
- end
58
-
59
- end
60
-
61
- describe '.generate_sin_from_pem' do
62
- let(:pem){PEM}
63
- let(:sin){CLIENT_ID}
64
-
65
- it 'will return the right sin for the right pem' do
66
- expect(key_utils.generate_sin_from_pem(pem)).to eq sin
67
- end
68
-
69
- it 'will retrieve the locally stored PEM if one is not provided' do
70
- allow(File).to receive(:read).with(BitPay::PRIVATE_KEY_PATH) {PEM}
71
- expect(key_utils.generate_sin_from_pem(nil)).to eq sin
72
- end
73
-
74
24
  end
75
25
 
76
- context "errors when priv_key is not provided" do
77
- before :each do
78
- allow(File).to receive(:read).with(BitPay::PRIVATE_KEY_PATH) {nil}
79
- end
80
-
81
- it 'will not retrieve public key' do
82
- expect{key_utils.get_public_key_from_pem(nil)}.to raise_error(BitPay::BitPayError)
83
- end
84
-
85
- end
86
-
87
26
  end
data/spec/spec_helper.rb CHANGED
@@ -3,12 +3,10 @@ require 'pry'
3
3
  require 'capybara/rspec'
4
4
  require 'capybara/poltergeist'
5
5
 
6
- require File.join File.dirname(__FILE__), '..', 'lib', 'bitpay', 'client.rb'
7
- require File.join File.dirname(__FILE__), '..', 'lib', 'bitpay', 'key_utils.rb'
8
6
  require File.join File.dirname(__FILE__), '..', 'lib', 'bitpay.rb'
7
+
9
8
  require_relative '../config/constants.rb'
10
9
  require_relative '../config/capybara.rb'
11
-
12
10
  #
13
11
  ## Test Variables
14
12
  #
@@ -22,4 +20,17 @@ RSpec.configure do |config|
22
20
  config.before :each do |example|
23
21
  WebMock.allow_net_connect! if example.metadata[:type] == :feature
24
22
  end
23
+
24
+ config.before :all do |example|
25
+ FileUtils.mkdir_p(BitPay::BITPAY_CREDENTIALS_DIR)
26
+ end
27
+ end
28
+
29
+ def an_illegal_claim_code
30
+ legal_map = [*'A'..'Z'] + [*'a'..'z'] + [*0..9]
31
+ first_length = rand(6)
32
+ short_code = (0..first_length).map{legal_map.sample}.join
33
+ second_length = [*8..25].sample
34
+ long_code = [*8..25].sample.times.inject([]){|arr| arr << legal_map.sample}.join
35
+ [nil, short_code, long_code].sample
25
36
  end
metadata CHANGED
@@ -1,57 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitpay-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bitpay, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-02 00:00:00.000000000 Z
11
+ date: 2015-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bitpay-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.1'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: json
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - ">="
31
+ - - "~>"
18
32
  - !ruby/object:Gem::Version
19
- version: '0'
33
+ version: 1.8.1
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - ">="
38
+ - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: '0'
40
+ version: 1.8.1
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rack
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - ">="
45
+ - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '0'
47
+ version: 1.5.2
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - ">="
52
+ - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: '0'
54
+ version: 1.5.2
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: ecdsa
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - ">="
59
+ - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '0'
61
+ version: 1.2.0
48
62
  type: :runtime
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - ">="
66
+ - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '0'
68
+ version: 1.2.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: commander
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -70,142 +84,156 @@ dependencies:
70
84
  name: rake
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ">="
87
+ - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '0'
89
+ version: 10.3.2
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ">="
94
+ - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '0'
96
+ version: 10.3.2
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: webmock
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - ">="
101
+ - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: '0'
103
+ version: 1.18.0
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - ">="
108
+ - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: '0'
110
+ version: 1.18.0
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: pry
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - ">="
115
+ - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: '0'
117
+ version: 0.10.1
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - ">="
122
+ - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: '0'
124
+ version: 0.10.1
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: pry-byebug
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
- - - ">="
129
+ - - "~>"
116
130
  - !ruby/object:Gem::Version
117
- version: '0'
131
+ version: 2.0.0
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
- - - ">="
136
+ - - "~>"
123
137
  - !ruby/object:Gem::Version
124
- version: '0'
138
+ version: 2.0.0
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: pry-rescue
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
- - - ">="
143
+ - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: '0'
145
+ version: 1.4.1
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
- - - ">="
150
+ - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: '0'
152
+ version: 1.4.1
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: capybara
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
- - - ">="
157
+ - - "~>"
144
158
  - !ruby/object:Gem::Version
145
- version: '0'
159
+ version: 2.4.3
146
160
  type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
- - - ">="
164
+ - - "~>"
151
165
  - !ruby/object:Gem::Version
152
- version: '0'
166
+ version: 2.4.3
167
+ - !ruby/object:Gem::Dependency
168
+ name: cucumber
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 1.3.17
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 1.3.17
153
181
  - !ruby/object:Gem::Dependency
154
182
  name: poltergeist
155
183
  requirement: !ruby/object:Gem::Requirement
156
184
  requirements:
157
- - - ">="
185
+ - - "~>"
158
186
  - !ruby/object:Gem::Version
159
- version: '0'
187
+ version: 1.5.1
160
188
  type: :development
161
189
  prerelease: false
162
190
  version_requirements: !ruby/object:Gem::Requirement
163
191
  requirements:
164
- - - ">="
192
+ - - "~>"
165
193
  - !ruby/object:Gem::Version
166
- version: '0'
194
+ version: 1.5.1
167
195
  - !ruby/object:Gem::Dependency
168
196
  name: airborne
169
197
  requirement: !ruby/object:Gem::Requirement
170
198
  requirements:
171
- - - ">="
199
+ - - "~>"
172
200
  - !ruby/object:Gem::Version
173
- version: '0'
201
+ version: 0.0.20
174
202
  type: :development
175
203
  prerelease: false
176
204
  version_requirements: !ruby/object:Gem::Requirement
177
205
  requirements:
178
- - - ">="
206
+ - - "~>"
179
207
  - !ruby/object:Gem::Version
180
- version: '0'
208
+ version: 0.0.20
181
209
  - !ruby/object:Gem::Dependency
182
210
  name: rspec
183
211
  requirement: !ruby/object:Gem::Requirement
184
212
  requirements:
185
- - - ">="
213
+ - - "~>"
186
214
  - !ruby/object:Gem::Version
187
- version: '0'
215
+ version: 3.1.0
188
216
  type: :development
189
217
  prerelease: false
190
218
  version_requirements: !ruby/object:Gem::Requirement
191
219
  requirements:
192
- - - ">="
220
+ - - "~>"
193
221
  - !ruby/object:Gem::Version
194
- version: '0'
222
+ version: 3.1.0
195
223
  - !ruby/object:Gem::Dependency
196
224
  name: mongo
197
225
  requirement: !ruby/object:Gem::Requirement
198
226
  requirements:
199
- - - ">="
227
+ - - "~>"
200
228
  - !ruby/object:Gem::Version
201
- version: '0'
229
+ version: 1.11.1
202
230
  type: :development
203
231
  prerelease: false
204
232
  version_requirements: !ruby/object:Gem::Requirement
205
233
  requirements:
206
- - - ">="
234
+ - - "~>"
207
235
  - !ruby/object:Gem::Version
208
- version: '0'
236
+ version: 1.11.1
209
237
  description: Powerful, flexible, lightweight, thread-safe interface to the BitPay
210
238
  developers API
211
239
  email: info@bitpay.com
@@ -224,13 +252,18 @@ files:
224
252
  - bitpay-client.gemspec
225
253
  - config/capybara.rb
226
254
  - config/constants.rb
255
+ - features/creating_invoices.feature
256
+ - features/pairing.feature
257
+ - features/retrieving_invoices.feature
258
+ - features/step_definitions/invoice_steps.rb
259
+ - features/step_definitions/keygen_steps.rb
260
+ - features/step_definitions/step_helpers.rb
227
261
  - lib/bitpay.rb
228
262
  - lib/bitpay/cacert.pem
229
263
  - lib/bitpay/cli.rb
230
- - lib/bitpay/client.rb
231
- - lib/bitpay/key_utils.rb
264
+ - lib/bitpay/cli_client.rb
265
+ - lib/bitpay/cli_key_utils.rb
232
266
  - lib/bitpay/version.rb
233
- - lib/harness.rb
234
267
  - spec/client_spec.rb
235
268
  - spec/features/pair_spec.rb
236
269
  - spec/features/pos_spec.rb
@@ -263,4 +296,3 @@ signing_key:
263
296
  specification_version: 4
264
297
  summary: Official ruby client library for the BitPay API
265
298
  test_files: []
266
- has_rdoc:
data/lib/bitpay/client.rb DELETED
@@ -1,160 +0,0 @@
1
- # license Copyright 2011-2014 BitPay, Inc., MIT License
2
- # see http://opensource.org/licenses/MIT
3
- # or https://github.com/bitpay/php-bitpay-client/blob/master/LICENSE
4
-
5
- require 'uri'
6
- require 'net/https'
7
- require 'json'
8
-
9
- require_relative 'key_utils'
10
-
11
- module BitPay
12
- # This class is used to instantiate a BitPay Client object. It is expected to be thread safe.
13
- #
14
- class Client
15
-
16
-
17
- # @return [Client]
18
- # @example
19
- # # Create a client with a pem file created by the bitpay client:
20
- # client = BitPay::Client.new
21
- def initialize(opts={})
22
- @pem = opts[:pem] || ENV['BITPAY_PEM'] || KeyUtils.retrieve_or_generate_pem
23
- @key = KeyUtils.create_key @pem
24
- @priv_key = KeyUtils.get_private_key @key
25
- @pub_key = KeyUtils.get_public_key @key
26
- @client_id = KeyUtils.generate_sin_from_pem @pem
27
- @uri = URI.parse opts[:api_uri] || API_URI
28
- @user_agent = opts[:user_agent] || USER_AGENT
29
- @https = Net::HTTP.new @uri.host, @uri.port
30
- @https.use_ssl = true
31
- @https.ca_file = CA_FILE
32
- @tokens = {}
33
-
34
- # Option to disable certificate validation in extraordinary circumstance. NOT recommended for production use
35
- @https.verify_mode = opts[:insecure] == true ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
36
-
37
- # Option to enable http request debugging
38
- @https.set_debug_output($stdout) if opts[:debug] == true
39
-
40
- end
41
-
42
- def pair_pos_client(claimCode)
43
- response = set_pos_token(claimCode)
44
- get_token 'pos'
45
- response
46
- end
47
-
48
- def create_invoice(id:, price:, currency:, facade: 'pos', params:{})
49
- params.merge!({price: price, currency: currency})
50
- response = send_request("POST", "invoices", facade: facade, params: params)
51
- response["data"]
52
- end
53
-
54
- def get_public_invoice(id:)
55
- request = Net::HTTP::Get.new("/invoices/#{id}")
56
- response = process_request(request)
57
- response["data"]
58
- end
59
-
60
- ## Generates REST request to api endpoint
61
- def send_request(verb, path, facade: 'merchant', params: {}, token: nil)
62
- token ||= get_token(facade)
63
-
64
- # Verb-specific logic
65
- case verb.upcase
66
- when "GET"
67
- urlpath = '/' + path + '?nonce=' + KeyUtils.nonce + '&token=' + token
68
- request = Net::HTTP::Get.new urlpath
69
- request['X-Signature'] = KeyUtils.sign(@uri.to_s + urlpath, @priv_key)
70
-
71
- when "PUT"
72
-
73
- when "POST" # Requires a GUID
74
-
75
- urlpath = '/' + path
76
- request = Net::HTTP::Post.new urlpath
77
- params[:token] = token
78
- params[:nonce] = KeyUtils.nonce
79
- params[:guid] = SecureRandom.uuid
80
- params[:id] = @client_id
81
- request.body = params.to_json
82
- request['X-Signature'] = KeyUtils.sign(@uri.to_s + urlpath + request.body, @priv_key)
83
-
84
- when "DELETE"
85
-
86
- raise(BitPayError, "Invalid HTTP verb: #{verb.upcase}")
87
- end
88
-
89
- # Build request headers and submit
90
- request['X-Identity'] = @pub_key
91
-
92
- response = process_request(request)
93
- end
94
-
95
- ##### PRIVATE METHODS #####
96
- private
97
-
98
- ## Processes HTTP Request and returns parsed response
99
- # Otherwise throws error
100
- #
101
- def process_request(request)
102
-
103
- request['User-Agent'] = @user_agent
104
- request['Content-Type'] = 'application/json'
105
- request['X-BitPay-Plugin-Info'] = 'Rubylib' + VERSION
106
-
107
- response = @https.request request
108
-
109
- if response.kind_of? Net::HTTPSuccess
110
- return JSON.parse(response.body)
111
- elsif JSON.parse(response.body)["error"]
112
- raise(BitPayError, "#{response.code}: #{JSON.parse(response.body)['error']}")
113
- else
114
- raise BitPayError, "#{response.code}: #{JSON.parse(response.body)}"
115
- end
116
-
117
- end
118
-
119
- ## Requests token by appending nonce and signing URL
120
- # Returns a hash of available tokens
121
- #
122
- def load_tokens
123
-
124
- urlpath = '/tokens?nonce=' + KeyUtils.nonce
125
-
126
- request = Net::HTTP::Get.new(urlpath)
127
- request['x-identity'] = @pub_key
128
- request['x-signature'] = KeyUtils.sign(@uri.to_s + urlpath, @priv_key)
129
-
130
- response = process_request(request)
131
-
132
- token_array = response["data"] || {}
133
-
134
- tokens = {}
135
- token_array.each do |t|
136
- tokens[t.keys.first] = t.values.first
137
- end
138
-
139
- @tokens = tokens
140
- return tokens
141
-
142
- end
143
-
144
- ## Retrieves specified token from hash, otherwise tries to refresh @tokens and retry
145
- def set_pos_token(claim_code)
146
- params = {pairingCode: claim_code}
147
- urlpath = '/tokens'
148
- request = Net::HTTP::Post.new urlpath
149
- params[:guid] = SecureRandom.uuid
150
- params[:id] = @client_id
151
- request.body = params.to_json
152
- process_request(request)
153
- end
154
-
155
- def get_token(facade)
156
- token = @tokens[facade] || load_tokens[facade] || raise(BitPayError, "Not authorized for facade: #{facade}")
157
- end
158
-
159
- end
160
- end