onchain 1.0.13 → 1.0.14
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/lib/onchain/block_chain.rb +53 -273
- data/lib/onchain/payments.rb +2 -2
- data/lib/onchain/providers/blockchaininfo_api.rb +70 -0
- data/lib/onchain/providers/blockr_api.rb +74 -0
- data/lib/onchain/providers/chaincom_api.rb +4 -0
- data/lib/onchain/sweeper.rb +1 -1
- data/lib/onchain.rb +3 -0
- metadata +13 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34dfbd268297f6be4f6cd1a23d766aecee706b9f
|
4
|
+
data.tar.gz: 5efa3f058778c38e0e0f1e5b38eefb6210ce845c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c934cdae3ac301001fddc90c702eac3518d99ff82e7b9fd752dfc6a4e73072bc2de89d40d535f18abaa9d7f93410848b850e8f6f916e3ac6c5958646087c12ce
|
7
|
+
data.tar.gz: 953098816da0ce65180dee31cb1d0dba97cf30e2c7f6799bcb337759d45faae9a71164e86172998d3198404ae58a79da4804f7ba251af76195883818d7933b82
|
data/lib/onchain/block_chain.rb
CHANGED
@@ -1,292 +1,81 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'json'
|
3
3
|
|
4
|
+
# We support a number of blockchain API providers,
|
5
|
+
# if one goes down we automatically switch over to another.
|
6
|
+
#
|
7
|
+
# Each provider has to support the following methods
|
8
|
+
#
|
9
|
+
# get_balance(address)
|
10
|
+
# get_all_balances([])
|
11
|
+
# send_tx(tx_hex)
|
12
|
+
# get_transactions(address)
|
13
|
+
#
|
4
14
|
class OnChain
|
15
|
+
end
|
16
|
+
|
17
|
+
class OnChain::BlockChain
|
5
18
|
class << self
|
6
19
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@@cache = {}
|
11
|
-
|
12
|
-
def cache_write(key, data, max_age=0)
|
13
|
-
@@cache[key] = [Time.now, data, max_age]
|
14
|
-
end
|
15
|
-
|
16
|
-
def cache_read(key)
|
17
|
-
# if the API URL exists as a key in cache, we just return it
|
18
|
-
# we also make sure the data is fresh
|
19
|
-
if @@cache.has_key? key
|
20
|
-
return @@cache[key][1] if Time.now-@@cache[key][0] < @@cache[key][2]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
20
|
+
#ALL_SUPPLIERS = [:chaincom, :blockr, :blockinfo ]
|
21
|
+
ALL_SUPPLIERS = [ :blockr, :blockinfo ]
|
24
22
|
|
25
|
-
def
|
23
|
+
def method_missing (method_name, *args, &block)
|
24
|
+
|
25
|
+
get_available_suppliers.each do |supplier|
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
real_method = "#{supplier.to_s}_#{method_name}"
|
28
|
+
begin
|
29
|
+
method = self.method(real_method)
|
30
|
+
begin
|
31
|
+
result = method.call(*args)
|
32
|
+
return result
|
33
|
+
rescue => e2
|
34
|
+
# We have the method but it errored. Assume
|
35
|
+
# service is down.
|
36
|
+
cache_write(supplier.to_s, 'down', SERVICE_DOWN_FOR)
|
37
|
+
puts e2.to_s
|
38
|
+
end
|
39
|
+
rescue => e
|
40
|
+
puts "there's no method called '#{real_method}'"
|
41
|
+
puts e.backtrace
|
42
|
+
end
|
30
43
|
end
|
31
44
|
|
32
|
-
if ! blockchain_down?
|
33
|
-
bal = blockinfo_get_all_balances(addresses)
|
34
|
-
return bal
|
35
|
-
end
|
36
45
|
end
|
37
46
|
|
38
47
|
def get_balance_satoshi(address)
|
39
48
|
return (get_balance(address).to_f * 100000000).to_i
|
40
49
|
end
|
41
50
|
|
42
|
-
def
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
if ! bal.instance_of? String
|
48
|
-
return bal
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# Looks like blockchain is down, let's try blockr
|
53
|
-
if ! blockr_down?
|
54
|
-
bal = blockr_balance(address)
|
55
|
-
if ! bal.instance_of? String
|
56
|
-
return bal
|
51
|
+
def get_available_suppliers
|
52
|
+
available = []
|
53
|
+
ALL_SUPPLIERS.each do |supplier|
|
54
|
+
if cache_read(supplier.to_s) == nil
|
55
|
+
available << supplier
|
57
56
|
end
|
58
57
|
end
|
59
|
-
|
60
|
-
# OK I give up.
|
61
|
-
'Balance could not be retrieved'
|
58
|
+
return available
|
62
59
|
end
|
63
60
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
# Blockchain doesn't support multi sig, so only use blockr
|
69
|
-
uri = URI.parse("http://btc.blockr.io/api/v1/tx/push")
|
70
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
71
|
-
|
72
|
-
request = Net::HTTP::Post.new(uri.request_uri)
|
73
|
-
request.body = '{"hex":"' + tx_hex + '"}'
|
74
|
-
response = http.request(request)
|
75
|
-
return response
|
76
|
-
end
|
61
|
+
BALANCE_CACHE_FOR = 120
|
62
|
+
API_CACHE_FOR = 60
|
63
|
+
SERVICE_DOWN_FOR = 60
|
77
64
|
|
78
|
-
|
79
|
-
return []
|
80
|
-
end
|
65
|
+
@@cache = {}
|
81
66
|
|
82
|
-
def
|
83
|
-
|
84
|
-
base_url = "http://btc.blockr.io/api/v1/address/txs/#{address}"
|
85
|
-
json = fetch_response(base_url, true)
|
86
|
-
|
87
|
-
unspent = []
|
88
|
-
|
89
|
-
json['data']['txs'].each do |data|
|
90
|
-
line = []
|
91
|
-
line << data['tx']
|
92
|
-
line << (data['amount'].to_f * 100000000).to_i
|
93
|
-
unspent << line
|
94
|
-
end
|
95
|
-
|
96
|
-
return unspent
|
97
|
-
rescue Exception => e
|
98
|
-
puts e.to_s
|
99
|
-
'Unspent outputs could not be retrieved'
|
100
|
-
end
|
67
|
+
def cache_write(key, data, max_age=0)
|
68
|
+
@@cache[key] = [Time.now, data, max_age]
|
101
69
|
end
|
102
70
|
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
end
|
110
|
-
|
111
|
-
if ! blockchain_down?
|
112
|
-
return blockinfo_unspent(address)
|
113
|
-
end
|
114
|
-
|
115
|
-
# OK I give up.
|
116
|
-
'Unspent outputs could not be retrieved'
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
def blockchain_is_down
|
121
|
-
cache_write(:blockchainapi, 'it is down', 60)
|
122
|
-
end
|
123
|
-
|
124
|
-
def blockchain_down?
|
125
|
-
if cache_read(:blockchainapi) != nil
|
126
|
-
return true
|
127
|
-
end
|
128
|
-
return false
|
129
|
-
end
|
130
|
-
|
131
|
-
def blockr_is_down
|
132
|
-
cache_write(:blockrapi, 'it is down', 60)
|
133
|
-
end
|
134
|
-
|
135
|
-
def blockr_down?
|
136
|
-
if cache_read(:blockrapi) != nil
|
137
|
-
return true
|
138
|
-
end
|
139
|
-
return false
|
140
|
-
end
|
141
|
-
|
142
|
-
def blockinfo_get_all_balances(addresses)
|
143
|
-
begin
|
144
|
-
base = "https://blockchain.info/multiaddr?&simple=true&active="
|
145
|
-
|
146
|
-
addresses.each do |address|
|
147
|
-
base = base + address + '|'
|
148
|
-
end
|
149
|
-
|
150
|
-
json = fetch_response(URI::encode(base))
|
151
|
-
|
152
|
-
addresses.each do |address|
|
153
|
-
bal = json[address]['final_balance'] / 100000000.0
|
154
|
-
cache_write(address, bal, BALANCE_CACHE_FOR)
|
155
|
-
end
|
156
|
-
|
157
|
-
rescue
|
158
|
-
'Balance could not be retrieved'
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
def blockinfo_unspent(address)
|
163
|
-
begin
|
164
|
-
base_url = "http://blockchain.info/unspent?active=#{address}"
|
165
|
-
json = fetch_response(base_url, true)
|
166
|
-
|
167
|
-
unspent = []
|
168
|
-
|
169
|
-
json['unspent_outputs'].each do |data|
|
170
|
-
line = []
|
171
|
-
line << reverse_blockchain_tx(data['tx_hash'])
|
172
|
-
line << data['tx_output_n']
|
173
|
-
line << data['script']
|
174
|
-
line << data['value']
|
175
|
-
unspent << line
|
176
|
-
end
|
177
|
-
|
178
|
-
return unspent
|
179
|
-
rescue Exception => e
|
180
|
-
puts e.to_s
|
181
|
-
'Unspent outputs could not be retrieved'
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def blockinfo_balance(address)
|
186
|
-
begin
|
187
|
-
if cache_read(address) == nil
|
188
|
-
json = block_chain('address', address, "&limit=0")
|
189
|
-
if json.key?('final_balance')
|
190
|
-
bal = json['final_balance'] / 100000000.0
|
191
|
-
cache_write(address, bal, BALANCE_CACHE_FOR)
|
192
|
-
else
|
193
|
-
cache_write(address, 'Error', BALANCE_CACHE_FOR)
|
194
|
-
end
|
195
|
-
end
|
196
|
-
bal = cache_read(address)
|
197
|
-
if bal.class == Fixnum
|
198
|
-
bal = bal.to_f
|
199
|
-
end
|
200
|
-
return bal
|
201
|
-
rescue
|
202
|
-
'Balance could not be retrieved'
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
def blockr_unspent(address)
|
207
|
-
begin
|
208
|
-
base_url = "http://btc.blockr.io/api/v1/address/unspent/#{address}"
|
209
|
-
json = fetch_response(base_url, true)
|
210
|
-
|
211
|
-
unspent = []
|
212
|
-
|
213
|
-
json['data']['unspent'].each do |data|
|
214
|
-
line = []
|
215
|
-
line << data['tx']
|
216
|
-
line << data['n']
|
217
|
-
line << data['script']
|
218
|
-
line << (data['amount'].to_f * 100000000).to_i
|
219
|
-
unspent << line
|
220
|
-
end
|
221
|
-
|
222
|
-
return unspent
|
223
|
-
rescue Exception => e
|
224
|
-
puts e.to_s
|
225
|
-
'Unspent outputs could not be retrieved'
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
def blockr_get_all_balances(addresses)
|
230
|
-
begin
|
231
|
-
base = "https://blockr.io/api/v1/address/balance/"
|
232
|
-
|
233
|
-
addresses.each do |address|
|
234
|
-
base = base + address + ','
|
235
|
-
end
|
236
|
-
|
237
|
-
json = fetch_response(URI::encode(base))
|
238
|
-
|
239
|
-
json['data'].each do |data|
|
240
|
-
bal = data['balance']
|
241
|
-
addr = data['address']
|
242
|
-
cache_write(addr, bal, BALANCE_CACHE_FOR)
|
243
|
-
end
|
244
|
-
|
245
|
-
rescue
|
246
|
-
'Balance could not be retrieved'
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
def blockr_balance(address)
|
251
|
-
begin
|
252
|
-
if cache_read(address) == nil
|
253
|
-
json = blockr('address/balance', address)
|
254
|
-
if json.key?('data')
|
255
|
-
bal = json['data']['balance'].to_f
|
256
|
-
cache_write(address, bal, BALANCE_CACHE_FOR)
|
257
|
-
else
|
258
|
-
cache_write(address, 'Error', BALANCE_CACHE_FOR)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
return cache_read(address)
|
262
|
-
rescue Exception => e
|
263
|
-
'Balance could not be retrieved'
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
def blockr(cmd, address, params = "")
|
268
|
-
if ! blockr_down?
|
269
|
-
begin
|
270
|
-
base_url = "http://blockr.io/api/v1/#{cmd}/#{address}" + params
|
271
|
-
fetch_response(base_url, true)
|
272
|
-
rescue
|
273
|
-
blockr_is_down
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
def block_chain(cmd, address, params = "")
|
279
|
-
if ! blockchain_down?
|
280
|
-
begin
|
281
|
-
base_url = "http://blockchain.info/#{cmd}/#{address}?format=json" + params
|
282
|
-
|
283
|
-
fetch_response(base_url, true)
|
284
|
-
rescue
|
285
|
-
blockchain_is_down
|
286
|
-
end
|
287
|
-
end
|
71
|
+
def cache_read(key)
|
72
|
+
# if the API URL exists as a key in cache, we just return it
|
73
|
+
# we also make sure the data is fresh
|
74
|
+
if @@cache.has_key? key
|
75
|
+
return @@cache[key][1] if Time.now-@@cache[key][0] < @@cache[key][2]
|
76
|
+
end
|
288
77
|
end
|
289
|
-
|
78
|
+
|
290
79
|
def fetch_response(url, do_json=true)
|
291
80
|
resp = Net::HTTP.get_response(URI.parse(url))
|
292
81
|
data = resp.body
|
@@ -298,14 +87,5 @@ class OnChain
|
|
298
87
|
end
|
299
88
|
end
|
300
89
|
|
301
|
-
def reverse_blockchain_tx(hash)
|
302
|
-
bytes = hash.scan(/../).map { |x| x.hex.chr }.join
|
303
|
-
|
304
|
-
bytes = bytes.reverse
|
305
|
-
|
306
|
-
return hash.scan(/../).reverse.join
|
307
|
-
end
|
308
|
-
|
309
|
-
|
310
90
|
end
|
311
91
|
end
|
data/lib/onchain/payments.rb
CHANGED
@@ -36,7 +36,7 @@ class OnChain
|
|
36
36
|
total_amount = total_amount + payment[1]
|
37
37
|
end
|
38
38
|
|
39
|
-
total_in_fund = get_balance_satoshi(fund_address)
|
39
|
+
total_in_fund = OnChain::BlockChain.get_balance_satoshi(fund_address)
|
40
40
|
|
41
41
|
# Do we have enough in the fund.
|
42
42
|
if(total_amount > total_in_fund)
|
@@ -45,7 +45,7 @@ class OnChain
|
|
45
45
|
|
46
46
|
# OK, let's get some inputs
|
47
47
|
amount_so_far = 0
|
48
|
-
unspent = get_unspent_outs(fund_address)
|
48
|
+
unspent = OnChain::BlockChain.get_unspent_outs(fund_address)
|
49
49
|
unspent.each do |spent|
|
50
50
|
|
51
51
|
txin = Bitcoin::Protocol::TxIn.new
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class OnChain::BlockChain
|
2
|
+
class << self
|
3
|
+
|
4
|
+
|
5
|
+
def blockinfo_get_all_balances(addresses)
|
6
|
+
base = "https://blockchain.info/multiaddr?&simple=true&active="
|
7
|
+
|
8
|
+
addresses.each do |address|
|
9
|
+
base = base + address + '|'
|
10
|
+
end
|
11
|
+
|
12
|
+
json = fetch_response(URI::encode(base))
|
13
|
+
|
14
|
+
addresses.each do |address|
|
15
|
+
bal = json[address]['final_balance'] / 100000000.0
|
16
|
+
cache_write(address, bal, BALANCE_CACHE_FOR)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def blockinfo_get_unspent_outs(address)
|
21
|
+
base_url = "http://blockchain.info/unspent?active=#{address}"
|
22
|
+
json = fetch_response(base_url, true)
|
23
|
+
|
24
|
+
unspent = []
|
25
|
+
|
26
|
+
json['unspent_outputs'].each do |data|
|
27
|
+
line = []
|
28
|
+
line << reverse_blockchain_tx(data['tx_hash'])
|
29
|
+
line << data['tx_output_n']
|
30
|
+
line << data['script']
|
31
|
+
line << data['value']
|
32
|
+
unspent << line
|
33
|
+
end
|
34
|
+
|
35
|
+
return unspent
|
36
|
+
end
|
37
|
+
|
38
|
+
def blockinfo_get_balance(address)
|
39
|
+
if cache_read(address) == nil
|
40
|
+
json = block_chain('address', address, "&limit=0")
|
41
|
+
if json.key?('final_balance')
|
42
|
+
bal = json['final_balance'] / 100000000.0
|
43
|
+
cache_write(address, bal, BALANCE_CACHE_FOR)
|
44
|
+
else
|
45
|
+
cache_write(address, 'Error', BALANCE_CACHE_FOR)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
bal = cache_read(address)
|
49
|
+
if bal.class == Fixnum
|
50
|
+
bal = bal.to_f
|
51
|
+
end
|
52
|
+
return bal
|
53
|
+
end
|
54
|
+
|
55
|
+
def block_chain(cmd, address, params = "")
|
56
|
+
base_url = "http://blockchain.info/#{cmd}/#{address}?format=json" + params
|
57
|
+
|
58
|
+
fetch_response(base_url, true)
|
59
|
+
end
|
60
|
+
|
61
|
+
def reverse_blockchain_tx(hash)
|
62
|
+
bytes = hash.scan(/../).map { |x| x.hex.chr }.join
|
63
|
+
|
64
|
+
bytes = bytes.reverse
|
65
|
+
|
66
|
+
return hash.scan(/../).reverse.join
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class OnChain::BlockChain
|
2
|
+
class << self
|
3
|
+
|
4
|
+
def blockr_get_balance(address)
|
5
|
+
if cache_read(address) == nil
|
6
|
+
json = blockr('address/balance', address)
|
7
|
+
if json.key?('data')
|
8
|
+
bal = json['data']['balance'].to_f
|
9
|
+
cache_write(address, bal, BALANCE_CACHE_FOR)
|
10
|
+
else
|
11
|
+
cache_write(address, 'Error', BALANCE_CACHE_FOR)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
return cache_read(address)
|
15
|
+
end
|
16
|
+
|
17
|
+
def blockr_get_transactions(address)
|
18
|
+
base_url = "http://btc.blockr.io/api/v1/address/txs/#{address}"
|
19
|
+
json = fetch_response(base_url, true)
|
20
|
+
|
21
|
+
unspent = []
|
22
|
+
|
23
|
+
json['data']['txs'].each do |data|
|
24
|
+
line = []
|
25
|
+
line << data['tx']
|
26
|
+
line << (data['amount'].to_f * 100000000).to_i
|
27
|
+
unspent << line
|
28
|
+
end
|
29
|
+
|
30
|
+
return unspent
|
31
|
+
end
|
32
|
+
|
33
|
+
def blockr_get_unspent_outs(address)
|
34
|
+
base_url = "http://btc.blockr.io/api/v1/address/unspent/#{address}"
|
35
|
+
json = fetch_response(base_url, true)
|
36
|
+
|
37
|
+
unspent = []
|
38
|
+
|
39
|
+
json['data']['unspent'].each do |data|
|
40
|
+
line = []
|
41
|
+
line << data['tx']
|
42
|
+
line << data['n']
|
43
|
+
line << data['script']
|
44
|
+
line << (data['amount'].to_f * 100000000).to_i
|
45
|
+
unspent << line
|
46
|
+
end
|
47
|
+
|
48
|
+
return unspent
|
49
|
+
end
|
50
|
+
|
51
|
+
def blockr_get_all_balances(addresses)
|
52
|
+
base = "https://blockr.io/api/v1/address/balance/"
|
53
|
+
|
54
|
+
addresses.each do |address|
|
55
|
+
base = base + address + ','
|
56
|
+
end
|
57
|
+
|
58
|
+
json = fetch_response(URI::encode(base))
|
59
|
+
|
60
|
+
json['data'].each do |data|
|
61
|
+
bal = data['balance']
|
62
|
+
addr = data['address']
|
63
|
+
cache_write(addr, bal, BALANCE_CACHE_FOR)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def blockr(cmd, address, params = "")
|
68
|
+
|
69
|
+
base_url = "http://blockr.io/api/v1/#{cmd}/#{address}" + params
|
70
|
+
fetch_response(base_url, true)
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/onchain/sweeper.rb
CHANGED
data/lib/onchain.rb
CHANGED
metadata
CHANGED
@@ -1,69 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: onchain
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Purton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
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: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rspec
|
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: money-tree
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bitcoin-ruby
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
description: Call 3rd party API's but also switch API's if a 3rd party is down
|
@@ -76,6 +76,9 @@ files:
|
|
76
76
|
- lib/onchain.rb
|
77
77
|
- lib/onchain/block_chain.rb
|
78
78
|
- lib/onchain/payments.rb
|
79
|
+
- lib/onchain/providers/blockchaininfo_api.rb
|
80
|
+
- lib/onchain/providers/blockr_api.rb
|
81
|
+
- lib/onchain/providers/chaincom_api.rb
|
79
82
|
- lib/onchain/sweeper.rb
|
80
83
|
homepage: https://github.com/onchain/onchain-gem
|
81
84
|
licenses: []
|