sibit 0.14.2 → 0.14.3

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: 80dd8e6fa8034a499c63c15f1333cf366800c85da969af2891b392cc7a09c6ac
4
- data.tar.gz: f8126179a4de258e575daf7dc04e9e21cd5bd31c214699573366b7ede67eacca
3
+ metadata.gz: e3746b345c4e7b36083c7a2377e4a5449532116978e38f964ac558046670fb5d
4
+ data.tar.gz: 480071555f2cc5e4b15a81274b526fb74a75c223d7b98a98226a134dd87e0e03
5
5
  SHA512:
6
- metadata.gz: 8ba3f4cd38f43af06f5399caf63be7e48cbcfa63192ceec6c42d892d92800863773e482cbc3a431ba4843042db85b970950d65bbc4c299cf0ec18fc81f2456ab
7
- data.tar.gz: b6a759fc3c29c1ca6d6cfad246501ca36abfc81f7ef4caebdcf0e77ed462e0a97328e61d3dfac23d47f56b7a5d6fc8e1ecc44e0cf3267eb86d5512c379fb03ee
6
+ metadata.gz: '097f3d44a66b8ef449e26429ec068bc8395258d80a2e0d5f520f9af24f5e0323d1f83f2f41e691d9daee570fb9527288c4b721ffdfa43762eafd1ef8c62d8095'
7
+ data.tar.gz: 8e9d7c89c01e6d537d159e16af0facdffbee6ea1ed4c16104a1c1fd33e4342b0a0a44bc7b3b5b2b5b45e11fa0fd222b4ac8e54aa4de6a75e416e4837540bc796
data/bin/sibit CHANGED
@@ -31,6 +31,7 @@ require_relative '../lib/sibit/version'
31
31
  require_relative '../lib/sibit/blockchain'
32
32
  require_relative '../lib/sibit/btc'
33
33
  require_relative '../lib/sibit/bitcoinchain'
34
+ require_relative '../lib/sibit/earn'
34
35
 
35
36
  begin
36
37
  begin
@@ -57,7 +58,11 @@ Options are:"
57
58
  exit
58
59
  end
59
60
  o.bool '--verbose', 'Print all possible debug messages'
60
- o.array '--api', 'Ordered List of APIs to use, e.g. "blockchain,btc"', default: ['blockchain']
61
+ o.array(
62
+ '--api',
63
+ 'Ordered List of APIs to use, e.g. "earn,blockchain,btc,bitcoinchain"',
64
+ default: %w[earn blockchain btc bitcoinchain]
65
+ )
61
66
  end
62
67
  rescue Slop::Error => ex
63
68
  raise ex.message
@@ -73,6 +78,8 @@ Options are:"
73
78
  api = Sibit::Btc.new(http: http, log: log, dry: opts[:dry])
74
79
  elsif a == 'bitcoinchain'
75
80
  api = Sibit::Bitcoinchain.new(http: http, log: log, dry: opts[:dry])
81
+ elsif a == 'earn'
82
+ api = Sibit::Earn.new(http: http, log: log, dry: opts[:dry])
76
83
  else
77
84
  raise Sibit::Error, "Unknown API \"#{a}\""
78
85
  end
@@ -60,11 +60,6 @@ class Sibit
60
60
  raise Sibit::Error, 'Not implemented yet'
61
61
  end
62
62
 
63
- # Sends a payment and returns the transaction hash.
64
- def pay(_amount, _fee, _sources, _target, _change)
65
- raise Sibit::Error, 'Not implemented yet'
66
- end
67
-
68
63
  # Gets the hash of the latest block.
69
64
  def latest
70
65
  Sibit::Json.new(http: @http, log: @log).get(
@@ -72,6 +67,16 @@ class Sibit
72
67
  )['hash']
73
68
  end
74
69
 
70
+ # Fetch all unspent outputs per address.
71
+ def utxos(_sources)
72
+ raise Sibit::Error, 'Not implemented yet'
73
+ end
74
+
75
+ # Push this transaction (in hex format) to the network.
76
+ def push(_hex)
77
+ raise Sibit::Error, 'Not implemented yet'
78
+ end
79
+
75
80
  # This method should fetch a Blockchain block and return as a hash. Raises
76
81
  # an exception if the block is not found.
77
82
  def block(hash)
