block_io 1.0.5 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,44 @@
1
+
2
+ describe "Helper.sha256" do
3
+ it "deadbeef" do
4
+ expect(BlockIo::Helper.sha256("deadbeef")).to eq("2baf1f40105d9501fe319a8ec463fdf4325a2a5df445adf3f572f626253678c9")
5
+ end
6
+ end
7
+
8
+ describe "Helper.pinToAesKey" do
9
+ it "deadbeef" do
10
+ expect(BlockIo::Helper.pinToAesKey("deadbeef", false)).to eq([["b87ddac3d84865782a0edbc21b5786d56795dd52bab0fe49270b3726372a83fe"].pack("H*")].pack("m0"))
11
+ end
12
+ end
13
+
14
+ describe "Helper.encrypt" do
15
+ before(:each) do
16
+ @encryption_key = BlockIo::Helper.pinToAesKey("deadbeef")
17
+ @encrypted_data = BlockIo::Helper.encrypt("beadbeef", @encryption_key)
18
+ end
19
+
20
+ it "beadbeef" do
21
+ expect(@encrypted_data).to eq("3wIJtPoC8KO6S7x6LtrN0g==")
22
+ end
23
+
24
+ end
25
+
26
+ describe "Helper.decrypt" do
27
+ before(:each) do
28
+ @encryption_key = BlockIo::Helper.pinToAesKey("deadbeef")
29
+ @bad_encryption_key = BlockIo::Helper.pinToAesKey(SecureRandom.hex(4))
30
+ @encrypted_data = BlockIo::Helper.encrypt("beadbeef", @encryption_key)
31
+ end
32
+
33
+ it "encryption_key" do
34
+ @decrypted_data = BlockIo::Helper.decrypt(@encrypted_data, @encryption_key)
35
+ expect(@decrypted_data).to eq("beadbeef")
36
+ end
37
+
38
+ it "bad_encryption_key" do
39
+ expect{
40
+ BlockIo::Helper.decrypt(@encrypted_data, @bad_encryption_key)
41
+ }.to raise_error(Exception, "Invalid Secret PIN provided.")
42
+ end
43
+
44
+ end
@@ -0,0 +1,61 @@
1
+
2
+ describe "Key.from_wif" do
3
+
4
+ context "L1cq4uDmSKMiViT4DuR8jqJv8AiiSZ9VeJr82yau5nfVQYaAgDdr" do
5
+
6
+ before(:each) do
7
+ @key_any_r = BlockIo::Key.from_wif("L1cq4uDmSKMiViT4DuR8jqJv8AiiSZ9VeJr82yau5nfVQYaAgDdr", false)
8
+ @key_low_r = BlockIo::Key.from_wif("L1cq4uDmSKMiViT4DuR8jqJv8AiiSZ9VeJr82yau5nfVQYaAgDdr")
9
+ end
10
+
11
+ it "match(public_key)" do
12
+ expect(@key_any_r.public_key).to eq("024988bae7e0ade83cb1b6eb0fd81e6161f6657ad5dd91d216fbeab22aea3b61a0")
13
+ expect(@key_low_r.public_key).to eq("024988bae7e0ade83cb1b6eb0fd81e6161f6657ad5dd91d216fbeab22aea3b61a0")
14
+ end
15
+
16
+ it "match(private_key)" do
17
+ expect(@key_any_r.private_key).to eq("833e2256c42b4a41ee0a6ee284c39cf8e1978bc8e878eb7ae87803e22d48caa9")
18
+ expect(@key_low_r.private_key).to eq("833e2256c42b4a41ee0a6ee284c39cf8e1978bc8e878eb7ae87803e22d48caa9")
19
+ end
20
+
21
+ it "sign_without_low_r" do
22
+ expect(@key_any_r.sign("e76f0f78b7e7474f04cc14ad1343e4cc28f450399a79457d1240511a054afd63")).to eq("3045022100aec97f7ad7a9831d583ca157284a68706a6ac4e76d6c9ee33adce6227a40e675022008894fb35020792c01443d399d33ffceb72ac1d410b6dcb9e31dcc71e6c49e92")
23
+ end
24
+
25
+ it "sign_with_low_r" do
26
+ expect(@key_low_r.sign("e76f0f78b7e7474f04cc14ad1343e4cc28f450399a79457d1240511a054afd63")).to eq("3044022061753424b6936ca4cfcc81b883dab55f16d84d3eaf9d5da77c1e25f54fda963802200d3db78e8f5aac62909c2a89ab1b2b413c00c0860926e824f37a19fa140c79f4")
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ describe "Key.from_passphrase" do
33
+
34
+ context "deadbeef" do
35
+
36
+ before(:each) do
37
+ @key_any_r = BlockIo::Key.from_passphrase("deadbeef", false)
38
+ @key_low_r = BlockIo::Key.from_passphrase("deadbeef")
39
+ @data = "e76f0f78b7e7474f04cc14ad1343e4cc28f450399a79457d1240511a054afd63"
40
+ end
41
+
42
+ it "match(public_key)" do
43
+ expect(@key_low_r.public_key).to eq("02953b9dfcec241eec348c12b1db813d3cd5ec9d93923c04d2fa3832208b8c0f84")
44
+ end
45
+
46
+ it "match(private_key)" do
47
+ expect(@key_low_r.private_key).to eq("5f78c33274e43fa9de5659265c1d917e25c03722dcb0b8d27db8d5feaa813953")
48
+ end
49
+
50
+ it "sign_without_low_r" do
51
+ expect(@key_any_r.sign(@data)).to eq("30450221009a68321e071c94e25484e26435639f00d23ef3fbe9c529c3347dc061f562530c0220134d3159098950b81b678f9e3b15e100f5478bb45345d3243df41ae616e70032")
52
+ end
53
+
54
+ it "sign_with_low_r" do
55
+ expect(@key_low_r.sign(@data)).to eq("304402204ac97a4cdad5f842e745e27c3ffbe08b3704900baafab602277a5a196c3a4a3202202bacdf06afaf58032383447a9f3e9a42bfaeabf6dbcf9ab275d8f24171d272cf")
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
@@ -0,0 +1,59 @@
1
+ describe "RFC6979" do
2
+
3
+ context "deadbeef" do
4
+
5
+ before(:each) do
6
+ @key = BlockIo::Key.from_passphrase("deadbeef")
7
+ @data = "e76f0f78b7e7474f04cc14ad1343e4cc28f450399a79457d1240511a054afd63"
8
+ end
9
+
10
+ it "without_extra_entropy" do
11
+ nonce = BlockIo::Key.send(:deterministicGenerateK, [@data].pack("H*"), @key.private_key.to_i(16)).to_s(16)
12
+ expect(nonce).to eq("b13fa787e16b878c9a7815c8b508eb9e6a401432a15f340dd3fcde25e5c494b8")
13
+ end
14
+
15
+ it "with_extra_entropy_1" do
16
+ # Key.deterministicGenerateK([data].pack("H*"), @private_key, counter)
17
+ nonce = BlockIo::Key.send(:deterministicGenerateK, [@data].pack("H*"), @key.private_key.to_i(16), 1).to_s(16)
18
+ expect(nonce).to eq("b69b1e880b537aca72b7235506ba04a676bdd2d663e4e1eb7d8c567f48ab0646")
19
+ end
20
+
21
+ it "with_extra_entropy_2" do
22
+ nonce = BlockIo::Key.send(:deterministicGenerateK, [@data].pack("H*"), @key.private_key.to_i(16), 2).to_s(16)
23
+ expect(nonce).to eq("e0b71534de1cf4f5019b0bc4e10d655d0e625b531e4911daf44cf2d065dcedd3")
24
+ end
25
+
26
+ it "with_extra_entropy_3" do
27
+ nonce = BlockIo::Key.send(:deterministicGenerateK, [@data].pack("H*"), @key.private_key.to_i(16), 3).to_s(16)
28
+ expect(nonce).to eq("faed0d38abb73e5f909cc989d967e3c4abb873ad177fe72bc35dc8ba42452fc0")
29
+ end
30
+
31
+ it "with_extra_entropy_4" do
32
+ nonce = BlockIo::Key.send(:deterministicGenerateK, [@data].pack("H*"), @key.private_key.to_i(16), 4).to_s(16)
33
+ expect(nonce).to eq("96db9090ce1eb13ae91fb15129838d73ba382cfeb48f6d1cf1a1296a3ce94c49")
34
+ end
35
+
36
+ it "with_extra_entropy_16" do
37
+ nonce = BlockIo::Key.send(:deterministicGenerateK, [@data].pack("H*"), @key.private_key.to_i(16),16).to_s(16)
38
+ expect(nonce).to eq("d4985f135357c3885c55c3dff3e9f98bccb0264fb348259f8160660e41f5ce65")
39
+ end
40
+
41
+ it "with_extra_entropy_17" do
42
+ nonce = BlockIo::Key.send(:deterministicGenerateK, [@data].pack("H*"), @key.private_key.to_i(16),17).to_s(16)
43
+ expect(nonce).to eq("1affb74f0ecffa9b1996670ba47c6366dd76b484f7af977e4cd32d16c5545e0d")
44
+ end
45
+
46
+ it "with_extra_entropy_255" do
47
+ nonce = BlockIo::Key.send(:deterministicGenerateK, [@data].pack("H*"), @key.private_key.to_i(16),255).to_s(16)
48
+ expect(nonce).to eq("d72decc0d526ece67755680556b8700ccfdd2fd7beba87f709ec4037f7a0771f")
49
+ end
50
+
51
+ it "with_extra_entropy_256" do
52
+ nonce = BlockIo::Key.send(:deterministicGenerateK, [@data].pack("H*"), @key.private_key.to_i(16),256).to_s(16)
53
+ expect(nonce).to eq("5ff357395dc803f98967276a49a0802cc5b44b52db395242926bd2c4a6ac062f")
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+
@@ -0,0 +1,5 @@
1
+ require_relative '../lib/block_io'
2
+
3
+ require 'webmock/rspec'
4
+
5
+ WebMock.disable_net_connect!
@@ -0,0 +1,90 @@
1
+
2
+ describe "Oj.load_file" do
3
+
4
+ context "withdraw_response.json" do
5
+
6
+ before(:each) do
7
+ @data = Oj.load_file("spec/data/withdraw_response.json")
8
+ end
9
+
10
+ it "valid?(data.reference_id)" do
11
+ expect(@data["data"]["reference_id"]).to eq("25cd8b0ad5cf8987c99e16921149cdb0680b1c1360276b4d652904958b19a8bd")
12
+ end
13
+
14
+ end
15
+
16
+ context "sign_and_finalize_withdraw_request.json" do
17
+
18
+ before(:each) do
19
+ @data = Oj.load_file("spec/data/sign_and_finalize_withdrawal_request.json")
20
+ end
21
+
22
+ it ".key?(signature_data)" do
23
+ expect(@data.key?("signature_data")).to eq(true)
24
+ end
25
+
26
+ it "signature_data.is_a?(String)" do
27
+ expect(@data["signature_data"].is_a?(String)).to eq(true)
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+
34
+ describe "Helper.signData" do
35
+
36
+ context "bad_key" do
37
+
38
+ before(:each) do
39
+ @bad_key = BlockIo::Key.new(nil, false)
40
+ @data = Oj.load_file("spec/data/withdraw_response.json")
41
+ @signatures_added = BlockIo::Helper.signData(@data["data"]["inputs"], [@bad_key])
42
+ end
43
+
44
+ it "signed_data.nil?" do
45
+ all_signatures_empty = @data["data"]["inputs"].all?{|input| input["signers"].first["signed_data"].nil? }
46
+ expect(all_signatures_empty).to eq(true)
47
+ end
48
+
49
+ it "!signatures_added?" do
50
+ expect(@signatures_added).to eq(false)
51
+ end
52
+
53
+ end
54
+
55
+ context "key" do
56
+
57
+ before(:each) do
58
+ @data = Oj.load_file("spec/data/withdraw_response.json")
59
+ @encryption_key = BlockIo::Helper.pinToAesKey("blockiotestpininsecure")
60
+ @decrypted = BlockIo::Helper.decrypt(@data["data"]["encrypted_passphrase"]["passphrase"], @encryption_key)
61
+ @key = BlockIo::Key.from_passphrase(@decrypted, false)
62
+ @bad_key = BlockIo::Key.new(nil, false)
63
+ @result = Oj.safe_load(Oj.load_file("spec/data/sign_and_finalize_withdrawal_request.json")["signature_data"])["inputs"]
64
+ @signatures_added = BlockIo::Helper.signData(@data["data"]["inputs"], [@key])
65
+ end
66
+
67
+ it "signatures_added?" do
68
+ expect(@signatures_added).to eq(true)
69
+ end
70
+
71
+ it "valid_signature?(key)" do
72
+ all_signatures_valid = @data["data"]["inputs"].all?{|input| @key.valid_signature?(input["signers"].first["signed_data"], input["data_to_sign"]) }
73
+ expect(all_signatures_valid).to eq(true)
74
+ end
75
+
76
+ it "result.eq?(expected_signed_data)" do
77
+ matches_signed_data = Oj.dump(@result).eql?(Oj.dump(@data["data"]["inputs"]))
78
+ expect(matches_signed_data).to eq(true)
79
+ end
80
+
81
+ it "valid_signature?(bad_key)" do
82
+ all_signatures_invalid = @data["data"]["inputs"].all?{|input|
83
+ (!input["signers"].first["signed_data"].nil? and
84
+ !@bad_key.valid_signature?(input["signers"].first["signed_data"], input["data_to_sign"]))
85
+ }
86
+ expect(all_signatures_invalid).to eq(true)
87
+ end
88
+
89
+ end
90
+ end
metadata CHANGED
@@ -1,143 +1,175 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: block_io
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Atif Nazir
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-04 00:00:00.000000000 Z
11
+ date: 2020-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ - - "<"
18
21
  - !ruby/object:Gem::Version
