sibit 0.29.0 → 0.29.1

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: ddde20b613a744a0618b9b91d4adfea42d945a13d778ecad2492b1a15afe3c0e
4
- data.tar.gz: 7d83be599123ff738035fbf610d1ae6f763c5c36cec2a83a626658707cf37cda
3
+ metadata.gz: 16d749128c92e0a715c1545d8cb6aa6a41a4afcbd7fc39db0e708fa87ea7383d
4
+ data.tar.gz: c522bc105501aedd9f3ef6140ac99bb1b18cec23fc060ff8dd6ceed4d4e69dff
5
5
  SHA512:
6
- metadata.gz: 9811599df9ebb242927bcf50a8ed2b1e24adad74832b72748b1f1c113c9f30e89c0b9079f3a0898308963c55c59d0f899534d529d673f0120a718176402a4e10
7
- data.tar.gz: 2f3821bb817a4fadbe8137ccce649d66ba388ae17f0a3b99f6293947e0d3ef084d2d0f1501fabcbec8d933b7127d655a1fae74bdb907019ae39e088d4bd6bf52
6
+ metadata.gz: 854ede7b60a6cd9e1334341b14f1b712e002b23499a5a192d61b53380b68d3203f4d7c3d0aaa87499d59a885190345e776410e1eb133f26f85b8aaac260772ed
7
+ data.tar.gz: f99cee0f4d8615d0a39ee7609c697b4238e0e867193934564d5f2d29cfffe454b630b8da0f4e7f1bda9620d57d395bdf4b365614cf318c6079b808dab330cc2f
data/Gemfile CHANGED
@@ -14,6 +14,8 @@ gem 'logger', '~>1.7', require: false
14
14
  gem 'minitest', '~>6.0', require: false
15
15
  gem 'minitest-reporters', '~>1.7', require: false
16
16
  gem 'nokogiri', '~>1.18', require: false
17
+ gem 'os', '~>1.1', require: false
18
+ gem 'qbash', '~>0.0', require: false
17
19
  gem 'rake', '~>13.2', require: false
18
20
  gem 'rdoc', '~>7.0', require: false
19
21
  gem 'rubocop', '~>1.62', require: false
data/Gemfile.lock CHANGED
@@ -59,6 +59,9 @@ GEM
59
59
  date (3.5.1)
60
60
  diff-lcs (1.6.2)
61
61
  docile (1.4.1)
62
+ elapsed (0.2.1)
63
+ loog (~> 0.6)
64
+ tago (~> 0.1)
62
65
  erb (6.0.1)
63
66
  ffi (1.17.2-arm64-darwin)
64
67
  ffi (1.17.2-x86_64-linux-gnu)
@@ -85,6 +88,7 @@ GEM
85
88
  mini_portile2 (~> 2.8.2)
86
89
  racc (~> 1.4)
87
90
  openssl (4.0.0)
91
+ os (1.1.4)
88
92
  parallel (1.27.0)
89
93
  parser (3.3.10.0)
90
94
  ast (~> 2.4.1)
@@ -94,6 +98,11 @@ GEM
94
98
  date
95
99
  stringio
96
100
  public_suffix (7.0.0)
101
+ qbash (0.4.8)
102
+ backtrace (> 0)
103
+ elapsed (> 0)
104
+ loog (> 0)
105
+ tago (> 0)
97
106
  racc (1.8.1)
98
107
  rainbow (3.1.1)
99
108
  rake (13.3.1)
@@ -150,6 +159,7 @@ GEM
150
159
  sys-uname (1.4.1)
151
160
  ffi (~> 1.1)
152
161
  memoist3 (~> 1.0.0)
162
+ tago (0.6.0)
153
163
  thor (1.4.0)
154
164
  tsort (0.2.0)
155
165
  unicode-display_width (3.2.0)
@@ -173,6 +183,8 @@ DEPENDENCIES
173
183
  minitest (~> 6.0)
174
184
  minitest-reporters (~> 1.7)