@@ -67,85 +67,33 @@ class Sibit
67
67
  json['final_balance']
68
68
  end
69
69
 
70
- # Get recommended fees, in satoshi per byte. The method returns
71
- # a hash: { S: 12, M: 45, L: 100, XL: 200 }
70
+ # Get recommended fees.
72
71
  def fees
73
- json = Sibit::Json.new(http: @http, log: @log).get(
74
- URI('https://bitcoinfees.earn.com/api/v1/fees/recommended')
75
- )
76
- @log.info("Current recommended Bitcoin fees: \
77
- #{json['hourFee']}/#{json['halfHourFee']}/#{json['fastestFee']} sat/byte")
78
- {
79
- S: json['hourFee'] / 3,
80
- M: json['hourFee'],
81
- L: json['halfHourFee'],
82
- XL: json['fastestFee']
83
- }
72
+ raise Sibit::Error, 'fees() not implemented yet'
84
73
  end
85
74
 
86
- # Sends a payment and returns the transaction hash.
87
- def pay(amount, fee, sources, target, change)
88
- p = price('USD')
89
- satoshi = satoshi(amount)
90
- f = mfee(fee, size_of(amount, sources))
91
- satoshi += f if f.negative?
92
- raise Error, "The fee #{f.abs} covers the entire amount" if satoshi.zero?
93
- raise Error, "The fee #{f.abs} is bigger than the amount #{satoshi}" if satoshi.negative?
94
- builder = Bitcoin::Builder::TxBuilder.new
95
- unspent = 0
96
- size = 100
97
- utxos = Sibit::Json.new(http: @http, log: @log).get(
75
+ # Fetch all unspent outputs per address.
76
+ def utxos(sources)
77
+ Sibit::Json.new(http: @http, log: @log).get(
98
78
  URI("https://blockchain.info/unspent?active=#{sources.keys.join('|')}&limit=1000")
99
- )['unspent_outputs']
100
- @log.info("#{utxos.count} UTXOs found, these will be used \
101
- (value/confirmations at tx_hash):")
102
- utxos.each do |utxo|
103
- unspent += utxo['value']
104
- builder.input do |i|
105
- i.prev_out(utxo['tx_hash_big_endian'])
106
- i.prev_out_index(utxo['tx_output_n'])
107
- i.prev_out_script = [utxo['script']].pack('H*')
108
- address = Bitcoin::Script.new([utxo['script']].pack('H*')).get_address
109
- i.signature_key(key(sources[address]))
110
- end
111
- size += 180
112
- @log.info(
113
- " #{num(utxo['value'], p)}/#{utxo['confirmations']} at #{utxo['tx_hash_big_endian']}"
114
- )
115
- break if unspent > satoshi
79
+ )['unspent_outputs'].map do |u|
80
+ {
81
+ value: u['value'],
82
+ hash: u['tx_hash_big_endian'],
83
+ index: u['tx_output_n'],
84
+ confirmations: u['confirmations'],
85
+ script: [u['script']].pack('H*')
86
+ }
116
87
  end
117
- if unspent < satoshi
118
- raise Error, "Not enough funds to send #{num(satoshi, p)}, only #{num(unspent, p)} left"
119
- end
120
- builder.output(satoshi, target)
121
- f = mfee(fee, size)
122
- tx = builder.tx(
123
- input_value: unspent,
124
- leave_fee: true,
125
- extra_fee: [f, Bitcoin.network[:min_tx_fee]].max,
126
- change_address: change
88
+ end
89
+
90
+ # Push this transaction (in hex format) to the network.
91
+ def push(hex)
92
+ return if @dry
93
+ Sibit::Json.new(http: @http, log: @log).post(
94
+ URI('https://blockchain.info/pushtx'),
95
+ hex
127
96
  )
128
- left = unspent - tx.outputs.map(&:value).inject(&:+)
129
- @log.info("A new Bitcoin transaction #{tx.hash} prepared:
130
- #{tx.in.count} input#{tx.in.count > 1 ? 's' : ''}:
131
- #{tx.inputs.map { |i| " in: #{i.prev_out.bth}:#{i.prev_out_index}" }.join("\n ")}
132
- #{tx.out.count} output#{tx.out.count > 1 ? 's' : ''}:
133
- #{tx.outputs.map { |o| "out: #{o.script.bth} / #{num(o.value, p)}" }.join("\n ")}
134
- Min tx fee: #{num(Bitcoin.network[:min_tx_fee], p)}
135
- Fee requested: #{num(f, p)} as \"#{fee}\"
136
- Fee actually paid: #{num(left, p)}
137
- Tx size: #{size} bytes
138
- Unspent: #{num(unspent, p)}
139
- Amount: #{num(satoshi, p)}
140
- Target address: #{target}
141
- Change address is #{change}")
142
- unless @dry
143
- Sibit::Json.new(http: @http, log: @log).post(
144
- URI('https://blockchain.info/pushtx'),
145
- tx.to_payload.bth
146
- )
147
- end
148
- tx.hash
149
97
  end
150
98
 
151
99
  # Gets the hash of the latest block.
@@ -157,74 +105,7 @@ class Sibit
157
105
 
158
106
  # This method should fetch a Blockchain block and return as a hash.
159
107
  def block(_hash)
160
- raise Sibit::Error, 'Not implemented yet'
161
- end
162
-
163
- private
164
-
165
- def num(satoshi, usd)
166
- format(
167
- '%<satoshi>ss/$%<dollars>0.2f',
168
- satoshi: satoshi.to_s.gsub(/\d(?=(...)+$)/, '\0,'),
169
- dollars: satoshi * usd / 100_000_000
170
- )
171
- end
172
-
173
- # Convert text to amount.
174
- def satoshi(amount)
175
- return amount if amount.is_a?(Integer)
176
- raise Error, 'Amount should either be a String or Integer' unless amount.is_a?(String)
177
- return (amount.gsub(/BTC$/, '').to_f * 100_000_000).to_i if amount.end_with?('BTC')
178
- raise Error, "Can't understand the amount #{amount.inspect}"
179
- end
180
-
181
- # Calculates a fee in satoshi for the transaction of the specified size.
182
- # The +fee+ argument could be a number in satoshi, in which case it will
183
- # be returned as is, or a string like "XL" or "S", in which case the
184
- # fee will be calculated using the +size+ argument (which is the size
185
- # of the transaction in bytes).
186
- def mfee(fee, size)
187
- return fee.to_i if fee.is_a?(Integer)
188
- raise Error, 'Fee should either be a String or Integer' unless fee.is_a?(String)
189
- mul = 1
190
- if fee.start_with?('+', '-')
191
- mul = -1 if fee.start_with?('-')
192
- fee = fee[1..-1]
193
- end
194
- sat = fees[fee.to_sym]
195
- raise Error, "Can't understand the fee: #{fee.inspect}" if sat.nil?
196
- mul * sat * size
197
- end
198
-
199
- # Make key from private key string in Hash160.
200
- def key(hash160)
201
- key = Bitcoin::Key.new
202
- key.priv = hash160
203
- key
204
- end
205
-
206
- # Calculate an approximate size of the transaction.
207
- def size_of(amount, sources)
208
- satoshi = satoshi(amount)
209
- builder = Bitcoin::Builder::TxBuilder.new
210
- unspent = 0
211
- size = 100
212
- utxos = Sibit::Json.new(http: @http, log: @log).get(
213
- URI("https://blockchain.info/unspent?active=#{sources.keys.join('|')}&limit=1000")
214
- )['unspent_outputs']
215
- utxos.each do |utxo|
216
- unspent += utxo['value']
217
- builder.input do |i|
218
- i.prev_out(utxo['tx_hash_big_endian'])
219
- i.prev_out_index(utxo['tx_output_n'])
220
- i.prev_out_script = [utxo['script']].pack('H*')
221
- address = Bitcoin::Script.new([utxo['script']].pack('H*')).get_address
222
- i.signature_key(key(sources[address]))
223
- end
224
- size += 180
225
- break if unspent > satoshi
226
- end
227
- size
108
+ raise Sibit::Error, 'block() not implemented yet'
228
109
  end
229
110
  end
230
111
  end
data/lib/sibit/btc.rb CHANGED
@@ -68,11 +68,6 @@ class Sibit
68
68
  raise Sibit::Error, 'Not implemented yet'
69
69
  end
70
70
 
71
- # Sends a payment and returns the transaction hash.
72
- def pay(_amount, _fee, _sources, _target, _change)
73
- raise Sibit::Error, 'Not implemented yet'
74
- end
75
-
76
71
  # Gets the hash of the latest block.
77
72
  def latest
78
73
  uri = URI('https://chain.api.btc.com/v3/block/latest')
@@ -82,6 +77,16 @@ class Sibit
82
77
  hash
83
78
  end
84
79
 
80
+ # Fetch all unspent outputs per address.
81
+ def utxos(_sources)
82
+ raise Sibit::Error, 'Not implemented yet'
83
+ end
84
+
85
+ # Push this transaction (in hex format) to the network.
86
+ def push(_hex)
87
+ raise Sibit::Error, 'Not implemented yet'
88
+ end
89
+
85
90
  # This method should fetch a Blockchain block and return as a hash.
86
91
  def block(hash)
87
92
  head = Sibit::Json.new(http: @http, log: @log).get(
data/lib/sibit/earn.rb ADDED
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2019-2020 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'json'
24
+ require 'uri'
25
+ require_relative 'version'
26
+ require_relative 'error'
27
+ require_relative 'http'
28
+ require_relative 'json'
29
+
30
+ # Earn.com API.
31
+ #
32
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
33
+ # Copyright:: Copyright (c) 2019-2020 Yegor Bugayenko
34
+ # License:: MIT
35
+ class Sibit
36
+ # Blockchain.info API.
37
+ class Earn
38
+ # Constructor.
39
+ def initialize(log: Sibit::Log.new, http: Sibit::Http.new, dry: false)
40
+ @http = http
41
+ @log = log
42
+ @dry = dry
43
+ end
44
+
45
+ # Current price of BTC in USD (float returned).
46
+ def price(_currency)
47
+ raise Sibit::Error, 'price() doesn\'t work here'
48
+ end
49
+
50
+ # Gets the balance of the address, in satoshi.
51
+ def balance(_address)
52
+ raise Sibit::Error, 'balance() doesn\'t work here'
53
+ end
54
+
55
+ # Get recommended fees, in satoshi per byte. The method returns
56
+ # a hash: { S: 12, M: 45, L: 100, XL: 200 }
57
+ def fees
58
+ json = Sibit::Json.new(http: @http, log: @log).get(
59
+ URI('https://bitcoinfees.earn.com/api/v1/fees/recommended')
60
+ )
61
+ @log.info("Current recommended Bitcoin fees: \
62
+ #{json['hourFee']}/#{json['halfHourFee']}/#{json['fastestFee']} sat/byte")
63
+ {
64
+ S: json['hourFee'] / 3,
65
+ M: json['hourFee'],
66
+ L: json['halfHourFee'],
67
+ XL: json['fastestFee']
68
+ }
69
+ end
70
+
71
+ # Fetch all unspent outputs per address.
72
+ def utxos(_sources)
73
+ raise Sibit::Error, 'Not implemented yet'
74
+ end
75
+
76
+ # Push this transaction (in hex format) to the network.
77
+ def push(_hex)
78
+ raise Sibit::Error, 'Not implemented yet'
79
+ end
80
+
81
+ # Gets the hash of the latest block.
82
+ def latest
83
+ raise Sibit::Error, 'latest() doesn\'t work here'
84
+ end
85
+
86
+ # This method should fetch a Blockchain block and return as a hash.
87
+ def block(_hash)
88
+ raise Sibit::Error, 'block() doesn\'t work here'
89
+ end
90
+ end
91
+ end
data/lib/sibit/fake.rb CHANGED
@@ -42,8 +42,12 @@ class Sibit
42
42
  100_000_000
43
43
  end
44
44
 
45
- def pay(_amount, _fee, _sources, _target, _change)
46
- '9dfe55a30b5ee732005158c589179a398117117a68d21531fb6c78b85b544c54'
45
+ def utxos(_sources)
46
+ []
47
+ end
48
+
49
+ def push(hex)
50
+ # Nothing to do here
47
51
  end
48
52
 
49
53
  def latest
data/lib/sibit/version.rb CHANGED
@@ -26,5 +26,5 @@
26
26
  # License:: MIT
27
27
  class Sibit
28
28
  # Current version of the library.
29
- VERSION = '0.14.2'
29
+ VERSION = '0.14.3'
30
30
  end
data/lib/sibit.rb CHANGED
@@ -105,9 +105,61 @@ class Sibit
105
105
  # +target+: the target address to send to
106
106
  # +change+: the address where the change has to be sent to
107
107
  def pay(amount, fee, sources, target, change)
108
+ p = price('USD')
109
+ satoshi = satoshi(amount)
110
+ builder = Bitcoin::Builder::TxBuilder.new
111
+ unspent = 0
112
+ size = 100
113
+ utxos = first_one { |api| api.utxos(sources) }
114
+ @log.info("#{utxos.count} UTXOs found, these will be used \
115
+ (value/confirmations at tx_hash):")
116
+ utxos.each do |utxo|
117
+ unspent += utxo[:value]
118
+ builder.input do |i|
119
+ i.prev_out(utxo[:hash])
120
+ i.prev_out_index(utxo[:index])
121
+ i.prev_out_script = utxo[:script]
122
+ address = Bitcoin::Script.new(utxo[:script]).get_address
123
+ i.signature_key(key(sources[address]))
124
+ end
125
+ size += 180
126
+ @log.info(
127
+ " #{num(utxo[:value], p)}/#{utxo[:confirmations]} at #{utxo[:hash]}"
128
+ )
129
+ break if unspent > satoshi
130
+ end
131
+ if unspent < satoshi
132
+ raise Error, "Not enough funds to send #{num(satoshi, p)}, only #{num(unspent, p)} left"
133
+ end
134
+ builder.output(satoshi, target)
135
+ f = mfee(fee, size)
136
+ satoshi += f if f.negative?
137
+ raise Error, "The fee #{f.abs} covers the entire amount" if satoshi.zero?
138
+ raise Error, "The fee #{f.abs} is bigger than the amount #{satoshi}" if satoshi.negative?
139
+ tx = builder.tx(
140
+ input_value: unspent,
141
+ leave_fee: true,
142
+ extra_fee: [f, Bitcoin.network[:min_tx_fee]].max,
143
+ change_address: change
144
+ )
145
+ left = unspent - tx.outputs.map(&:value).inject(&:+)
146
+ @log.info("A new Bitcoin transaction #{tx.hash} prepared:
147
+ #{tx.in.count} input#{tx.in.count > 1 ? 's' : ''}:
148
+ #{tx.inputs.map { |i| " in: #{i.prev_out.bth}:#{i.prev_out_index}" }.join("\n ")}
149
+ #{tx.out.count} output#{tx.out.count > 1 ? 's' : ''}:
150
+ #{tx.outputs.map { |o| "out: #{o.script.bth} / #{num(o.value, p)}" }.join("\n ")}
151
+ Min tx fee: #{num(Bitcoin.network[:min_tx_fee], p)}
152
+ Fee requested: #{num(f, p)} as \"#{fee}\"
153
+ Fee actually paid: #{num(left, p)}
154
+ Tx size: #{size} bytes
155
+ Unspent: #{num(unspent, p)}
156
+ Amount: #{num(satoshi, p)}
157
+ Target address: #{target}
158
+ Change address is #{change}")
108
159
  first_one do |api|
109
- api.pay(amount, fee, sources, target, change)
160
+ api.push(tx.to_payload.bth)
110
161
  end
162
+ tx.hash
111
163
  end
112
164
 
113
165
  # Gets the hash of the latest block.
@@ -186,7 +238,51 @@ class Sibit
186
238
  @log.info("The API #{api.class.name} failed: #{e.message}")
187
239
  end
188
240
  end
189
- raise Sibit::Error, 'No APIs managed to succeed' unless done
241
+ unless done
242
+ raise Sibit::Error, "No APIs out of #{@api.length} managed to succeed: \
243
+ #{@api.map { |a| a.class.name }.join(', ')}"
244
+ end
190
245
  result
191
246
  end
247
+
248
+ def num(satoshi, usd)
249
+ format(
250
+ '%<satoshi>ss/$%<dollars>0.2f',
251
+ satoshi: satoshi.to_s.gsub(/\d(?=(...)+$)/, '\0,'),
252
+ dollars: satoshi * usd / 100_000_000
253
+ )
254
+ end
255
+
256
+ # Convert text to amount.
257
+ def satoshi(amount)
258
+ return amount if amount.is_a?(Integer)
259
+ raise Error, 'Amount should either be a String or Integer' unless amount.is_a?(String)
260
+ return (amount.gsub(/BTC$/, '').to_f * 100_000_000).to_i if amount.end_with?('BTC')
261
+ raise Error, "Can't understand the amount #{amount.inspect}"
262
+ end
263
+
264
+ # Calculates a fee in satoshi for the transaction of the specified size.
265
+ # The +fee+ argument could be a number in satoshi, in which case it will
266
+ # be returned as is, or a string like "XL" or "S", in which case the
267
+ # fee will be calculated using the +size+ argument (which is the size
268
+ # of the transaction in bytes).
269
+ def mfee(fee, size)
270
+ return fee.to_i if fee.is_a?(Integer)
271
+ raise Error, 'Fee should either be a String or Integer' unless fee.is_a?(String)
272
+ mul = 1
273
+ if fee.start_with?('+', '-')
274
+ mul = -1 if fee.start_with?('-')
275
+ fee = fee[1..-1]
276
+ end
277
+ sat = fees[fee.to_sym]
278
+ raise Error, "Can't understand the fee: #{fee.inspect}" if sat.nil?
279
+ mul * sat * size
280
+ end
281
+
282
+ # Make key from private key string in Hash160.
283
+ def key(hash160)
284
+ key = Bitcoin::Key.new
285
+ key.priv = hash160
286
+ key
287
+ end
192
288
  end
data/test/test_fake.rb CHANGED
@@ -35,10 +35,7 @@ class TestFake < Minitest::Test
35
35
  assert_equal(4_000, sibit.price)
36
36
  assert_equal(12, sibit.fees[:S])
37
37
  assert_equal(100_000_000, sibit.balance(''))
38
- assert_equal(
39
- '9dfe55a30b5ee732005158c589179a398117117a68d21531fb6c78b85b544c54',
40
- sibit.pay(0, 'M', {}, '', '')
41
- )
38
+ assert_equal([], sibit.utxos(nil))
42
39
  assert_equal('00000000000000000008df8a6e1b61d1136803ac9791b8725235c9f780b4ed71', sibit.latest)
43
40
  end
44
41
 
data/test/test_sibit.rb CHANGED
@@ -24,6 +24,9 @@ require 'minitest/autorun'
24
24
  require 'webmock/minitest'
25
25
  require 'json'
26
26
  require_relative '../lib/sibit'
27
+ require_relative '../lib/sibit/earn'
28
+ require_relative '../lib/sibit/fake'
29
+ require_relative '../lib/sibit/blockchain'
27
30
 
28
31
  # Sibit.
29
32
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -34,7 +37,7 @@ class TestSibit < Minitest::Test
34
37
  stub_request(
35
38
  :get, 'https://bitcoinfees.earn.com/api/v1/fees/recommended'
36
39
  ).to_return(body: '{"fastestFee":300,"halfHourFee":200,"hourFee":180}')
37
- sibit = Sibit.new
40
+ sibit = Sibit.new(api: Sibit::Earn.new)
38
41
  fees = sibit.fees
39
42
  assert_equal(60, fees[:S])
40
43
  assert_equal(180, fees[:M])
@@ -124,7 +127,7 @@ class TestSibit < Minitest::Test
124
127
  'https://blockchain.info/unspent?active=1JvCsJtLmCxEk7ddZFnVkGXpr9uhxZPmJi&limit=1000'
125
128
  ).to_return(body: JSON.pretty_generate(json))
126
129
  stub_request(:post, 'https://blockchain.info/pushtx').to_return(status: 200)
127
- sibit = Sibit.new
130
+ sibit = Sibit.new(api: [Sibit::Earn.new, Sibit::Blockchain.new])
128
131
  target = sibit.create(sibit.generate)
129
132
  change = sibit.create(sibit.generate)
130
133
  tx = sibit.pay(
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sibit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.2
4
+ version: 0.14.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -284,6 +284,7 @@ files:
284
284
  - lib/sibit/bitcoinchain.rb
285
285
  - lib/sibit/blockchain.rb
286
286
  - lib/sibit/btc.rb
287
+ - lib/sibit/earn.rb
287
288
  - lib/sibit/error.rb
288
289
  - lib/sibit/fake.rb
289
290
  - lib/sibit/http.rb