19
- version: '1.6'
22
+ version: '3.0'
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: '1.6'
29
+ version: '1.16'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rake
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: '0'
39
+ version: '12.3'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 12.3.3
34
43
  type: :development
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
47
  - - "~>"
39
48
  - !ruby/object:Gem::Version
40
- version: '0'
49
+ version: '12.3'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 12.3.3
41
53
  - !ruby/object:Gem::Dependency
42
- name: ecdsa
54
+ name: rspec
43
55
  requirement: !ruby/object:Gem::Requirement
44
56
  requirements:
45
57
  - - "~>"
46
58
  - !ruby/object:Gem::Version
47
- version: '1.2'
59
+ version: '3.6'
48
60
  - - ">="
49
61
  - !ruby/object:Gem::Version
50
- version: 1.2.0
51
- type: :runtime
62
+ version: '3.6'
63
+ type: :development
52
64
  prerelease: false
53
65
  version_requirements: !ruby/object:Gem::Requirement
54
66
  requirements:
55
67
  - - "~>"
56
68
  - !ruby/object:Gem::Version
57
- version: '1.2'
69
+ version: '3.6'
58
70
  - - ">="
59
71
  - !ruby/object:Gem::Version
60
- version: 1.2.0
72
+ version: '3.6'
73
+ - !ruby/object:Gem::Dependency
74
+ name: webmock
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '3.8'
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.0'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.8'
90
+ - - "<"
91
+ - !ruby/object:Gem::Version
92
+ version: '4.0'
61
93
  - !ruby/object:Gem::Dependency
