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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: db71c5de986c5aeacfb60ddde907c84eade4b53e2b764f513cd6ea20c7a95c45
4
- data.tar.gz: c79bc1c5b9c544bcc16a61fff3912f09dd5b05152d5cbf667b418d5207d37575
3
+ metadata.gz: 0734db295c639e548f4b51d170e87bbabe2c6b94d7d4ba7e858716b74f145185
4
+ data.tar.gz: 9ff51aecc8e78f13917907f62e6485800531dd7d36198df80b5a089831fcbfcc
5
5
  SHA512:
6
- metadata.gz: 951c554ef902b64007c6807976c99f44f909a28730bff366135d5fb2728cae935df206fd065f9500d4f885982c10175c9775ba3001bb37de42ad2f2969dd45ee
7
- data.tar.gz: b60396b85498717187962637e00008b394eddcb030cdfb5839b3d043bfc086974f05f638057940f621ab1d7d60016857ed19d7bb0354325adcd3e5ebc964f3da
6
+ metadata.gz: '0095805aee3fbe209a73bcda6a9832e9aa26b43414232c6fa59d6fbed09a7648bcd6739e76a558106f86a152a9ebbf5b36c32afffd927f9a2f5feaa34fa4c4d4'
7
+ data.tar.gz: 0fde0492c34a1f636180f01d0a331da019e8b461b0819909869cd9f0b5b3f6fb9070f1d79fa6a80f87f3f8903975abeeb7a6e30e9b9b8a4fa5de7f8fbf522794
@@ -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
@@ -31,5 +31,5 @@ Feature: Command Line Processing
31
31
  Then Exit code is zero
32
32
 
33
33
  Scenario: Bitcoin fees can be printed
34
- When I run bin/sibit with "fees --verbose"
34
+ When I run bin/sibit with "fees --verbose --api=fake"
35
35
  Then Exit code is zero
@@ -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?
@@ -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
- txns = json['data']['list']
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'].each do |u|
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
- txns = Sibit::Json.new(http: @http, log: @log).get(
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']['list'].map do |t|
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|
@@ -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
@@ -26,5 +26,5 @@
26
26
  # License:: MIT
27
27
  class Sibit
28
28
  # Current version of the library.
29
- VERSION = '0.19.2'
29
+ VERSION = '0.20.2'
30
30
  end
@@ -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.1.10'
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'
@@ -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.19.2
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-07-08 00:00:00.000000000 Z
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.1.10
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.1.10
124
+ version: 0.2.8
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: cucumber
127
127
  requirement: !ruby/object:Gem::Requirement