sibit 0.32.7 → 0.32.8

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: 759028cb2cfe895ec5f71b65a19b0cf2ea6e4cf190b8754196a9b62366095ff8
4
- data.tar.gz: 49129fb0e16c0554ef74d9a94b2d40a6eb08e4e8c92b41c8079887ee180b0cbe
3
+ metadata.gz: 8dbaecce413d6a977eee8d4d440a066a666f2054ad7d2b4cec0b21c6da4efe8e
4
+ data.tar.gz: 39431e80439522e9d000404ee29856f558ba3b4406976e9345e550f4efbf3974
5
5
  SHA512:
6
- metadata.gz: e4ef5e308449ad6342a3df1834fdd2d14511d3bcaaac4f180af4ac9d2a424493abc90c6660b119b5e688994f09db6d5393b88f710ad4f261711ca7bac4f0eeec
7
- data.tar.gz: a38f706880d1e63ac4264926199152aae8e5aab401754f58f20f301227bbdecb89ef01327f9837605f9f5ee1d0c4b276ff4f109fb1e28e151544b390b4ebc704
6
+ metadata.gz: dc62197de1ada4a3e155148fa09926ffd02861178f1049203b1212a363b60d01d11fe3881f3e61d86a57b666464084d511aec4b4664e8fd038904468b9fb315f
7
+ data.tar.gz: f1ec0c729a1ccca0b2b9728ea23348db8cb5e5d80b22ec06dc33a682fb04a76c47cd0b487d578d8b19d2e62dfb7ac3c4f638aac03a9f8fa7a4c791f882e10259
data/Gemfile.lock CHANGED
@@ -102,7 +102,7 @@ GEM
102
102
  parser (3.3.10.0)
103
103
  ast (~> 2.4.1)
104
104
  racc
105
- prism (1.7.0)
105
+ prism (1.8.0)
106
106
  psych (5.3.1)
107
107
  date
108
108
  stringio
@@ -115,7 +115,7 @@ GEM
115
115
  racc (1.8.1)
116
116
  rainbow (3.1.1)
117
117
  rake (13.3.1)
118
- rdoc (7.0.3)
118
+ rdoc (7.1.0)
119
119
  erb
120
120
  psych (>= 4.0.0)
121
121
  tsort
data/features/cli.feature CHANGED
@@ -33,7 +33,7 @@ Feature: Command Line Processing
33
33
  Then Exit code is zero
34
34
 
35
35
  Scenario: Bitcoin balance can be checked
36
- When I run bin/sibit with "balance 1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f --verbose --api=blockchain,btc"
36
+ When I run bin/sibit with "balance 1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f --verbose"
37
37
  Then Exit code is zero
38
38
 
39
39
  Scenario: Bitcoin fees can be printed
data/features/dry.feature CHANGED
@@ -3,22 +3,6 @@
3
3
  Feature: Command Line Processing
4
4
  As a holder of BTC I want to use sibit in dry mode
5
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
6
  Scenario: Bitcoin payment can be sent
23
7
  When I run bin/sibit with "pay --dry --verbose --api=fake --proxy=localhost:3128 999999 XL- 46feba063e9b59a8ae0dba68abd39a3cb8f52089e776576d6eb1bb5bfec123d1 1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f 1Fsyq5YGe8zbSjLS8YsDnZWM8U6AYMR6ZD"
24
8
  Then Exit code is not zero
@@ -0,0 +1,25 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
2
+ # SPDX-License-Identifier: MIT
3
+ Feature: Command Line Processing
4
+ As a holder of BTC I want to use sibit with fake provider
5
+
6
+ Scenario: Bitcoin price can be retrieved
7
+ When I run bin/sibit with "price --attempts=4 --api=fake"
8
+ Then Exit code is zero
9
+
10
+ Scenario: Bitcoin latest block hash can be retrieved
11
+ When I run bin/sibit with "latest --api=fake"
12
+ Then Exit code is zero
13
+
14
+ Scenario: Bitcoin balance can be checked
15
+ When I run bin/sibit with "balance 1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f --verbose --api=fake"
16
+ Then Exit code is zero
17
+
18
+ Scenario: Bitcoin fees can be printed
19
+ When I run bin/sibit with "fees --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 --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"
data/lib/sibit/key.rb CHANGED
@@ -7,6 +7,7 @@ require 'digest'
7
7
  require 'openssl'