62
- name: httpclient
94
+ name: ecdsa
63
95
  requirement: !ruby/object:Gem::Requirement
64
96
  requirements:
65
97
  - - "~>"
66
98
  - !ruby/object:Gem::Version
67
- version: '2.4'
99
+ version: 1.2.0
68
100
  - - ">="
69
101
  - !ruby/object:Gem::Version
70
- version: 2.4.0
102
+ version: 1.2.0
71
103
  type: :runtime
72
104
  prerelease: false
73
105
  version_requirements: !ruby/object:Gem::Requirement
74
106
  requirements:
75
107
  - - "~>"
76
108
  - !ruby/object:Gem::Version
77
- version: '2.4'
109
+ version: 1.2.0
78
110
  - - ">="
79
111
  - !ruby/object:Gem::Version
80
- version: 2.4.0
112
+ version: 1.2.0
81
113
  - !ruby/object:Gem::Dependency
82
- name: json
114
+ name: http
83
115
  requirement: !ruby/object:Gem::Requirement
84
116
  requirements:
85
117
  - - "~>"
86
118
  - !ruby/object:Gem::Version
87
- version: '1.8'
119
+ version: 4.4.1
88
120
  - - ">="
89
121
  - !ruby/object:Gem::Version
90
- version: 1.8.1
122
+ version: 4.4.1
91
123
  type: :runtime
