sibit 0.19.2 → 0.20.2
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/.rultor.yml +2 -2
- data/bin/sibit +11 -2
- data/features/cli.feature +1 -1
- data/lib/sibit/bestof.rb +3 -2
- data/lib/sibit/btc.rb +20 -4
- data/lib/sibit/firstof.rb +4 -2
- data/lib/sibit/version.rb +1 -1
- data/sibit.gemspec +1 -1
- data/test/test_btc.rb +34 -0
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0734db295c639e548f4b51d170e87bbabe2c6b94d7d4ba7e858716b74f145185
|
|
4
|
+
data.tar.gz: 9ff51aecc8e78f13917907f62e6485800531dd7d36198df80b5a089831fcbfcc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0095805aee3fbe209a73bcda6a9832e9aa26b43414232c6fa59d6fbed09a7648bcd6739e76a558106f86a152a9ebbf5b36c32afffd927f9a2f5feaa34fa4c4d4'
|
|
7
|
+
data.tar.gz: 0fde0492c34a1f636180f01d0a331da019e8b461b0819909869cd9f0b5b3f6fb9070f1d79fa6a80f87f3f8903975abeeb7a6e30e9b9b8a4fa5de7f8fbf522794
|
data/.rultor.yml
CHANGED
|
@@ -5,7 +5,7 @@ install: |
|
|
|
5
5
|
sudo bundle install --no-color "--gemfile=$(pwd)/Gemfile"
|
|
6
6
|
release:
|
|
7
7
|
script: |-
|
|
8
|
-
bundle exec rake
|
|
8
|
+
bundle exec rake clean test rubocop copyright
|
|
9
9
|
sed -i "s/1\.0\.snapshot/${tag}/g" lib/sibit/version.rb
|
|
10
10
|
git add lib/sibit/version.rb
|
|
11
11
|
git commit -m "version set to ${tag}"
|
|
@@ -14,7 +14,7 @@ release:
|
|
|
14
14
|
gem push *.gem --config-file ../rubygems.yml
|
|
15
15
|
merge:
|
|
16
16
|
script: |-
|
|
17
|
-
bundle exec rake
|
|
17
|
+
bundle exec rake clean test rubocop copyright
|
|
18
18
|
deploy:
|
|
19
19
|
script: |-
|
|
20
20
|
echo "There is nothing to deploy"
|
data/bin/sibit
CHANGED
|
@@ -29,9 +29,12 @@ require 'retriable_proxy'
|
|
|
29
29
|
require_relative '../lib/sibit'
|
|
30
30
|
require_relative '../lib/sibit/version'
|
|
31
31
|
require_relative '../lib/sibit/blockchain'
|
|
32
|
+
require_relative '../lib/sibit/blockchair'
|
|
32
33
|
require_relative '../lib/sibit/btc'
|
|
33
34
|
require_relative '../lib/sibit/bitcoinchain'
|
|
35
|
+
require_relative '../lib/sibit/cex'
|
|
34
36
|
require_relative '../lib/sibit/earn'
|
|
37
|
+
require_relative '../lib/sibit/fake'
|
|
35
38
|
require_relative '../lib/sibit/firstof'
|
|
36
39
|
|
|
37
40
|
begin
|
|
@@ -62,7 +65,7 @@ Options are:"
|
|
|
62
65
|
o.array(
|
|
63
66
|
'--api',
|
|
64
67
|
'Ordered List of APIs to use, e.g. "earn,blockchain,btc,bitcoinchain"',
|
|
65
|
-
default: %w[earn blockchain btc bitcoinchain]
|
|
68
|
+
default: %w[earn blockchain btc bitcoinchain blockchair cex]
|
|
66
69
|
)
|
|
67
70
|
end
|
|
68
71
|
rescue Slop::Error => ex
|
|
@@ -79,6 +82,12 @@ Options are:"
|
|
|
79
82
|
api = Sibit::Btc.new(http: http, log: log, dry: opts[:dry])
|
|
80
83
|
elsif a == 'bitcoinchain'
|
|
81
84
|
api = Sibit::Bitcoinchain.new(http: http, log: log, dry: opts[:dry])
|
|
85
|
+
elsif a == 'blockchair'
|
|
86
|
+
api = Sibit::Blockchair.new(http: http, log: log, dry: opts[:dry])
|
|
87
|
+
elsif a == 'cex'
|
|
88
|
+
api = Sibit::Cex.new(http: http, log: log, dry: opts[:dry])
|
|
89
|
+
elsif a == 'fake'
|
|
90
|
+
api = Sibit::Fake.new
|
|
82
91
|
elsif a == 'earn'
|
|
83
92
|
api = Sibit::Earn.new(http: http, log: log, dry: opts[:dry])
|
|
84
93
|
else
|
|
@@ -87,7 +96,7 @@ Options are:"
|
|
|
87
96
|
api = RetriableProxy.for_object(api, on: Sibit::Error) if opts[:attempts] > 1
|
|
88
97
|
api
|
|
89
98
|
end
|
|
90
|
-
sibit = Sibit.new(log: log, api: Sibit::FirstOf.new(apis, log: log))
|
|
99
|
+
sibit = Sibit.new(log: log, api: Sibit::FirstOf.new(apis, log: log, verbose: true))
|
|
91
100
|
case opts.arguments[0]
|
|
92
101
|
when 'price'
|
|
93
102
|
puts sibit.price
|
data/features/cli.feature
CHANGED
data/lib/sibit/bestof.rb
CHANGED
|
@@ -32,9 +32,10 @@ class Sibit
|
|
|
32
32
|
# Best of API.
|
|
33
33
|
class BestOf
|
|
34
34
|
# Constructor.
|
|
35
|
-
def initialize(list, log: Sibit::Log.new)
|
|
35
|
+
def initialize(list, log: Sibit::Log.new, verbose: false)
|
|
36
36
|
@list = list
|
|
37
37
|
@log = log
|
|
38
|
+
@verbose = verbose
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
# Current price of BTC in USD (float returned).
|
|
@@ -106,7 +107,7 @@ class Sibit
|
|
|
106
107
|
begin
|
|
107
108
|
results << yield(api)
|
|
108
109
|
rescue Sibit::Error => e
|
|
109
|
-
@log.info("The API #{api.class.name} failed at #{method}(): #{e.message}")
|
|
110
|
+
@log.info("The API #{api.class.name} failed at #{method}(): #{e.message}") if @verbose
|
|
110
111
|
end
|
|
111
112
|
end
|
|
112
113
|
if results.empty?
|
data/lib/sibit/btc.rb
CHANGED
|
@@ -58,7 +58,16 @@ class Sibit
|
|
|
58
58
|
@log.info("The balance of #{address} is zero (not found)")
|
|
59
59
|
return 0
|
|
60
60
|
end
|
|
61
|
-
|
|
61
|
+
data = json['data']
|
|
62
|
+
if data.nil?
|
|
63
|
+
@log.info("The balance of #{address} is probably zero (not found)")
|
|
64
|
+
return 0
|
|
65
|
+
end
|
|
66
|
+
txns = data['list']
|
|
67
|
+
if txns.nil?
|
|
68
|
+
@log.info("The balance of #{address} is probably zero (not found)")
|
|
69
|
+
return 0
|
|
70
|
+
end
|
|
62
71
|
balance = txns.map { |tx| tx['value'] }.inject(&:+) || 0
|
|
63
72
|
@log.info("The balance of #{address} is #{balance}, total txns: #{txns.count}")
|
|
64
73
|
balance
|
|
@@ -86,6 +95,7 @@ class Sibit
|
|
|
86
95
|
data = json['data']
|
|
87
96
|
raise Sibit::Error, "The block #{hash} not found" if data.nil?
|
|
88
97
|
h = data['height']
|
|
98
|
+
raise Sibit::Error, "The block #{hash} found but the height is absent" if h.nil?
|
|
89
99
|
@log.info("The height of #{hash} is #{h}")
|
|
90
100
|
h
|
|
91
101
|
end
|
|
@@ -115,7 +125,9 @@ class Sibit
|
|
|
115
125
|
)
|
|
116
126
|
data = json['data']
|
|
117
127
|
raise Sibit::Error, "The address #{hash} not found" if data.nil?
|
|
118
|
-
data['list']
|
|
128
|
+
txns = data['list']
|
|
129
|
+
next if txns.nil?
|
|
130
|
+
txns.each do |u|
|
|
119
131
|
outs = Sibit::Json.new(http: @http, log: @log).get(
|
|
120
132
|
URI("https://chain.api.btc.com/v3/tx/#{u['tx_hash']}?verbose=3")
|
|
121
133
|
)['data']['outputs']
|
|
@@ -164,9 +176,13 @@ class Sibit
|
|
|
164
176
|
psize = 50
|
|
165
177
|
all = []
|
|
166
178
|
loop do
|
|
167
|
-
|
|
179
|
+
data = Sibit::Json.new(http: @http, log: @log).get(
|
|
168
180
|
URI("https://chain.api.btc.com/v3/block/#{hash}/tx?page=#{page}&pagesize=#{psize}")
|
|
169
|
-
)['data']
|
|
181
|
+
)['data']
|
|
182
|
+
raise Sibit::Error, "The block #{hash} has no data at page #{page}" if data.nil?
|
|
183
|
+
list = data['list']
|
|
184
|
+
raise Sibit::Error, "The list is empty for block #{hash} at page #{page}" if list.nil?
|
|
185
|
+
txns = list.map do |t|
|
|
170
186
|
{
|
|
171
187
|
hash: t['hash'],
|
|
172
188
|
outputs: t['outputs'].reject { |o| o['spent_by_tx'] }.map do |o|
|
data/lib/sibit/firstof.rb
CHANGED
|
@@ -32,9 +32,10 @@ class Sibit
|
|
|
32
32
|
# First of API.
|
|
33
33
|
class FirstOf
|
|
34
34
|
# Constructor.
|
|
35
|
-
def initialize(list, log: Sibit::Log.new)
|
|
35
|
+
def initialize(list, log: Sibit::Log.new, verbose: false)
|
|
36
36
|
@list = list
|
|
37
37
|
@log = log
|
|
38
|
+
@verbose = verbose
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
# Current price of BTC in USD (float returned).
|
|
@@ -104,12 +105,13 @@ class Sibit
|
|
|
104
105
|
done = false
|
|
105
106
|
result = nil
|
|
106
107
|
@list.each do |api|
|
|
108
|
+
@log.info("Calling #{api.class.name}##{method}()...")
|
|
107
109
|
begin
|
|
108
110
|
result = yield api
|
|
109
111
|
done = true
|
|
110
112
|
break
|
|
111
113
|
rescue Sibit::Error => e
|
|
112
|
-
@log.info("The API #{api.class.name} failed at #{method}(): #{e.message}")
|
|
114
|
+
@log.info("The API #{api.class.name} failed at #{method}(): #{e.message}") if @verbose
|
|
113
115
|
end
|
|
114
116
|
end
|
|
115
117
|
unless done
|
data/lib/sibit/version.rb
CHANGED
data/sibit.gemspec
CHANGED
|
@@ -55,7 +55,7 @@ and Ruby 2.3+.'
|
|
|
55
55
|
s.add_runtime_dependency 'retriable_proxy', '1.0.2'
|
|
56
56
|
s.add_runtime_dependency 'slop', '~> 4.6'
|
|
57
57
|
s.add_development_dependency 'aruba', '~> 0.14.1'
|
|
58
|
-
s.add_development_dependency 'codecov', '0.
|
|
58
|
+
s.add_development_dependency 'codecov', '0.2.8'
|
|
59
59
|
s.add_development_dependency 'cucumber', '~> 1.3.17'
|
|
60
60
|
s.add_development_dependency 'debase', '0.2.2'
|
|
61
61
|
s.add_development_dependency 'minitest', '5.5.0'
|
data/test/test_btc.rb
CHANGED
|
@@ -42,6 +42,28 @@ class TestBtc < Minitest::Test
|
|
|
42
42
|
assert_equal(0, balance)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
+
def test_get_zero_balance_no_txns
|
|
46
|
+
stub_request(
|
|
47
|
+
:get,
|
|
48
|
+
'https://chain.api.btc.com/v3/address/1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f/unspent'
|
|
49
|
+
).to_return(body: '{"data":{}}')
|
|
50
|
+
sibit = Sibit::Btc.new
|
|
51
|
+
balance = sibit.balance('1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f')
|
|
52
|
+
assert(balance.is_a?(Integer))
|
|
53
|
+
assert_equal(0, balance)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_get_broken_balance
|
|
57
|
+
stub_request(
|
|
58
|
+
:get,
|
|
59
|
+
'https://chain.api.btc.com/v3/address/1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f/unspent'
|
|
60
|
+
).to_return(body: '{}')
|
|
61
|
+
sibit = Sibit::Btc.new
|
|
62
|
+
balance = sibit.balance('1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f')
|
|
63
|
+
assert(balance.is_a?(Integer))
|
|
64
|
+
assert_equal(0, balance)
|
|
65
|
+
end
|
|
66
|
+
|
|
45
67
|
def test_get_empty_balance
|
|
46
68
|
stub_request(
|
|
47
69
|
:get,
|
|
@@ -64,6 +86,18 @@ class TestBtc < Minitest::Test
|
|
|
64
86
|
assert_equal(123, balance)
|
|
65
87
|
end
|
|
66
88
|
|
|
89
|
+
def test_fetch_block_broken
|
|
90
|
+
hash = '000000000000000007341915521967247f1dec17b3a311b8a8f4495392f1439b'
|
|
91
|
+
stub_request(:get, "https://chain.api.btc.com/v3/block/#{hash}")
|
|
92
|
+
.to_return(body: '{"data": {"next_block_hash": "n", "hash": "h", "prev_block_hash": "p"}}')
|
|
93
|
+
stub_request(:get, "https://chain.api.btc.com/v3/block/#{hash}/tx?page=1&pagesize=50")
|
|
94
|
+
.to_return(body: '{}')
|
|
95
|
+
sibit = Sibit::Btc.new
|
|
96
|
+
assert_raises Sibit::Error do
|
|
97
|
+
sibit.block(hash)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
67
101
|
def test_fetch_block
|
|
68
102
|
hash = '000000000000000007341915521967247f1dec17b3a311b8a8f4495392f1439b'
|
|
69
103
|
stub_request(:get, "https://chain.api.btc.com/v3/block/#{hash}")
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sibit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.20.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yegor Bugayenko
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-08-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: backtrace
|
|
@@ -114,14 +114,14 @@ dependencies:
|
|
|
114
114
|
requirements:
|
|
115
115
|
- - '='
|
|
116
116
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: 0.
|
|
117
|
+
version: 0.2.8
|
|
118
118
|
type: :development
|
|
119
119
|
prerelease: false
|
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
121
|
requirements:
|
|
122
122
|
- - '='
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: 0.
|
|
124
|
+
version: 0.2.8
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
126
|
name: cucumber
|
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|