8
8
  require_relative 'base58'
9
9
  require_relative 'bech32'
10
+ require_relative 'error'
10
11
 
11
12
  # Sibit main class.
12
13
  class Sibit
@@ -61,24 +62,36 @@ class Sibit
61
62
  def bech32
62
63
  hrp = { mainnet: 'bc', testnet: 'tb', regtest: 'bcrt' }[@network]
63
64
  hex = pub
64
- raise 'Invalid public key: not on curve' unless @key.public_key.on_curve?
65
- raise 'Invalid public key format' unless hex.match?(/\A0[23][0-9a-f]{64}\z/)
66
- Bech32.encode(hrp, 0, hash160(hex))
65
+ raise Error, 'Invalid public key: not on curve' unless @key.public_key.on_curve?
66
+ raise Error, 'Invalid public key format' unless hex.match?(/\A0[23][0-9a-f]{64}\z/)
67
+ addr = Bech32.encode(hrp, 0, hash160(hex))
68
+ expected = /\A#{hrp}1q[a-z0-9]{38,58}\z/
69
+ raise Error, "Invalid bech32 address: #{addr}" unless addr.match?(expected)
70
+ addr
67
71
  end
68
72
 
69
73
  def base58
70
74
  hex = pub
71
- raise 'Invalid public key: not on curve' unless @key.public_key.on_curve?
72
- raise 'Invalid public key format' unless hex.match?(/\A0[23][0-9a-f]{64}\z/)
75
+ raise Error, 'Invalid public key: not on curve' unless @key.public_key.on_curve?
76
+ raise Error, 'Invalid public key format' unless hex.match?(/\A0[23][0-9a-f]{64}\z/)
73
77
  hash = hash160(hex)
74
78
  prefix = @network == :mainnet ? '00' : '6f'
75
79
  versioned = "#{prefix}#{hash}"
76
80
  checksum = Base58.new(versioned).check
77
- Base58.new(versioned + checksum).encode
81
+ addr = Base58.new(versioned + checksum).encode
82
+ mainnet = /\A1[1-9A-HJ-NP-Za-km-z]{25,34}\z/
83
+ testnet = /\A[mn][1-9A-HJ-NP-Za-km-z]{25,34}\z/
84
+ unless addr.match?(@network == :mainnet ? mainnet : testnet)
85
+ raise Error,
86
+ "Invalid base58 address: #{addr}"
87
+ end
88
+ addr
78
89
  end
79
90
 
80
91
  def sign(data)
81
- @key.dsa_sign_asn1(data)
92
+ sig = @key.dsa_sign_asn1(data)
93
+ raise Error, 'Signature verification failed' unless verify(data, sig)
94
+ sig
82
95
  end
83
96
 
84
97
  def verify(data, sig)
@@ -91,7 +104,7 @@ class Sibit
91
104
 
92
105
  def build(privkey)
93
106
  value = privkey.to_i(16)
94
- raise 'private key is not on curve' unless value.between?(MIN_PRIV, MAX_PRIV)
107
+ raise Error, 'Private key is not on curve' unless value.between?(MIN_PRIV, MAX_PRIV)
95
108
  group = OpenSSL::PKey::EC::Group.new('secp256k1')
96
109
  bn = OpenSSL::BN.new(privkey, 16)
97
110
  pubkey = group.generator.mul(bn)
@@ -114,10 +127,15 @@ class Sibit
114
127
  def decode(key)
115
128
  if key.length == 64 && key.match?(/\A[0-9a-f]+\z/i)
116
129
  @network = @override || :mainnet