92
124
  prerelease: false
93
125
  version_requirements: !ruby/object:Gem::Requirement
94
126
  requirements:
95
127
  - - "~>"
96
128
  - !ruby/object:Gem::Version
97
- version: '1.8'
129
+ version: 4.4.1
98
130
  - - ">="
99
131
  - !ruby/object:Gem::Version
100
- version: 1.8.1
132
+ version: 4.4.1
101
133
  - !ruby/object:Gem::Dependency
102
- name: connection_pool
134
+ name: oj
103
135
  requirement: !ruby/object:Gem::Requirement
104
136
  requirements:
105
137
  - - "~>"
106
138
  - !ruby/object:Gem::Version
107
- version: '2.0'
139
+ version: 3.10.6
108
140
  - - ">="
109
141
  - !ruby/object:Gem::Version
110
- version: 2.0.0
142
+ version: '3.10'
111
143
  type: :runtime
112
144
  prerelease: false
113
145
  version_requirements: !ruby/object:Gem::Requirement
114
146
  requirements:
115
147
  - - "~>"
116
148
  - !ruby/object:Gem::Version
117
- version: '2.0'
149
+ version: 3.10.6
118
150
  - - ">="
119
151
  - !ruby/object:Gem::Version
120
- version: 2.0.0
152
+ version: '3.10'
121
153
  - !ruby/object:Gem::Dependency
