block_io 1.0.6 → 1.0.8
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/block_io.gemspec +4 -3
- data/examples/change.rb +117 -0
- data/lib/block_io.rb +41 -32
- data/lib/block_io/version.rb +1 -1
- metadata +58 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9dc992c3a7aa1fc125e1eaf8b16d531318e31fd
|
4
|
+
data.tar.gz: fdf9ae723127d8688e55cdc0c1ffc9f0eb263bda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ed068c30ce271df8745e66288f050b97f5f3ec3f68f3087c88ed3b7068059e29503edc1043521bb55d56f80dfbb57491ce709033e36ef021e850775ee94501f
|
7
|
+
data.tar.gz: e9c4c14b3c2bbd292a20f8a018bd9089b20d5742115b0ebc9d6c2a707e4fac3583e1dc620fb4a580c5ab284b45a4ce3bc911dbd42ba6853930e93524d0e5e412
|
data/block_io.gemspec
CHANGED
@@ -21,8 +21,9 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.6"
|
22
22
|
spec.add_development_dependency "rake", "~> 0"
|
23
23
|
spec.add_runtime_dependency "ecdsa", "~> 1.2", '>= 1.2.0'
|
24
|
-
spec.add_runtime_dependency "httpclient", "~> 2.
|
25
|
-
spec.add_runtime_dependency "
|
26
|
-
spec.add_runtime_dependency "
|
24
|
+
spec.add_runtime_dependency "httpclient", "~> 2.8", '>= 2.8.0'
|
25
|
+
spec.add_runtime_dependency "oj", "~> 3.3", '>= 3.3.5'
|
26
|
+
spec.add_runtime_dependency "oj_mimic_json"
|
27
|
+
spec.add_runtime_dependency "connection_pool", "~> 2.2", '>= 2.2.1'
|
27
28
|
spec.add_runtime_dependency "pbkdf2-ruby", '~> 0.2', '>= 0.2.1'
|
28
29
|
end
|
data/examples/change.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
# 1. create an address (first_address), move all coins to it
|
2
|
+
# 2. create an address (second_address), as the change address for the first_address
|
3
|
+
# 3. send destination_amount to destination_address from first_address, and the rest of the coins to second_address
|
4
|
+
# 4. archive first_address since it will no longer be used
|
5
|
+
|
6
|
+
# execute with:
|
7
|
+
# $ DESTINATION_ADDRESS=AN_ADDRESS DESTINATION_AMOUNT=COINS_TO_SEND_TO_DESTINATION_ADDRESS API_KEY=TESTNET_API_KEY PIN=YOUR_SECRET_PIN ruby change.rb
|
8
|
+
|
9
|
+
require 'block_io'
|
10
|
+
require 'securerandom'
|
11
|
+
require 'bigdecimal'
|
12
|
+
|
13
|
+
# please use the Dogecoin/Bitcoin Testnet API key here
|
14
|
+
BlockIo.set_options :api_key => ENV['API_KEY'], :pin => ENV['PIN'], :version => 2
|
15
|
+
|
16
|
+
# create address A, and withdraw all coins to address A
|
17
|
+
first_address_label = SecureRandom.hex(8) # the source address
|
18
|
+
second_address_label = SecureRandom.hex(8) # the change address
|
19
|
+
|
20
|
+
# let's fill up the first address with whatever coins exist in this account
|
21
|
+
puts BlockIo.get_new_address(:label => first_address_label)
|
22
|
+
|
23
|
+
available_balance = BigDecimal(BlockIo.get_balance()['data']['available_balance'])
|
24
|
+
network_fee = BigDecimal('0.0')
|
25
|
+
|
26
|
+
puts "Available Balance: #{available_balance.truncate(8).to_s('F')}"
|
27
|
+
|
28
|
+
options = {:to_labels => first_address_label, :amounts => available_balance.to_s("F")}
|
29
|
+
|
30
|
+
tries = 2 # retry twice at most
|
31
|
+
|
32
|
+
begin
|
33
|
+
options[:amounts] = (available_balance - network_fee).truncate(8).to_s("F")
|
34
|
+
|
35
|
+
response = BlockIo.get_network_fee_estimate(options)
|
36
|
+
network_fee = BigDecimal(response['data']['estimated_network_fee'])
|
37
|
+
|
38
|
+
puts "Final Network Fee: #{network_fee.truncate(8).to_s('F')}"
|
39
|
+
|
40
|
+
options[:amounts] = (available_balance - network_fee).truncate(8).to_s("F")
|
41
|
+
rescue Exception => e
|
42
|
+
# extract the fee and subtract it from the available amount
|
43
|
+
|
44
|
+
network_fee = BigDecimal(e.to_s.split(' ')[7])
|
45
|
+
puts "Estimated Network Fee: #{e.to_s.split(' ')[7]}"
|
46
|
+
|
47
|
+
retry unless (tries -= 1).zero?
|
48
|
+
|
49
|
+
raise Exception.new("UNABLE TO ESTIMATE NETWORK FEE")
|
50
|
+
end
|
51
|
+
|
52
|
+
# make the withdrawal
|
53
|
+
puts BlockIo.withdraw(options)
|
54
|
+
|
55
|
+
# all balance has been transferred to first_address_label
|
56
|
+
|
57
|
+
# create the change address
|
58
|
+
puts BlockIo.get_new_address(:label => second_address_label)
|
59
|
+
|
60
|
+
destination_address = ENV['DESTINATION_ADDRESS']
|
61
|
+
destination_amount = BigDecimal(ENV['DESTINATION_AMOUNT'])
|
62
|
+
|
63
|
+
puts "Sending #{destination_amount} to #{destination_address}"
|
64
|
+
|
65
|
+
available_balance = BigDecimal(BlockIo.get_balance(:labels => first_address_label)['data']['available_balance'])
|
66
|
+
|
67
|
+
second_address = BlockIo.get_address_by_label(:label => second_address_label)['data']['address']
|
68
|
+
|
69
|
+
options = {}
|
70
|
+
|
71
|
+
tries = 2 # two tries to estimate the correct network fee
|
72
|
+
|
73
|
+
network_fee = BigDecimal('0.0')
|
74
|
+
|
75
|
+
to_addresses = []
|
76
|
+
amounts = []
|
77
|
+
|
78
|
+
# estimate the fee for this withdrawal
|
79
|
+
begin
|
80
|
+
|
81
|
+
change_amount = available_balance - destination_amount
|
82
|
+
|
83
|
+
if change_amount - network_fee > 0 then
|
84
|
+
to_addresses = [destination_address, second_address]
|
85
|
+
amounts = [destination_amount.truncate(8).to_s("F"), (change_amount - network_fee).truncate(8).to_s("F")]
|
86
|
+
else
|
87
|
+
to_addresses = [destination_address]
|
88
|
+
amounts = [destination_amount.truncate(8).to_s("F")]
|
89
|
+
end
|
90
|
+
|
91
|
+
response = BlockIo.get_network_fee_estimate(:from_labels => first_address_label, :to_addresses => to_addresses.join(','), :amounts => amounts.join(','))
|
92
|
+
network_fee = BigDecimal(response['data']['estimated_network_fee'])
|
93
|
+
|
94
|
+
puts "Final Network Fee: #{network_fee.truncate(8).to_s('F')}"
|
95
|
+
|
96
|
+
rescue Exception => e
|
97
|
+
# extract the fee and subtract it from the available amount
|
98
|
+
|
99
|
+
puts "Exception: #{e.to_s}"
|
100
|
+
|
101
|
+
network_fee = BigDecimal(e.to_s.split(' ')[7])
|
102
|
+
puts "Estimated Network Fee: #{e.to_s.split(' ')[7]}"
|
103
|
+
|
104
|
+
retry unless (tries -= 1).zero?
|
105
|
+
|
106
|
+
raise Exception.new("UNABLE TO ESTIMATE NETWORK FEE")
|
107
|
+
end
|
108
|
+
|
109
|
+
# make the withdrawal + send change to change address
|
110
|
+
|
111
|
+
puts BlockIo.withdraw(:from_labels => first_address_label, :to_addresses => to_addresses.join(','), :amounts => amounts.join(','))
|
112
|
+
|
113
|
+
# archive the first address
|
114
|
+
|
115
|
+
puts BlockIo.archive_address(:labels => first_address_label)
|
116
|
+
|
117
|
+
|
data/lib/block_io.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'block_io/version'
|
2
2
|
require 'httpclient'
|
3
|
-
require '
|
3
|
+
require 'oj'
|
4
4
|
require 'connection_pool'
|
5
5
|
require 'ecdsa'
|
6
6
|
require 'openssl'
|
@@ -24,7 +24,7 @@ module BlockIo
|
|
24
24
|
@pin = args[:pin]
|
25
25
|
@encryptionKey = Helper.pinToAesKey(@pin) if !@pin.nil?
|
26
26
|
|
27
|
-
@conn_pool = ConnectionPool.new(size:
|
27
|
+
@conn_pool = ConnectionPool.new(size: 1, timeout: 300) { h = HTTPClient.new; h.tcp_keepalive = true; h.ssl_config.ssl_version = :auto; h }
|
28
28
|
|
29
29
|
@version = args[:version] || 2 # default version is 2
|
30
30
|
|
@@ -56,7 +56,7 @@ module BlockIo
|
|
56
56
|
|
57
57
|
params = get_params(args)
|
58
58
|
|
59
|
-
params
|
59
|
+
params << "&pin=" << @pin if @version == 1 # Block.io handles the Secret PIN in the legacy API (v1)
|
60
60
|
|
61
61
|
response = self.api_call([method_name, params])
|
62
62
|
|
@@ -74,21 +74,10 @@ module BlockIo
|
|
74
74
|
# let's sign all the inputs we can
|
75
75
|
inputs = response['data']['inputs']
|
76
76
|
|
77
|
-
inputs
|
78
|
-
# iterate over all signers
|
79
|
-
|
80
|
-
input['signers'].each do |signer|
|
81
|
-
# if our public key matches this signer's public key, sign the data
|
82
|
-
|
83
|
-
signer['signed_data'] = key.sign(input['data_to_sign']) if signer['signer_public_key'] == key.public_key
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
77
|
+
Helper.signData(inputs, [key])
|
88
78
|
|
89
79
|
# the response object is now signed, let's stringify it and finalize this withdrawal
|
90
|
-
|
91
|
-
response = self.api_call(['sign_and_finalize_withdrawal',{:signature_data => response['data'].to_json}])
|
80
|
+
response = self.api_call(['sign_and_finalize_withdrawal',{:signature_data => Oj.dump(response['data'])}])
|
92
81
|
|
93
82
|
# if we provided all the required signatures, this transaction went through
|
94
83
|
# otherwise Block.io responded with data asking for more signatures
|
@@ -118,22 +107,10 @@ module BlockIo
|
|
118
107
|
|
119
108
|
# let's sign all the inputs we can
|
120
109
|
inputs = response['data']['inputs']
|
121
|
-
|
122
|
-
inputs.each do |input|
|
123
|
-
# iterate over all signers
|
124
|
-
|
125
|
-
input['signers'].each do |signer|
|
126
|
-
# if our public key matches this signer's public key, sign the data
|
127
|
-
|
128
|
-
signer['signed_data'] = key.sign(input['data_to_sign']) if signer['signer_public_key'] == key.public_key
|
129
|
-
|
130
|
-
end
|
131
|
-
|
132
|
-
end
|
110
|
+
Helper.signData(inputs, [key])
|
133
111
|
|
134
112
|
# the response object is now signed, let's stringify it and finalize this withdrawal
|
135
|
-
|
136
|
-
response = self.api_call(['sign_and_finalize_sweep',{:signature_data => response['data'].to_json}])
|
113
|
+
response = self.api_call(['sign_and_finalize_sweep',{:signature_data => Oj.dump(response['data'])}])
|
137
114
|
|
138
115
|
# if we provided all the required signatures, this transaction went through
|
139
116
|
# otherwise Block.io responded with data asking for more signatures
|
@@ -154,11 +131,10 @@ module BlockIo
|
|
154
131
|
@conn_pool.with do |hc|
|
155
132
|
# prevent initiation of HTTPClients every time we make this call, use a connection_pool
|
156
133
|
|
157
|
-
hc.ssl_config.ssl_version = :TLSv1
|
158
134
|
response = hc.post("#{@base_url.gsub('API_CALL',endpoint[0]).gsub('VERSION', 'v'+@version.to_s) + @api_key}", endpoint[1])
|
159
135
|
|
160
136
|
begin
|
161
|
-
body =
|
137
|
+
body = Oj.load(response.body)
|
162
138
|
raise Exception.new(body['data']['error_message']) if !body['status'].eql?('success')
|
163
139
|
rescue
|
164
140
|
raise Exception.new('Unknown error occurred. Please report this.')
|
@@ -310,6 +286,39 @@ module BlockIo
|
|
310
286
|
|
311
287
|
module Helper
|
312
288
|
|
289
|
+
def self.signData(inputs, keys)
|
290
|
+
# sign the given data with the given keys
|
291
|
+
# TODO loop is O(n^3), make it better
|
292
|
+
|
293
|
+
raise Exception.new('Keys object must be an array of keys, without at least one key inside it.') unless keys.is_a?(Array) and keys.size >= 1
|
294
|
+
|
295
|
+
i = 0
|
296
|
+
while i < inputs.size do
|
297
|
+
# iterate over all signers
|
298
|
+
input = inputs[i]
|
299
|
+
|
300
|
+
j = 0
|
301
|
+
while j < input['signers'].size do
|
302
|
+
# if our public key matches this signer's public key, sign the data
|
303
|
+
signer = inputs[i]['signers'][j]
|
304
|
+
|
305
|
+
k = 0
|
306
|
+
while k < keys.size do
|
307
|
+
# sign for each key provided, if we can
|
308
|
+
key = keys[k]
|
309
|
+
signer['signed_data'] = key.sign(input['data_to_sign']) if signer['signer_public_key'] == key.public_key
|
310
|
+
k = k + 1
|
311
|
+
end
|
312
|
+
|
313
|
+
j = j + 1
|
314
|
+
end
|
315
|
+
|
316
|
+
i = i + 1
|
317
|
+
end
|
318
|
+
|
319
|
+
inputs
|
320
|
+
end
|
321
|
+
|
313
322
|
def self.extractKey(encrypted_data, b64_enc_key)
|
314
323
|
# passphrase is in plain text
|
315
324
|
# encrypted_data is in base64, as it was stored on Block.io
|
data/lib/block_io/version.rb
CHANGED
metadata
CHANGED
@@ -1,141 +1,155 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: block_io
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Atif Nazir
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-09-10 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
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.6'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: ecdsa
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '1.2'
|
48
|
-
- -
|
48
|
+
- - '>='
|
49
49
|
- !ruby/object:Gem::Version
|
50
50
|
version: 1.2.0
|
51
51
|
type: :runtime
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
54
54
|
requirements:
|
55
|
-
- -
|
55
|
+
- - ~>
|
56
56
|
- !ruby/object:Gem::Version
|
57
57
|
version: '1.2'
|
58
|
-
- -
|
58
|
+
- - '>='
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: 1.2.0
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: httpclient
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
|
-
- -
|
65
|
+
- - ~>
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '2.
|
68
|
-
- -
|
67
|
+
version: '2.8'
|
68
|
+
- - '>='
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version: 2.
|
70
|
+
version: 2.8.0
|
71
71
|
type: :runtime
|
72
72
|
prerelease: false
|
73
73
|
version_requirements: !ruby/object:Gem::Requirement
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: '2.
|
78
|
-
- -
|
77
|
+
version: '2.8'
|
78
|
+
- - '>='
|
79
79
|
- !ruby/object:Gem::Version
|
80
|
-
version: 2.
|
80
|
+
version: 2.8.0
|
81
81
|
- !ruby/object:Gem::Dependency
|
82
|
-
name:
|
82
|
+
name: oj
|
83
83
|
requirement: !ruby/object:Gem::Requirement
|
84
84
|
requirements:
|
85
|
-
- -
|
85
|
+
- - ~>
|
86
86
|
- !ruby/object:Gem::Version
|
87
|
-
version: '
|
88
|
-
- -
|
87
|
+
version: '3.3'
|
88
|
+
- - '>='
|
89
89
|
- !ruby/object:Gem::Version
|
90
|
-
version:
|
90
|
+
version: 3.3.5
|
91
91
|
type: :runtime
|
92
92
|
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- -
|
95
|
+
- - ~>
|
96
96
|
- !ruby/object:Gem::Version
|
97
|
-
version: '
|
98
|
-
- -
|
97
|
+
version: '3.3'
|
98
|
+
- - '>='
|
99
99
|
- !ruby/object:Gem::Version
|
100
|
-
version:
|
100
|
+
version: 3.3.5
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: oj_mimic_json
|
103
|
+
requirement: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
type: :runtime
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
101
115
|
- !ruby/object:Gem::Dependency
|
102
116
|
name: connection_pool
|
103
117
|
requirement: !ruby/object:Gem::Requirement
|
104
118
|
requirements:
|
105
|
-
- -
|
119
|
+
- - ~>
|
106
120
|
- !ruby/object:Gem::Version
|
107
|
-
version: '2.
|
108
|
-
- -
|
121
|
+
version: '2.2'
|
122
|
+
- - '>='
|
109
123
|
- !ruby/object:Gem::Version
|
110
|
-
version: 2.
|
124
|
+
version: 2.2.1
|
111
125
|
type: :runtime
|
112
126
|
prerelease: false
|
113
127
|
version_requirements: !ruby/object:Gem::Requirement
|
114
128
|
requirements:
|
115
|
-
- -
|
129
|
+
- - ~>
|
116
130
|
- !ruby/object:Gem::Version
|
117
|
-
version: '2.
|
118
|
-
- -
|
131
|
+
version: '2.2'
|
132
|
+
- - '>='
|
119
133
|
- !ruby/object:Gem::Version
|
120
|
-
version: 2.
|
134
|
+
version: 2.2.1
|
121
135
|
- !ruby/object:Gem::Dependency
|
122
136
|
name: pbkdf2-ruby
|
123
137
|
requirement: !ruby/object:Gem::Requirement
|
124
138
|
requirements:
|
125
|
-
- -
|
139
|
+
- - ~>
|
126
140
|
- !ruby/object:Gem::Version
|
127
141
|
version: '0.2'
|
128
|
-
- -
|
142
|
+
- - '>='
|
129
143
|
- !ruby/object:Gem::Version
|
130
144
|
version: 0.2.1
|
131
145
|
type: :runtime
|
132
146
|
prerelease: false
|
133
147
|
version_requirements: !ruby/object:Gem::Requirement
|
134
148
|
requirements:
|
135
|
-
- -
|
149
|
+
- - ~>
|
136
150
|
- !ruby/object:Gem::Version
|
137
151
|
version: '0.2'
|
138
|
-
- -
|
152
|
+
- - '>='
|
139
153
|
- !ruby/object:Gem::Version
|
140
154
|
version: 0.2.1
|
141
155
|
description: This Ruby Gem is the official reference client for the Block.io payments
|
@@ -147,13 +161,14 @@ executables: []
|
|
147
161
|
extensions: []
|
148
162
|
extra_rdoc_files: []
|
149
163
|
files:
|
150
|
-
-
|
164
|
+
- .gitignore
|
151
165
|
- Gemfile
|
152
166
|
- LICENSE
|
153
167
|
- README.md
|
154
168
|
- Rakefile
|
155
169
|
- block_io.gemspec
|
156
170
|
- examples/basic.rb
|
171
|
+
- examples/change.rb
|
157
172
|
- examples/dtrust.rb
|
158
173
|
- examples/sweeper.rb
|
159
174
|
- lib/block_io.rb
|
@@ -168,17 +183,17 @@ require_paths:
|
|
168
183
|
- lib
|
169
184
|
required_ruby_version: !ruby/object:Gem::Requirement
|
170
185
|
requirements:
|
171
|
-
- -
|
186
|
+
- - '>='
|
172
187
|
- !ruby/object:Gem::Version
|
173
188
|
version: '0'
|
174
189
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
190
|
requirements:
|
176
|
-
- -
|
191
|
+
- - '>='
|
177
192
|
- !ruby/object:Gem::Version
|
178
193
|
version: '0'
|
179
194
|
requirements: []
|
180
195
|
rubyforge_project:
|
181
|
-
rubygems_version: 2.
|
196
|
+
rubygems_version: 2.0.14.1
|
182
197
|
signing_key:
|
183
198
|
specification_version: 4
|
184
199
|
summary: An easy to use Dogecoin, Bitcoin, Litecoin wallet API by Block.io. Sign up
|