175
185
  nokogiri (~> 1.18)
186
+ os (~> 1.1)
187
+ qbash (~> 0.0)
176
188
  rake (~> 13.2)
177
189
  rdoc (~> 7.0)
178
190
  rubocop (~> 1.62)
data/Rakefile CHANGED
@@ -3,10 +3,13 @@
3
3
  # SPDX-FileCopyrightText: Copyright (c) 2019-2025 Yegor Bugayenko
4
4
  # SPDX-License-Identifier: MIT
5
5
 
6
- require 'rubygems'
6
+ require 'os'
7
+ require 'qbash'
7
8
  require 'rake'
8
- require 'rdoc'
9
9
  require 'rake/clean'
10
+ require 'rdoc'
11
+ require 'rubygems'
12
+ require 'shellwords'
10
13
 
11
14
  def name
12
15
  @name ||= File.basename(Dir['*.gemspec'].first, '.*')
@@ -16,7 +19,7 @@ def version
16
19
  Gem::Specification.load(Dir['*.gemspec'].first).version
17
20
  end
18
21
 
19
- task default: %i[clean test features rubocop]
22
+ task default: %i[clean test picks features rubocop]
20
23
 
21
24
  require 'rake/testtask'
22
25
  Rake::TestTask.new(:test) do |test|
@@ -27,6 +30,16 @@ Rake::TestTask.new(:test) do |test|
27
30
  test.verbose = false
28
31
  end
29
32
 
33
+ desc 'Run them via Ruby, one by one'
34
+ task :picks do
35
+ next if OS.windows?
36
+ %w[test lib].each do |d|
37
+ Dir["#{d}/**/*.rb"].each do |f|
38
+ qbash("bundle exec ruby #{Shellwords.escape(f)}", log: $stdout, env: { 'PICKS' => 'yes' })
39
+ end
40
+ end
41
+ end
42
+
30
43
  require 'rdoc/task'
31
44
  Rake::RDocTask.new do |rdoc|
32
45
  rdoc.rdoc_dir = 'rdoc'
data/bin/sibit CHANGED
@@ -11,6 +11,7 @@ require 'loog'
11
11
  require 'retriable_proxy'
12
12
  require 'slop'
13
13
  require_relative '../lib/sibit'
14
+ require_relative '../lib/sibit/http'
14
15
  require_relative '../lib/sibit/bitcoinchain'
15
16
  require_relative '../lib/sibit/blockchain'
16
17
  require_relative '../lib/sibit/blockchair'
data/features/cli.feature CHANGED
@@ -1,7 +1,7 @@
1
1
  # SPDX-FileCopyrightText: Copyright (c) 2019-2025 Yegor Bugayenko
2
2
  # SPDX-License-Identifier: MIT
3
3
  Feature: Command Line Processing
4
- As a newsletter author I want to be able to send a newsletter
4
+ As a holder of BTC I want to be able to use sibit
5
5
 
6
6
  Scenario: Help can be printed
7
7
  When I run bin/sibit with "--help"
@@ -0,0 +1,25 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2019-2025 Yegor Bugayenko
2
+ # SPDX-License-Identifier: MIT
3
+ Feature: Command Line Processing
4
+ As a holder of BTC I want to use sibit in dry mode
5
+
6
+ Scenario: Bitcoin price can be retrieved
7
+ When I run bin/sibit with "price --dry --attempts=4"
8
+ Then Exit code is zero
9
+
10
+ Scenario: Bitcoin latest block hash can be retrieved
11
+ When I run bin/sibit with "latest --dry --api=blockchain"
12
+ Then Exit code is zero
13
+
14
+ Scenario: Bitcoin balance can be checked
15
+ When I run bin/sibit with "balance --dry 1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f --verbose --api=blockchain,btc"
16
+ Then Exit code is zero
17
+
18
+ Scenario: Bitcoin fees can be printed
19
+ When I run bin/sibit with "fees --dry --verbose --api=fake"
20
+ Then Exit code is zero
21
+
22
+ Scenario: Bitcoin payment can be sent
23
+ When I run bin/sibit with "pay --dry --verbose --api=fake --proxy=localhost:3128 999999 XL- 46feba063e9b59a8ae0dba68abd39a3cb8f52089e776576d6eb1bb5bfec123d1 1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f 1Fsyq5YGe8zbSjLS8YsDnZWM8U6AYMR6ZD"
24
+ Then Exit code is not zero
25
+ Then Stdout contains "UTXO arrived to 1JvCsJtLmCxEk7ddZFnVkGXpr9uhxZPmJi is incorrect"
@@ -5,25 +5,26 @@
5
5
 