122
- name: pbkdf2-ruby
154
+ name: connection_pool
123
155
  requirement: !ruby/object:Gem::Requirement
124
156
  requirements:
125
157
  - - "~>"
126
158
  - !ruby/object:Gem::Version
127
- version: '0.2'
159
+ version: 2.2.3
128
160
  - - ">="
129
161
  - !ruby/object:Gem::Version
130
- version: 0.2.1
162
+ version: '2.2'
131
163
  type: :runtime
132
164
  prerelease: false
133
165
  version_requirements: !ruby/object:Gem::Requirement
134
166
  requirements:
135
167
  - - "~>"
136
168
  - !ruby/object:Gem::Version
137
- version: '0.2'
169
+ version: 2.2.3
138
170
  - - ">="
139
171
  - !ruby/object:Gem::Version
140
- version: 0.2.1
172
+ version: '2.2'
141
173
  description: This Ruby Gem is the official reference client for the Block.io payments
142
174
  API. To use this, you will need the Dogecoin, Bitcoin, or Litecoin API key(s) from
143
175
  Block.io. Go ahead, sign up :)
@@ -147,7 +179,10 @@ executables: []
147
179
  extensions: []
148
180
  extra_rdoc_files: []
149
181
  files:
182
+ - ".appveyor.yml"
150
183
  - ".gitignore"
184
+ - ".rspec"
185
+ - ".travis.yml"
151
186
  - Gemfile
152
187
  - LICENSE
153
188
  - README.md
@@ -155,8 +190,27 @@ files:
155
190
  - block_io.gemspec
156
191
  - examples/basic.rb
157
192
  - examples/dtrust.rb
193
+ - examples/max_withdrawal.rb
194
+ - examples/proxy.rb
195
+ - examples/sweeper.rb
158
196
  - lib/block_io.rb
197
+ - lib/block_io/client.rb
198
+ - lib/block_io/constants.rb
199
+ - lib/block_io/helper.rb
200
+ - lib/block_io/key.rb
159
201
  - lib/block_io/version.rb
202
+ - spec/client_spec.rb
203
+ - spec/data/sign_and_finalize_dtrust_withdrawal_request.json
204
+ - spec/data/sign_and_finalize_sweep_request.json
205
+ - spec/data/sign_and_finalize_withdrawal_request.json
206
+ - spec/data/sweep_from_address_response.json
207
+ - spec/data/withdraw_from_dtrust_address_response.json
208
+ - spec/data/withdraw_response.json
209
+ - spec/helper_spec.rb
210
+ - spec/key_spec.rb
211
+ - spec/rfc6979_spec.rb
212
+ - spec/spec_helper.rb
213
+ - spec/withdraw_spec.rb
160
214
  homepage: https://block.io/api/simple/ruby
161
215
  licenses:
162
216
  - MIT
@@ -169,17 +223,28 @@ required_ruby_version: !ruby/object:Gem::Requirement
169
223
  requirements:
170
224
  - - ">="
171
225
  - !ruby/object:Gem::Version
172
- version: '0'
226
+ version: 2.3.0
173
227
  required_rubygems_version: !ruby/object:Gem::Requirement
174
228
  requirements:
175
229
  - - ">="
176
230
  - !ruby/object:Gem::Version
177
231
  version: '0'
178
232
  requirements: []
179
- rubyforge_project:
180
- rubygems_version: 2.2.2
233
+ rubygems_version: 3.1.2
181
234
  signing_key:
182
235
  specification_version: 4
183
236
  summary: An easy to use Dogecoin, Bitcoin, Litecoin wallet API by Block.io. Sign up
184
237
  required at Block.io.
185
- test_files: []
238
+ test_files:
239
+ - spec/client_spec.rb
240
+ - spec/data/sign_and_finalize_dtrust_withdrawal_request.json
241
+ - spec/data/sign_and_finalize_sweep_request.json
242
+ - spec/data/sign_and_finalize_withdrawal_request.json
243
+ - spec/data/sweep_from_address_response.json
244
+ - spec/data/withdraw_from_dtrust_address_response.json
245
+ - spec/data/withdraw_response.json
246
+ - spec/helper_spec.rb
247
+ - spec/key_spec.rb
248
+ - spec/rfc6979_spec.rb
249
+ - spec/spec_helper.rb
250
+ - spec/withdraw_spec.rb