117
- return key
130
+ return key.downcase
118
131
  end
119
132
  raw = Base58.new(key).decode
133
+ payload = raw[0..-9]
134
+ checksum = raw[-8..]
135
+ expected = Base58.new(payload).check
136
+ raise Error, 'Invalid WIF checksum' unless checksum == expected
120
137
  version = raw[0, 2]
138
+ raise Error, "Invalid WIF version: #{version}" unless %w[80 ef].include?(version)
121
139
  detected = version == '80' ? :mainnet : :testnet
122
140
  @network = @override || detected
123
141
  body = raw[2..-9]
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.32.7' unless defined?(VERSION)
12
+ VERSION = '0.32.8' unless defined?(VERSION)
13
13
  end
data/lib/sibit.rb CHANGED
@@ -53,7 +53,7 @@ class Sibit
53
53
  # Generates new Bitcoin private key and returns in Hash160 format.
54
54
  def generate
55
55
  key = Key.generate.priv
56
- @log.debug("Bitcoin private key generated: #{key[0..8]}...")
56
+ @log.debug("Bitcoin private key generated: #{key.ellipsized(8)}...")
57
57
  key
58
58
  end
59
59
 
@@ -181,19 +181,28 @@ class Sibit
181
181
  change_address: change
182
182
  )
183
183
  left = unspent - tx.outputs.sum(&:value)
184
- @log.debug("A new Bitcoin transaction #{tx.hash} prepared:
185
- #{tx.in.count} input#{'s' if tx.in.count > 1}:
186
- #{tx.inputs.map { |i| " in: #{i.prev_out.unpack1('H*')}:#{i.prev_out_index}" }.join("\n ")}
187
- #{tx.out.count} output#{'s' if tx.out.count > 1}:
188
- #{tx.outputs.map { |o| "out: #{o.script_hex} / #{num(o.value, p)}" }.join("\n ")}
189
- Min fee: #{num(MIN_SATOSHI_PER_BYTE, p)} /byte
190
- Fee requested: #{num(f, p)} as \"#{fee}\"
191
- Fee actually paid: #{num(left, p)}
192
- Tx size: #{size} bytes
193
- Unspent: #{num(unspent, p)}
194
- Amount: #{num(satoshi, p)}
195
- Target address: #{target}
196
- Change address is #{change}")
184
+ has_change = tx.out.count > 1
185
+ @log.debug(
186
+ [
187
+ "A new Bitcoin transaction #{tx.hash} prepared:",
188
+ "#{tx.in.count} input#{'s' if tx.in.count > 1}:",
189
+ tx.inputs.map do |i|
190
+ " in: #{i.prev_out.unpack1('H*')}:#{i.prev_out_index}"
191
+ end,
192
+ "#{tx.out.count} output#{'s' if tx.out.count > 1}:",
193
+ tx.outputs.map do |o|
194
+ " out: #{o.script_hex} / #{num(o.value, p)}"
195
+ end,
196
+ "Min fee: #{num(MIN_SATOSHI_PER_BYTE, p)} /byte",
197
+ "Fee requested: #{num(f, p)} as \"#{fee}\"",
198
+ "Fee actually paid: #{num(left, p)}",
199
+ "Tx size: #{size} bytes",
200
+ "Unspent: #{num(unspent, p)}",
201
+ "Amount: #{num(satoshi, p)}",
202
+ "Target address: #{target}",
203
+ ("Change address: #{change}" if has_change)
204
+ ].flatten.compact.join("\n")
205
+ )
197
206
  @api.push(tx.to_payload.bth)
198
207
  tx.hash
199
208
  end
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.32.7
4
+ version: 0.32.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -171,6 +171,7 @@ files:
171
171
  - cucumber.yml
172
172
  - features/cli.feature
173
173
  - features/dry.feature
174
+ - features/fake.feature
174
175
  - features/gem_package.feature
175
176
  - features/step_definitions/steps.rb
176
177
  - features/support/env.rb