6
6
  require 'digest'
7
7
 
8
- # Bitcoin primitives module.
9
- #
10
- # Pure Ruby implementation of Bitcoin functionality using OpenSSL 3.0+.
11
- # Replaces the bitcoin-ruby dependency which is incompatible with OpenSSL 3.0.
12
- module Sibit::Bitcoin
13
- MIN_TX_FEE = 10_000
14
-
8
+ # Sibit main class.
9
+ class Sibit
15
10
  # Base58 encoding for Bitcoin addresses.
16
11
  #
12
+ # Encapsulates hex data and provides encoding/decoding functionality.
13
+ #
17
14
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
18
15
  # Copyright:: Copyright (c) 2019-2025 Yegor Bugayenko
19
16
  # License:: MIT
20
- module Base58
17
+ class Base58
21
18
  ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
22
19
 
23
- def self.encode(hex)
24
- bytes = [hex].pack('H*')
20
+ def initialize(data)
21
+ @data = data
22
+ end
23
+
24
+ def encode
25
+ bytes = [@data].pack('H*')
25
26
  leading = bytes.match(/^\x00*/)[0].length
26
- num = hex.to_i(16)
27
+ num = @data.to_i(16)
27
28
  result = ''
28
29
  while num.positive?
29
30
  num, remainder = num.divmod(58)
@@ -32,17 +33,17 @@ module Sibit::Bitcoin
32
33
  ('1' * leading) + result
33
34
  end
34
35
 
35
- def self.decode(str)
36
- leading = str.match(/^1*/)[0].length
36
+ def decode
37
+ leading = @data.match(/^1*/)[0].length
37
38
  num = 0
38
- str.each_char { |c| num = (num * 58) + ALPHABET.index(c) }
39
+ @data.each_char { |c| num = (num * 58) + ALPHABET.index(c) }
39
40
  hex = num.zero? ? '' : num.to_s(16)
40
41
  hex = "0#{hex}" if hex.length.odd?
41
42
  ('00' * leading) + hex
42
43
  end
43
44
 
44
- def self.check(hex)
45
- Digest::SHA256.hexdigest(Digest::SHA256.digest([hex].pack('H*')))[0...8]
45
+ def check
46
+ Digest::SHA256.hexdigest(Digest::SHA256.digest([@data].pack('H*')))[0...8]
46
47
  end
47
48
  end
48
49
  end
@@ -7,7 +7,8 @@ require 'digest'
7
7
  require 'openssl'
8
8
  require_relative 'base58'
9
9
 
10
- module Sibit::Bitcoin
10
+ # Sibit main class.
11
+ class Sibit
11
12
  # Bitcoin ECDSA key using secp256k1 curve.
12
13
  #
13
14
  # Supports OpenSSL 3.0+ by constructing keys via DER encoding instead
@@ -44,8 +45,8 @@ module Sibit::Bitcoin
44
45
  def addr
45
46
  hash = hash160(pub)
46
47
  versioned = "00#{hash}"
47
- checksum = Base58.check(versioned)
48
- Base58.encode(versioned + checksum)
48
+ checksum = Base58.new(versioned).check
49
+ Base58.new(versioned + checksum).encode
49
50
  end
50
51
 
51
52
  def sign(data)
@@ -6,7 +6,8 @@
6
6
  require 'digest'
7
7
  require_relative 'base58'
8
8
 
