onchain 0.4.2 → 1.0.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.
- checksums.yaml +4 -4
- data/lib/onchain/block_chain.rb +289 -0
- data/lib/onchain/sweeper.rb +41 -0
- data/lib/onchain.rb +4 -289
- metadata +10 -26
- data/.gitignore +0 -14
- data/README.md +0 -4
- data/lib/onchain/version.rb +0 -3
- data/onchain.gemspec +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 434e9d7b76fb77c75cd6ee42ee305c88ff1e654f
|
4
|
+
data.tar.gz: 3414885379272cc9c61a53a1310de8a30652c73b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15e32c96f9ad075a6d390ed51c82fede89aadc6d964414b224c92887bb81e027e0730ff2ff3a7fd22e73535470966d0e1e4a2ea442f3bab26c5d99725e025437
|
7
|
+
data.tar.gz: f38144aac4022320524fc41fb273b6f88afac0795f6b08598c4620d948f4faa035dedb287f9cd509205fae25b20eeae4f3023bb0d4615a858a29577b090955d3
|
@@ -0,0 +1,289 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class OnChain
|
5
|
+
class << self
|
6
|
+
|
7
|
+
BALANCE_CACHE_FOR = 120
|
8
|
+
API_CACHE_FOR = 60
|
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
|
+
|
24
|
+
|
25
|
+
def get_all_balances(addresses)
|
26
|
+
|
27
|
+
if ! blockr_down?
|
28
|
+
bal = blockr_get_all_balances(addresses)
|
29
|
+
return bal
|
30
|
+
end
|
31
|
+
|
32
|
+
if ! blockchain_down?
|
33
|
+
bal = blockinfo_get_all_balances(addresses)
|
34
|
+
return bal
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_balance(address)
|
39
|
+
|
40
|
+
# These guys make 300k per month so hammer them first.
|
41
|
+
if ! blockchain_down?
|
42
|
+
bal = blockinfo_balance(address)
|
43
|
+
if ! bal.instance_of? String
|
44
|
+
return bal
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Looks like blockchain is down, let's try blockr
|
49
|
+
if ! blockr_down?
|
50
|
+
bal = blockr_balance(address)
|
51
|
+
if ! bal.instance_of? String
|
52
|
+
return bal
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# OK I give up.
|
57
|
+
'Balance could not be retrieved'
|
58
|
+
end
|
59
|
+
|
60
|
+
def send_tx(tx_hex)
|
61
|
+
#payload = { :tx => tx_hex }
|
62
|
+
#HTTParty.post('http://blockchain.info/pushtx', {:body => payload})
|
63
|
+
|
64
|
+
# Blockchain doesn't support multi sig, so only use blockr
|
65
|
+
uri = URI.parse("http://btc.blockr.io/api/v1/tx/push")
|
66
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
67
|
+
|
68
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
69
|
+
request.body = '{"hex":"' + tx_hex + '"}'
|
70
|
+
response = http.request(request)
|
71
|
+
return response
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_history
|
75
|
+
return []
|
76
|
+
end
|
77
|
+
|
78
|
+
def get_unspent_outs(address)
|
79
|
+
|
80
|
+
|
81
|
+
# Looks like blockchain is down, let's try blockr
|
82
|
+
if ! blockr_down?
|
83
|
+
return blockr_unspent(address)
|
84
|
+
end
|
85
|
+
|
86
|
+
if ! blockchain_down?
|
87
|
+
return blockinfo_unspent(address)
|
88
|
+
end
|
89
|
+
|
90
|
+
# OK I give up.
|
91
|
+
'Unspent outputs could not be retrieved'
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
def blockchain_is_down
|
96
|
+
cache_write(:blockchainapi, 'it is down', 60)
|
97
|
+
end
|
98
|
+
|
99
|
+
def blockchain_down?
|
100
|
+
if cache_read(:blockchainapi) != nil
|
101
|
+
return true
|
102
|
+
end
|
103
|
+
return false
|
104
|
+
end
|
105
|
+
|
106
|
+
def blockr_is_down
|
107
|
+
cache_write(:blockrapi, 'it is down', 60)
|
108
|
+
end
|
109
|
+
|
110
|
+
def blockr_down?
|
111
|
+
if cache_read(:blockrapi) != nil
|
112
|
+
return true
|
113
|
+
end
|
114
|
+
return false
|
115
|
+
end
|
116
|
+
|
117
|
+
def blockinfo_get_all_balances(addresses)
|
118
|
+
begin
|
119
|
+
base = "https://blockchain.info/multiaddr?&simple=true&active="
|
120
|
+
|
121
|
+
addresses.each do |address|
|
122
|
+
base = base + address + '|'
|
123
|
+
end
|
124
|
+
|
125
|
+
json = fetch_response(URI::encode(base))
|
126
|
+
|
127
|
+
addresses.each do |address|
|
128
|
+
bal = json[address]['final_balance'] / 100000000.0
|
129
|
+
cache_write(address, bal, BALANCE_CACHE_FOR)
|
130
|
+
end
|
131
|
+
|
132
|
+
rescue
|
133
|
+
'Balance could not be retrieved'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def blockinfo_unspent(address)
|
138
|
+
begin
|
139
|
+
base_url = "http://blockchain.info/unspent?active=#{address}"
|
140
|
+
json = fetch_response(base_url, true)
|
141
|
+
|
142
|
+
unspent = []
|
143
|
+
|
144
|
+
json['unspent_outputs'].each do |data|
|
145
|
+
line = []
|
146
|
+
line << reverse_blockchain_tx(data['tx_hash'])
|
147
|
+
line << data['tx_output_n']
|
148
|
+
line << data['script']
|
149
|
+
line << data['value']
|
150
|
+
unspent << line
|
151
|
+
end
|
152
|
+
|
153
|
+
return unspent
|
154
|
+
rescue Exception => e
|
155
|
+
puts e.to_s
|
156
|
+
'Unspent outputs could not be retrieved'
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def blockinfo_balance(address)
|
161
|
+
begin
|
162
|
+
if cache_read(address) == nil
|
163
|
+
puts "cache is empty"
|
164
|
+
json = block_chain('address', address, "&limit=0")
|
165
|
+
if json.key?('final_balance')
|
166
|
+
bal = json['final_balance'] / 100000000.0
|
167
|
+
cache_write(address, bal, BALANCE_CACHE_FOR)
|
168
|
+
else
|
169
|
+
cache_write(address, 'Error', BALANCE_CACHE_FOR)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
bal = cache_read(address)
|
173
|
+
if bal.class == Fixnum
|
174
|
+
bal = bal.to_f
|
175
|
+
end
|
176
|
+
return bal
|
177
|
+
rescue
|
178
|
+
'Balance could not be retrieved'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def blockr_unspent(address)
|
183
|
+
begin
|
184
|
+
base_url = "http://btc.blockr.io/api/v1/address/unspent/#{address}"
|
185
|
+
json = fetch_response(base_url, true)
|
186
|
+
|
187
|
+
unspent = []
|
188
|
+
|
189
|
+
json['data']['unspent'].each do |data|
|
190
|
+
line = []
|
191
|
+
line << data['tx']
|
192
|
+
line << data['n']
|
193
|
+
line << data['script']
|
194
|
+
line << (data['amount'].to_f * 100000000).to_i
|
195
|
+
unspent << line
|
196
|
+
end
|
197
|
+
|
198
|
+
return unspent
|
199
|
+
rescue Exception => e
|
200
|
+
puts e.to_s
|
201
|
+
'Unspent outputs could not be retrieved'
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def blockr_get_all_balances(addresses)
|
206
|
+
begin
|
207
|
+
base = "https://blockr.io/api/v1/address/balance/"
|
208
|
+
|
209
|
+
addresses.each do |address|
|
210
|
+
base = base + address + ','
|
211
|
+
end
|
212
|
+
|
213
|
+
json = fetch_response(URI::encode(base))
|
214
|
+
|
215
|
+
json['data'].each do |data|
|
216
|
+
bal = data['balance']
|
217
|
+
addr = data['address']
|
218
|
+
cache_write(addr, bal, BALANCE_CACHE_FOR)
|
219
|
+
end
|
220
|
+
|
221
|
+
rescue
|
222
|
+
'Balance could not be retrieved'
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def blockr_balance(address)
|
227
|
+
begin
|
228
|
+
if cache_read(address) == nil
|
229
|
+
json = blockr('address/balance', address)
|
230
|
+
if json.key?('data')
|
231
|
+
bal = json['data']['balance'].to_f
|
232
|
+
cache_write(address, bal, BALANCE_CACHE_FOR)
|
233
|
+
else
|
234
|
+
cache_write(address, 'Error', BALANCE_CACHE_FOR)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
return cache_read(address)
|
238
|
+
rescue Exception => e
|
239
|
+
puts e
|
240
|
+
'Balance could not be retrieved'
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def blockr(cmd, address, params = "")
|
245
|
+
if ! blockr_down?
|
246
|
+
begin
|
247
|
+
base_url = "http://blockr.io/api/v1/#{cmd}/#{address}" + params
|
248
|
+
fetch_response(base_url, true)
|
249
|
+
rescue
|
250
|
+
blockr_is_down
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def block_chain(cmd, address, params = "")
|
256
|
+
if ! blockchain_down?
|
257
|
+
begin
|
258
|
+
base_url = "http://blockchain.info/#{cmd}/#{address}?format=json" + params
|
259
|
+
|
260
|
+
puts base_url
|
261
|
+
fetch_response(base_url, true)
|
262
|
+
rescue
|
263
|
+
blockchain_is_down
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def fetch_response(url, do_json=true)
|
269
|
+
resp = Net::HTTP.get_response(URI.parse(url))
|
270
|
+
data = resp.body
|
271
|
+
|
272
|
+
if do_json
|
273
|
+
result = JSON.parse(data)
|
274
|
+
else
|
275
|
+
data
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def reverse_blockchain_tx(hash)
|
280
|
+
bytes = hash.scan(/../).map { |x| x.hex.chr }.join
|
281
|
+
|
282
|
+
bytes = bytes.reverse
|
283
|
+
|
284
|
+
return hash.scan(/../).reverse.join
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
end
|
289
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class OnChain
|
2
|
+
class << self
|
3
|
+
|
4
|
+
|
5
|
+
# With a bunch of HD wallet paths, build a transaction
|
6
|
+
# That pays all the coins to a certain address
|
7
|
+
def sweep(paths, mpk, destination_address)
|
8
|
+
|
9
|
+
master = MoneyTree::Node.from_serialized_address(mpk)
|
10
|
+
|
11
|
+
tx = Bitcoin::Protocol::Tx.new
|
12
|
+
|
13
|
+
amount = 0
|
14
|
+
|
15
|
+
paths.each do |path|
|
16
|
+
|
17
|
+
address = master.node_for_path(path).to_address
|
18
|
+
|
19
|
+
unspent = get_unspent_outs(address)
|
20
|
+
|
21
|
+
unspent.each do |spent|
|
22
|
+
txin = Bitcoin::Protocol::TxIn.new
|
23
|
+
|
24
|
+
txin.prev_out = spent[0]
|
25
|
+
txin.prev_out_index = spent[1]
|
26
|
+
amount += spent[3].to_i
|
27
|
+
|
28
|
+
tx.add_in(txin)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
txout = Bitcoin::Protocol::TxOut.new(amount, Bitcoin::Script.from_string(
|
33
|
+
"OP_DUP OP_HASH160 #{destination_address} " +
|
34
|
+
"OP_EQUALVERIFY OP_CHECKSIG").to_payload)
|
35
|
+
|
36
|
+
tx.add_out(txout)
|
37
|
+
puts tx.to_json
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/lib/onchain.rb
CHANGED
@@ -1,289 +1,4 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
|
4
|
-
|
5
|
-
class << self
|
6
|
-
|
7
|
-
BALANCE_CACHE_FOR = 120
|
8
|
-
API_CACHE_FOR = 60
|
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
|
-
|
24
|
-
|
25
|
-
def get_all_balances(addresses)
|
26
|
-
|
27
|
-
if ! blockr_down?
|
28
|
-
bal = blockr_get_all_balances(addresses)
|
29
|
-
return bal
|
30
|
-
end
|
31
|
-
|
32
|
-
if ! blockchain_down?
|
33
|
-
bal = blockinfo_get_all_balances(addresses)
|
34
|
-
return bal
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def get_balance(address)
|
39
|
-
|
40
|
-
# These guys make 300k per month so hammer them first.
|
41
|
-
if ! blockchain_down?
|
42
|
-
bal = blockinfo_balance(address)
|
43
|
-
if ! bal.instance_of? String
|
44
|
-
return bal
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# Looks like blockchain is down, let's try blockr
|
49
|
-
if ! blockr_down?
|
50
|
-
bal = blockr_balance(address)
|
51
|
-
if ! bal.instance_of? String
|
52
|
-
return bal
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# OK I give up.
|
57
|
-
'Balance could not be retrieved'
|
58
|
-
end
|
59
|
-
|
60
|
-
def send_tx(tx_hex)
|
61
|
-
#payload = { :tx => tx_hex }
|
62
|
-
#HTTParty.post('http://blockchain.info/pushtx', {:body => payload})
|
63
|
-
|
64
|
-
# Blockchain doesn't support multi sig, so only use blockr
|
65
|
-
uri = URI.parse("http://btc.blockr.io/api/v1/tx/push")
|
66
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
67
|
-
|
68
|
-
request = Net::HTTP::Post.new(uri.request_uri)
|
69
|
-
request.body = '{"hex":"' + tx_hex + '"}'
|
70
|
-
response = http.request(request)
|
71
|
-
return response
|
72
|
-
end
|
73
|
-
|
74
|
-
def get_history
|
75
|
-
return []
|
76
|
-
end
|
77
|
-
|
78
|
-
def get_unspent_outs(address)
|
79
|
-
|
80
|
-
|
81
|
-
# Looks like blockchain is down, let's try blockr
|
82
|
-
if ! blockr_down?
|
83
|
-
return blockr_unspent(address)
|
84
|
-
end
|
85
|
-
|
86
|
-
if ! blockchain_down?
|
87
|
-
return blockinfo_unspent(address)
|
88
|
-
end
|
89
|
-
|
90
|
-
# OK I give up.
|
91
|
-
'Unspent outputs could not be retrieved'
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
def blockchain_is_down
|
96
|
-
cache_write(:blockchainapi, 'it is down', 60)
|
97
|
-
end
|
98
|
-
|
99
|
-
def blockchain_down?
|
100
|
-
if cache_read(:blockchainapi) != nil
|
101
|
-
return true
|
102
|
-
end
|
103
|
-
return false
|
104
|
-
end
|
105
|
-
|
106
|
-
def blockr_is_down
|
107
|
-
cache_write(:blockrapi, 'it is down', 60)
|
108
|
-
end
|
109
|
-
|
110
|
-
def blockr_down?
|
111
|
-
if cache_read(:blockrapi) != nil
|
112
|
-
return true
|
113
|
-
end
|
114
|
-
return false
|
115
|
-
end
|
116
|
-
|
117
|
-
def blockinfo_get_all_balances(addresses)
|
118
|
-
begin
|
119
|
-
base = "https://blockchain.info/multiaddr?&simple=true&active="
|
120
|
-
|
121
|
-
addresses.each do |address|
|
122
|
-
base = base + address + '|'
|
123
|
-
end
|
124
|
-
|
125
|
-
json = fetch_response(URI::encode(base))
|
126
|
-
|
127
|
-
addresses.each do |address|
|
128
|
-
bal = json[address]['final_balance'] / 100000000.0
|
129
|
-
cache_write(address, bal, BALANCE_CACHE_FOR)
|
130
|
-
end
|
131
|
-
|
132
|
-
rescue
|
133
|
-
'Balance could not be retrieved'
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def blockinfo_unspent(address)
|
138
|
-
begin
|
139
|
-
base_url = "http://blockchain.info/unspent?active=#{address}"
|
140
|
-
json = fetch_response(base_url, true)
|
141
|
-
|
142
|
-
unspent = []
|
143
|
-
|
144
|
-
json['unspent_outputs'].each do |data|
|
145
|
-
line = []
|
146
|
-
line << reverse_blockchain_tx(data['tx_hash'])
|
147
|
-
line << data['tx_output_n']
|
148
|
-
line << data['script']
|
149
|
-
line << data['value']
|
150
|
-
unspent << line
|
151
|
-
end
|
152
|
-
|
153
|
-
return unspent
|
154
|
-
rescue Exception => e
|
155
|
-
puts e.to_s
|
156
|
-
'Unspent outputs could not be retrieved'
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
def blockinfo_balance(address)
|
161
|
-
begin
|
162
|
-
if cache_read(address) == nil
|
163
|
-
puts "cache is empty"
|
164
|
-
json = block_chain('address', address, "&limit=0")
|
165
|
-
if json.key?('final_balance')
|
166
|
-
bal = json['final_balance'] / 100000000.0
|
167
|
-
cache_write(address, bal, BALANCE_CACHE_FOR)
|
168
|
-
else
|
169
|
-
cache_write(address, 'Error', BALANCE_CACHE_FOR)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
bal = cache_read(address)
|
173
|
-
if bal.class == Fixnum
|
174
|
-
bal = bal.to_f
|
175
|
-
end
|
176
|
-
return bal
|
177
|
-
rescue
|
178
|
-
'Balance could not be retrieved'
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
def blockr_unspent(address)
|
183
|
-
begin
|
184
|
-
base_url = "http://btc.blockr.io/api/v1/address/unspent/#{address}"
|
185
|
-
json = fetch_response(base_url, true)
|
186
|
-
|
187
|
-
unspent = []
|
188
|
-
|
189
|
-
json['data']['unspent'].each do |data|
|
190
|
-
line = []
|
191
|
-
line << data['tx']
|
192
|
-
line << data['n']
|
193
|
-
line << data['script']
|
194
|
-
line << (data['amount'].to_f * 100000000).to_i
|
195
|
-
unspent << line
|
196
|
-
end
|
197
|
-
|
198
|
-
return unspent
|
199
|
-
rescue Exception => e
|
200
|
-
puts e.to_s
|
201
|
-
'Unspent outputs could not be retrieved'
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
def blockr_get_all_balances(addresses)
|
206
|
-
begin
|
207
|
-
base = "https://blockr.io/api/v1/address/balance/"
|
208
|
-
|
209
|
-
addresses.each do |address|
|
210
|
-
base = base + address + ','
|
211
|
-
end
|
212
|
-
|
213
|
-
json = fetch_response(URI::encode(base))
|
214
|
-
|
215
|
-
json['data'].each do |data|
|
216
|
-
bal = data['balance']
|
217
|
-
addr = data['address']
|
218
|
-
cache_write(addr, bal, BALANCE_CACHE_FOR)
|
219
|
-
end
|
220
|
-
|
221
|
-
rescue
|
222
|
-
'Balance could not be retrieved'
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
def blockr_balance(address)
|
227
|
-
begin
|
228
|
-
if cache_read(address) == nil
|
229
|
-
json = blockr('address/balance', address)
|
230
|
-
if json.key?('data')
|
231
|
-
bal = json['data']['balance'].to_f
|
232
|
-
cache_write(address, bal, BALANCE_CACHE_FOR)
|
233
|
-
else
|
234
|
-
cache_write(address, 'Error', BALANCE_CACHE_FOR)
|
235
|
-
end
|
236
|
-
end
|
237
|
-
return cache_read(address)
|
238
|
-
rescue Exception => e
|
239
|
-
puts e
|
240
|
-
'Balance could not be retrieved'
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
def blockr(cmd, address, params = "")
|
245
|
-
if ! blockr_down?
|
246
|
-
begin
|
247
|
-
base_url = "http://blockr.io/api/v1/#{cmd}/#{address}" + params
|
248
|
-
fetch_response(base_url, true)
|
249
|
-
rescue
|
250
|
-
blockr_is_down
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
def block_chain(cmd, address, params = "")
|
256
|
-
if ! blockchain_down?
|
257
|
-
begin
|
258
|
-
base_url = "http://blockchain.info/#{cmd}/#{address}?format=json" + params
|
259
|
-
|
260
|
-
puts base_url
|
261
|
-
fetch_response(base_url, true)
|
262
|
-
rescue
|
263
|
-
blockchain_is_down
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
def fetch_response(url, do_json=true)
|
269
|
-
resp = Net::HTTP.get_response(URI.parse(url))
|
270
|
-
data = resp.body
|
271
|
-
|
272
|
-
if do_json
|
273
|
-
result = JSON.parse(data)
|
274
|
-
else
|
275
|
-
data
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
def reverse_blockchain_tx(hash)
|
280
|
-
bytes = hash.scan(/../).map { |x| x.hex.chr }.join
|
281
|
-
|
282
|
-
bytes = bytes.reverse
|
283
|
-
|
284
|
-
return hash.scan(/../).reverse.join
|
285
|
-
end
|
286
|
-
|
287
|
-
|
288
|
-
end
|
289
|
-
end
|
1
|
+
require 'onchain/block_chain.rb'
|
2
|
+
require 'onchain/sweeper.rb'
|
3
|
+
require 'money-tree'
|
4
|
+
require 'bitcoin'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: onchain
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Purton
|
@@ -11,7 +11,7 @@ cert_chain: []
|
|
11
11
|
date: 2014-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -25,21 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: ir_b
|
28
|
+
name: rspec
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - ">="
|
@@ -53,13 +39,13 @@ dependencies:
|
|
53
39
|
- !ruby/object:Gem::Version
|
54
40
|
version: '0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
42
|
+
name: money-tree
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
45
|
- - ">="
|
60
46
|
- !ruby/object:Gem::Version
|
61
47
|
version: '0'
|
62
|
-
type: :
|
48
|
+
type: :runtime
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
@@ -67,13 +53,13 @@ dependencies:
|
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
56
|
+
name: bitcoin-ruby
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - ">="
|
74
60
|
- !ruby/object:Gem::Version
|
75
61
|
version: '0'
|
76
|
-
type: :
|
62
|
+
type: :runtime
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
@@ -82,16 +68,14 @@ dependencies:
|
|
82
68
|
version: '0'
|
83
69
|
description: Call 3rd party API's but also switch API's if a 3rd party is down
|
84
70
|
email:
|
85
|
-
- ian@onchain.
|
71
|
+
- ian@onchain.io
|
86
72
|
executables: []
|
87
73
|
extensions: []
|
88
74
|
extra_rdoc_files: []
|
89
75
|
files:
|
90
|
-
- ".gitignore"
|
91
|
-
- README.md
|
92
76
|
- lib/onchain.rb
|
93
|
-
- lib/onchain/
|
94
|
-
- onchain.
|
77
|
+
- lib/onchain/block_chain.rb
|
78
|
+
- lib/onchain/sweeper.rb
|
95
79
|
homepage: https://github.com/onchain/onchain-gem
|
96
80
|
licenses: []
|
97
81
|
metadata: {}
|
data/.gitignore
DELETED
data/README.md
DELETED
data/lib/onchain/version.rb
DELETED
data/onchain.gemspec
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
require File.expand_path('../lib/onchain/version', __FILE__)
|
3
|
-
|
4
|
-
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = ["Ian Purton"]
|
6
|
-
gem.email = ["ian@onchain.com"]
|
7
|
-
gem.summary = %q{Ruby wrapper for various 3rd-party bitcoin APIs}
|
8
|
-
gem.description = %q{Call 3rd party API's but also switch API's if a 3rd party is down}
|
9
|
-
gem.homepage = "https://github.com/onchain/onchain-gem"
|
10
|
-
|
11
|
-
gem.files = `git ls-files`.split($\)
|
12
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
-
gem.name = "onchain"
|
15
|
-
gem.require_paths = ["lib"]
|
16
|
-
gem.version = Onchain::VERSION
|
17
|
-
|
18
|
-
%w{rspec vcr ir_b guard-rspec webmock}.each do |gem_library|
|
19
|
-
gem.add_development_dependency gem_library
|
20
|
-
end
|
21
|
-
end
|