sibit 0.4.0 → 0.5.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/bin/sibit +6 -0
- data/lib/sibit/version.rb +1 -1
- data/lib/sibit.rb +26 -15
- data/test/test_sibit.rb +12 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 478069971b53901e3037034ee2830d5b66154a77fc1b5087b17f15e94870ca39
|
|
4
|
+
data.tar.gz: 48039e52d5835aef4515e28c3fa3575e946e99556fcdb424f71c9f4c022f66e5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 80d804206aa880655b81a696a73558a47fc8dd1eee00d0c82fe7965283469d0b0586e56cace8d6309114af8572f8781deda7c259f6522317a9180c889a3e7fe5
|
|
7
|
+
data.tar.gz: 92d14ce0a35f45a1d994615a18fdde4472b33e39ff30c64f22606c0691bf37beed91db3a0c71f8a0f9f8b690da11eae24b8606030483213b5d34f42aae36d0fb
|
data/bin/sibit
CHANGED
|
@@ -31,6 +31,8 @@ begin
|
|
|
31
31
|
opts = Slop.parse(ARGV, strict: true, help: true) do |o|
|
|
32
32
|
o.banner = "Usage (#{Sibit::VERSION}): sibit [options] command [args]
|
|
33
33
|
Commands are:
|
|
34
|
+
price: Get current price of BTC in USD
|
|
35
|
+
latest: Get hash of the latest block
|
|
34
36
|
generate: Generate a new private key
|
|
35
37
|
create: Create a public Bitcoin address from the key
|
|
36
38
|
balance: Check the balance of the Bitcoin address
|
|
@@ -48,6 +50,10 @@ Options are:"
|
|
|
48
50
|
raise 'Try --help' if opts.arguments.empty?
|
|
49
51
|
sibit = Sibit.new(log: opts[:verbose] ? STDOUT : nil)
|
|
50
52
|
case opts.arguments[0]
|
|
53
|
+
when 'price'
|
|
54
|
+
puts sibit.price
|
|
55
|
+
when 'latest'
|
|
56
|
+
puts sibit.latest
|
|
51
57
|
when 'generate'
|
|
52
58
|
puts sibit.generate
|
|
53
59
|
when 'create'
|
data/lib/sibit/version.rb
CHANGED
data/lib/sibit.rb
CHANGED
|
@@ -34,6 +34,9 @@ require 'json'
|
|
|
34
34
|
# Copyright:: Copyright (c) 2019 Yegor Bugayenko
|
|
35
35
|
# License:: MIT
|
|
36
36
|
class Sibit
|
|
37
|
+
# If something goes wrong.
|
|
38
|
+
class Error < StandardError; end
|
|
39
|
+
|
|
37
40
|
# Constructor.
|
|
38
41
|
#
|
|
39
42
|
# You may provide the log you want to see the messages in. If you don't
|
|
@@ -46,8 +49,8 @@ class Sibit
|
|
|
46
49
|
|
|
47
50
|
# Current price of 1 BTC.
|
|
48
51
|
def price(cur = 'USD')
|
|
49
|
-
h = get_json('
|
|
50
|
-
raise "Unrecognized currency #{cur}" if h.nil?
|
|
52
|
+
h = get_json('/ticker')[cur.upcase]
|
|
53
|
+
raise Error, "Unrecognized currency #{cur}" if h.nil?
|
|
51
54
|
h['15m']
|
|
52
55
|
end
|
|
53
56
|
|
|
@@ -63,7 +66,7 @@ class Sibit
|
|
|
63
66
|
|
|
64
67
|
# Gets the balance of the address, in satoshi.
|
|
65
68
|
def balance(address)
|
|
66
|
-
json = get_json("
|
|
69
|
+
json = get_json("/rawaddr/#{address}")
|
|
67
70
|
debug("Total transactions: #{json['n_tx']}")
|
|
68
71
|
debug("Received/sent: #{json['total_received']}/#{json['total_sent']}")
|
|
69
72
|
json['final_balance']
|
|
@@ -92,7 +95,7 @@ class Sibit
|
|
|
92
95
|
unspent = 0
|
|
93
96
|
size = 100
|
|
94
97
|
utxos = get_json(
|
|
95
|
-
"
|
|
98
|
+
"/unspent?active=#{sources.join('|')}&limit=1000"
|
|
96
99
|
)['unspent_outputs']
|
|
97
100
|
debug("#{utxos.count} UTXOs found:")
|
|
98
101
|
utxos.each do |utxo|
|
|
@@ -107,7 +110,7 @@ class Sibit
|
|
|
107
110
|
debug(" #{utxo['value']}/#{utxo['confirmations']} at #{utxo['tx_hash_big_endian']}")
|
|
108
111
|
break if unspent > satoshi
|
|
109
112
|
end
|
|
110
|
-
raise "Not enough funds to send #{amount}, only #{unspent} left" if unspent < satoshi
|
|
113
|
+
raise Error, "Not enough funds to send #{amount}, only #{unspent} left" if unspent < satoshi
|
|
111
114
|
builder.output(satoshi, target)
|
|
112
115
|
tx = builder.tx(
|
|
113
116
|
input_value: unspent,
|
|
@@ -118,6 +121,22 @@ class Sibit
|
|
|
118
121
|
tx.hash
|
|
119
122
|
end
|
|
120
123
|
|
|
124
|
+
# Gets the hash of the latest block.
|
|
125
|
+
def latest
|
|
126
|
+
get_json('/latestblock')['hash']
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Send GET request to the Blockchain API and return JSON response.
|
|
130
|
+
# This method will also log the process and will validate the
|
|
131
|
+
# response for correctness.
|
|
132
|
+
def get_json(uri)
|
|
133
|
+
start = Time.now
|
|
134
|
+
res = Net::HTTP.get_response(URI('https://blockchain.info' + uri))
|
|
135
|
+
raise Error, "Failed to retrieve #{uri}: #{res.code}" unless res.code == '200'
|
|
136
|
+
debug("GET #{uri}: #{res.code} in #{age(start)}")
|
|
137
|
+
JSON.parse(res.body)
|
|
138
|
+
end
|
|
139
|
+
|
|
121
140
|
private
|
|
122
141
|
|
|
123
142
|
# Convert text to amount.
|
|
@@ -138,7 +157,7 @@ class Sibit
|
|
|
138
157
|
when 'XL'
|
|
139
158
|
return 250 * size
|
|
140
159
|
else
|
|
141
|
-
raise "Can't understand the fee: #{fee.inspect}"
|
|
160
|
+
raise Error, "Can't understand the fee: #{fee.inspect}"
|
|
142
161
|
end
|
|
143
162
|
end
|
|
144
163
|
|
|
@@ -157,18 +176,10 @@ class Sibit
|
|
|
157
176
|
start = Time.now
|
|
158
177
|
uri = URI('https://blockchain.info/pushtx')
|
|
159
178
|
res = Net::HTTP.post_form(uri, tx: body)
|
|
160
|
-
raise "Failed to post tx to #{uri}: #{res.code}" unless res.code == '200'
|
|
179
|
+
raise Error, "Failed to post tx to #{uri}: #{res.code}" unless res.code == '200'
|
|
161
180
|
debug("POST #{uri}: #{res.code} in #{age(start)}")
|
|
162
181
|
end
|
|
163
182
|
|
|
164
|
-
def get_json(uri)
|
|
165
|
-
start = Time.now
|
|
166
|
-
res = Net::HTTP.get_response(URI(uri))
|
|
167
|
-
raise "Failed to retrieve #{uri}: #{res.code}" unless res.code == '200'
|
|
168
|
-
debug("GET #{uri}: #{res.code} in #{age(start)}")
|
|
169
|
-
JSON.parse(res.body)
|
|
170
|
-
end
|
|
171
|
-
|
|
172
183
|
def debug(msg)
|
|
173
184
|
if @log.respond_to?(:debug)
|
|
174
185
|
@log.debug(msg)
|
data/test/test_sibit.rb
CHANGED
|
@@ -57,7 +57,7 @@ class TestSibit < Minitest::Test
|
|
|
57
57
|
assert(/^1[0-9a-zA-Z]+$/.match?(address))
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
def
|
|
60
|
+
def test_get_balance
|
|
61
61
|
stub_request(
|
|
62
62
|
:get,
|
|
63
63
|
'https://blockchain.info/rawaddr/1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f'
|
|
@@ -68,7 +68,17 @@ class TestSibit < Minitest::Test
|
|
|
68
68
|
assert_equal(100, balance)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
def
|
|
71
|
+
def test_get_latest_block
|
|
72
|
+
stub_request(:get, 'https://blockchain.info/latestblock').to_return(
|
|
73
|
+
status: 200,
|
|
74
|
+
body: '{"hash": "0000000000000538200a48202ca6340e983646ca088c7618ae82d68e0c76ef5a"}'
|
|
75
|
+
)
|
|
76
|
+
sibit = Sibit.new
|
|
77
|
+
hash = sibit.latest
|
|
78
|
+
assert_equal('0000000000000538200a48202ca6340e983646ca088c7618ae82d68e0c76ef5a', hash)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def test_send_payment
|
|
72
82
|
json = {
|
|
73
83
|
unspent_outputs: [
|
|
74
84
|
{
|