9
- module Sibit::Bitcoin
9
+ # Sibit main class.
10
+ class Sibit
10
11
  # Bitcoin Script parser.
11
12
  #
12
13
  # Parses standard P2PKH scripts to extract addresses.
@@ -49,8 +50,8 @@ module Sibit::Bitcoin
49
50
  h = hash160
50
51
  return nil unless h
51
52
  versioned = "00#{h}"
52
- checksum = Base58.check(versioned)
53
- Base58.encode(versioned + checksum)
53
+ checksum = Base58.new(versioned).check
54
+ Base58.new(versioned + checksum).encode
54
55
  end
55
56
  end
56
57
  end
@@ -8,7 +8,10 @@ require_relative 'base58'
8
8
  require_relative 'key'
9
9
  require_relative 'script'
10
10
 
11
- module Sibit::Bitcoin
11
+ # Sibit main class.
12
+ class Sibit
13
+ MIN_TX_FEE = 10_000
14
+
12
15
  # Bitcoin Transaction structure.
13
16
  #
14
17
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -55,6 +58,62 @@ module Sibit::Bitcoin
55
58
  @outputs
56
59
  end
57
60
 
61
+ # Transaction input.
62
+ #
63
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
64
+ # Copyright:: Copyright (c) 2019-2025 Yegor Bugayenko
65
+ # License:: MIT
66
+ class Input
67
+ attr_reader :hash, :index, :prev_script, :key
68
+ attr_accessor :script_sig
69
+
70
+ def initialize(hash, index, script, key)
71
+ @hash = hash
72
+ @index = index
73
+ @prev_script = script
74
+ @key = key
75
+ @script_sig = ''
76
+ end
77
+
78
+ def prev_out
79
+ [@hash].pack('H*')
80
+ end
81
+
82
+ def prev_out_index
83
+ @index
84
+ end
85
+ end
86
+
87
+ # Transaction output.
88
+ #
89
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
90
+ # Copyright:: Copyright (c) 2019-2025 Yegor Bugayenko
91
+ # License:: MIT
92
+ class Output
93
+ attr_reader :value
94
+
95
+ def initialize(value, address)
96
+ @value = value
97
+ @address = address
98
+ end
99
+
100
+ def script
101
+ hash160 = address_to_hash160(@address)
102
+ [0x76, 0xa9, 0x14].pack('C*') + [hash160].pack('H*') + [0x88, 0xac].pack('C*')
103
+ end
104
+
105
+ def script_hex
106
+ script.unpack1('H*')
107
+ end
108
+
109
+ private
110
+
111
+ def address_to_hash160(addr)
112
+ decoded = Base58.new(addr).decode
113
+ decoded[2..41]
114
+ end
115
+ end
116
+
58
117
  private
59
118
 
60
119
  def sign_inputs
@@ -159,52 +218,4 @@ module Sibit::Bitcoin
159
218
  [0xff, num].pack('CQ<')
160
219
  end
161
220
  end
162
-
163
- # Transaction input.
164
- class Input
165
- attr_reader :hash, :index, :prev_script, :key
166
- attr_accessor :script_sig
167
-
168
- def initialize(hash, index, script, key)
169
- @hash = hash
170
- @index = index
171
- @prev_script = script
172
- @key = key
173
- @script_sig = ''
174
- end
175
-
176
- def prev_out
177
- [@hash].pack('H*')
178
- end
179
-
180
- def prev_out_index
181
- @index
182
- end
183
- end
184
-
185
- # Transaction output.
186
- class Output
187
- attr_reader :value
188
-
189
- def initialize(value, address)
190
- @value = value
191
- @address = address
192
- end
193
-
194
- def script
195
- hash160 = address_to_hash160(@address)
196
- [0x76, 0xa9, 0x14].pack('C*') + [hash160].pack('H*') + [0x88, 0xac].pack('C*')
197
- end
198
-
199
- def script_hex
200
- script.unpack1('H*')
201
- end
202
-
203
- private
204
-
205
- def address_to_hash160(addr)
206
- decoded = Base58.decode(addr)
207
- decoded[2..41]
208
- end
209
- end
210
221
  end
@@ -6,54 +6,57 @@
6
6
  require_relative 'key'
7
7
  require_relative 'tx'
8
8
 
9
+ # Sibit main class.
9
10
  class Sibit
10
- module Bitcoin
11
- # Bitcoin Transaction Builder.
12
- #
13
- # Provides a similar interface to Bitcoin::Builder::TxBuilder for
14
- # building and signing Bitcoin transactions.
15
- #
16
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
17
- # Copyright:: Copyright (c) 2019-2025 Yegor Bugayenko
18
- # License:: MIT
19
- class TxBuilder
20
- def initialize
21
- @inputs = []
22
- @outputs = []
23
- end
11
+ # Bitcoin Transaction Builder.
12
+ #
13
+ # Provides a similar interface to Bitcoin::Builder::TxBuilder for
14
+ # building and signing Bitcoin transactions.
15
+ #
16
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
17
+ # Copyright:: Copyright (c) 2019-2025 Yegor Bugayenko
18
+ # License:: MIT
19
+ class TxBuilder
20
+ def initialize
21
+ @inputs = []
22
+ @outputs = []
23
+ end
24
24
 
25
- def input
26
- inp = InputBuilder.new
27
- yield inp
28
- @inputs << inp
29
- end
25
+ def input
26
+ inp = Input.new
27
+ yield inp
28
+ @inputs << inp
29
+ end
30
30
 
31
- def output(value, address)
32
- @outputs << { value: value, address: address }
33
- end
31
+ def output(value, address)
32
+ @outputs << { value: value, address: address }
33
+ end
34
34
 
35
- def tx(input_value:, leave_fee:, extra_fee:, change_address:)
36
- txn = Tx.new
37
- @inputs.each do |inp|
38
- txn.add_input(
39
- hash: inp.prev_out_hash,
40
- index: inp.prev_out_idx,
41
- script: inp.script,
42
- key: inp.key
43
- )
44
- end
45
- total_out = @outputs.sum { |o| o[:value] }
46
- @outputs.each { |o| txn.add_output(o[:value], o[:address]) }
47
- if leave_fee
48
- change = input_value - total_out - extra_fee
49
- txn.add_output(change, change_address) if change.positive?
50
- end
51
- BuiltTx.new(txn, @inputs, @outputs)
52
- end
35
+ def tx(input_value:, leave_fee:, extra_fee:, change_address:)
36
+ txn = Tx.new
37
+ @inputs.each do |inp|
38
+ txn.add_input(
39
+ hash: inp.prev_out_hash,
40
+ index: inp.prev_out_idx,
41
+ script: inp.script,
42
+ key: inp.key
43
+ )
44
+ end
45
+ total_out = @outputs.sum { |o| o[:value] }
46
+ @outputs.each { |o| txn.add_output(o[:value], o[:address]) }
47
+ if leave_fee
48
+ change = input_value - total_out - extra_fee
49
+ txn.add_output(change, change_address) if change.positive?
50
+ end
51
+ Built.new(txn, @inputs, @outputs)
53
52
  end
54
53
 
55
54
  # Input builder for collecting input parameters.
56
- class InputBuilder
55
+ #
56
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
57
+ # Copyright:: Copyright (c) 2019-2025 Yegor Bugayenko
58
+ # License:: MIT
59
+ class Input
57
60
  attr_reader :prev_out_hash, :prev_out_idx, :script, :key
58
61
 
59
62
  def prev_out(hash)
@@ -74,11 +77,15 @@ class Sibit
74
77
  end
75
78
 
76
79
  # Wrapper for built transaction with convenience methods.
77
- class BuiltTx
80
+ #
81
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
82
+ # Copyright:: Copyright (c) 2019-2025 Yegor Bugayenko
83
+ # License:: MIT
84
+ class Built
78
85
  def initialize(txn, inputs, outputs)
79
86
  @tx = txn
80
- @inputs_data = inputs
81
- @outputs_data = outputs
87
+ @inputs = inputs
88
+ @outputs = outputs
82
89
  end
83
90
 
84
91
  def hash
@@ -102,18 +109,22 @@ class Sibit
102
109
  end
103
110
 
104
111
  def to_payload
105
- PayloadWrapper.new(@tx.payload)
112
+ Payload.new(@tx.payload)
106
113
  end
107
- end
108
114
 
109
- # Wrapper for payload with hex conversion.
110
- class PayloadWrapper
111
- def initialize(bytes)
112
- @bytes = bytes
113
- end
115
+ # Wrapper for payload with hex conversion.
116
+ #
117
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
118
+ # Copyright:: Copyright (c) 2019-2025 Yegor Bugayenko
119
+ # License:: MIT
120
+ class Payload
121
+ def initialize(bytes)
122
+ @bytes = bytes
123
+ end
114
124
 
115
- def bth
116
- @bytes.unpack1('H*')
125
+ def bth
126
+ @bytes.unpack1('H*')
127
+ end
117
128
  end
118
129
  end
119
130
  end
data/lib/sibit/fake.rb CHANGED
@@ -32,7 +32,15 @@ class Sibit::Fake
32
32
  end
33
33
 
34
34
  def utxos(_sources)
35
- []
35
+ [
36
+ {
37
+ hash: '5de641d3867eb8fec3eb1a5ef2b44df39b54e0b3bb664ab520f2ae26a5b18ffc',
38
+ index: 0,
39
+ value: 100_000_000,
40
+ confirmations: 6,
41
+ script: '76a914c48a1737b35a9f9d9e3b624a910f1e22f7e80bbc88ac'
42
+ }
43
+ ]
36
44
  end
37
45
 
38
46
  def push(_hex); end
data/lib/sibit/http.rb CHANGED
@@ -5,30 +5,37 @@
5
5
 
6
6
  require 'net/http'
7
7
 
8
- # HTTP interface.
9
- #
10
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2019-2025 Yegor Bugayenko
12
- # License:: MIT
13
- class Sibit::Http
14
- def client(uri)
15
- http = Net::HTTP.new(uri.host, uri.port)
16
- http.use_ssl = true
17
- http.read_timeout = 240
18
- http
8
+ # Sibit main class.
9
+ class Sibit
10
+ # HTTP interface.
11
+ #
12
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
13
+ # Copyright:: Copyright (c) 2019-2025 Yegor Bugayenko
14
+ # License:: MIT
15
+ class Http
16
+ def client(uri)
17
+ http = Net::HTTP.new(uri.host, uri.port)
18
+ http.use_ssl = true
19
+ http.read_timeout = 240
20
+ http
21
+ end
19
22
  end
20
- end
21
23
 
22
- # This HTTP client with proxy.
23
- class HttpProxy
24
- def initialize(addr)
25
- @host, @port = addr.split(':')
26
- end
24
+ # This HTTP client with proxy.
25
+ #
26
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
27
+ # Copyright:: Copyright (c) 2019-2025 Yegor Bugayenko
28
+ # License:: MIT
29
+ class HttpProxy
30
+ def initialize(addr)
31
+ @host, @port = addr.split(':')
32
+ end
27
33
 
28
- def client(uri)
29
- http = Net::HTTP.new(uri.host, uri.port, @host, @port.to_i)
30
- http.use_ssl = true
31
- http.read_timeout = 240
32
- http
34
+ def client(uri)
35
+ http = Net::HTTP.new(uri.host, uri.port, @host, @port.to_i)
36
+ http.use_ssl = true
37
+ http.read_timeout = 240
38
+ http
39
+ end
33
40
  end
34
41
  end
data/lib/sibit/version.rb CHANGED
@@ -9,5 +9,5 @@
9
9
  # License:: MIT
10
10
  class Sibit
11
11
  # Current version of the library.
12
- VERSION = '0.29.0'
12
+ VERSION = '0.29.1'
13
13
  end
data/lib/sibit.rb CHANGED
@@ -48,14 +48,14 @@ class Sibit
48
48
 
49
49
  # Generates new Bitcoin private key and returns in Hash160 format.
50
50
  def generate
51
- key = Bitcoin::Key.generate.priv
51
+ key = Key.generate.priv
52
52
  @log.info("Bitcoin private key generated: #{key[0..8]}...")
53
53
  key
54
54
  end
55
55
 
56
56
  # Creates Bitcoin address using the private key in Hash160 format.
57
57
  def create(pvt)
58
- Bitcoin::Key.new(pvt).addr
58
+ Key.new(pvt).addr
59
59
  end
60
60
 
61
61
  # Gets the balance of the address, in satoshi.
@@ -100,9 +100,9 @@ class Sibit
100
100
  # +change+: the address where the change has to be sent to
101
101
  def pay(amount, fee, sources, target, change, skip_utxo: [])
102
102
  p = price('USD')
103
- sources = sources.map { |k| [Bitcoin::Key.new(k).addr, k] }.to_h
103
+ sources = sources.map { |k| [Key.new(k).addr, k] }.to_h
104
104
  satoshi = satoshi(amount)
105
- builder = Bitcoin::TxBuilder.new
105
+ builder = TxBuilder.new
106
106
  unspent = 0
107
107
  size = 100
108
108
  utxos = @api.utxos(sources.keys)
@@ -118,8 +118,10 @@ class Sibit
118
118
  i.prev_out(utxo[:hash])
119
119
  i.prev_out_index(utxo[:index])
120
120
  i.prev_out_script = script_hex(utxo[:script])
121
- address = Bitcoin::Script.new(script_hex(utxo[:script])).address
122
- i.signature_key(key(sources[address]))
121
+ address = Script.new(script_hex(utxo[:script])).address
122
+ k = sources[address]
123
+ raise Error, "UTXO arrived to #{address} is incorrect" unless k
124
+ i.signature_key(key(k))
123
125
  end
124
126
  size += 180
125
127
  @log.info(
@@ -138,7 +140,7 @@ class Sibit
138
140
  tx = builder.tx(
139
141
  input_value: unspent,
140
142
  leave_fee: true,
141
- extra_fee: [f, Bitcoin::MIN_TX_FEE].max,
143
+ extra_fee: [f, MIN_TX_FEE].max,
142
144
  change_address: change
143
145
  )
144
146
  left = unspent - tx.outputs.sum(&:value)
@@ -147,7 +149,7 @@ class Sibit
147
149
  #{tx.inputs.map { |i| " in: #{i.prev_out.unpack1('H*')}:#{i.prev_out_index}" }.join("\n ")}
148
150
  #{tx.out.count} output#{'s' if tx.out.count > 1}:
149
151
  #{tx.outputs.map { |o| "out: #{o.script_hex} / #{num(o.value, p)}" }.join("\n ")}
150
- Min tx fee: #{num(Bitcoin::MIN_TX_FEE, p)}
152
+ Min tx fee: #{num(MIN_TX_FEE, p)}
151
153
  Fee requested: #{num(f, p)} as \"#{fee}\"
152
154
  Fee actually paid: #{num(left, p)}
153
155
  Tx size: #{size} bytes
@@ -272,7 +274,7 @@ in block #{block} (by #{json[:provider]})")
272
274
 
273
275
  # Make key from private key string in Hash160.
274
276
  def key(hash160)
275
- Bitcoin::Key.new(hash160)
277
+ Key.new(hash160)
276
278
  end
277
279
 
278
280
  # Convert script to hex string if needed.
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.29.0
4
+ version: 0.29.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -128,6 +128,7 @@ files:
128
128
  - bin/sibit
129
129
  - cucumber.yml
130
130
  - features/cli.feature
131
+ - features/dry.feature
131
132
  - features/gem_package.feature
132
133
  - features/step_definitions/steps.rb
133
134
  - features/support/env.rb