sibit 0.32.3 → 0.32.5

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: 196fa93e65ec890ca33a83d3d56358f311d57933e20432e61b5e3df32ae8515d
4
- data.tar.gz: 0d02c5a2f773d84dbd13c614c6e52533e88a88dff5c07e4ff304650311ce5a22
3
+ metadata.gz: '0721649ca64aee7e164f1ebffef396e8227a9011bb2e3ca6d392dcbbbcf80965'
4
+ data.tar.gz: d26bb44f64aa20fc6e44eab1fe2cfc5f7bfb6b7c02615abbc3c5002161d94ebc
5
5
  SHA512:
6
- metadata.gz: b62032df000f92c6e58147224c5055c3db2ac1798308022899b0e5a5706b691deb9b948733514bcbbac80e70b2ea9f31e085a1da9557a37fd60076240face315
7
- data.tar.gz: 21601d77cf209b9980caef8567321f018efe4442eec5caa96f2e791865519c7499d3f7c64111c01823e90ffeb2ed808608fc7e3387c3fda47d3056612a13449c
6
+ metadata.gz: 8896cc874ca2a200a4000d8ed4f8b8a93134d1b3326c0051588dad3ce3edf7c59e58bbfc9f4a8a8d1fc820d1b32aa7a70211f2f3b5e638e862b15767c98ffa60
7
+ data.tar.gz: 6b8eb51d3f7c2cb61090db5dc7aabeecb99d6400a385883ea2cf9d6340ea39a44a50ac164b88e922e2df204bffe9070c8e68a9b37213923a4b997630c97fda6f
data/features/cli.feature CHANGED
@@ -24,6 +24,14 @@ Feature: Command Line Processing
24
24
  When I run bin/sibit with "create 46feba063e9b59a8ae0dba68abd39a3cb8f52089e776576d6eb1bb5bfec123d1"
25
25
  Then Exit code is zero
26
26
 
27
+ Scenario: Bitcoin address can be created with base58 option at the end
28
+ When I run bin/sibit with "create 46feba063e9b59a8ae0dba68abd39a3cb8f52089e776576d6eb1bb5bfec123d1 --base58"
29
+ Then Exit code is zero
30
+
31
+ Scenario: Bitcoin address can be created with base58 option before command
32
+ When I run bin/sibit with "--base58 create 46feba063e9b59a8ae0dba68abd39a3cb8f52089e776576d6eb1bb5bfec123d1"
33
+ Then Exit code is zero
34
+
27
35
  Scenario: Bitcoin balance can be checked
28
36
  When I run bin/sibit with "balance 1MZT1fa6y8H9UmbZV6HqKF4UY41o9MGT5f --verbose --api=blockchain,btc"
29
37
  Then Exit code is zero
@@ -36,3 +44,8 @@ Feature: Command Line Processing
36
44
  When I run bin/sibit with "pay --help"
37
45
  Then Exit code is zero
38
46
  And Stdout contains "--skip-utxo"
47
+
48
+ Scenario: Unknown option shows error message
49
+ When I run bin/sibit with "generate --foo"
50
+ Then Exit code is not zero
51
+ And Stdout contains "Unknown option"
@@ -27,7 +27,7 @@ end
27
27
 
28
28
  When(%r{^I run bin/sibit with "([^"]*)"$}) do |arg|
29
29
  home = File.join(File.dirname(__FILE__), '../..')
30
- @stdout = `ruby -I#{home}/lib #{home}/bin/sibit #{arg}`
30
+ @stdout = `ruby -I#{home}/lib #{home}/bin/sibit #{arg} 2>&1`
31
31
  @exitstatus = $CHILD_STATUS.exitstatus
32
32
  end
33
33
 
data/lib/sibit/bin.rb CHANGED
@@ -20,6 +20,8 @@ class Sibit
20
20
  # Sibit::Bin.start(['price'])
21
21
  # Sibit::Bin.start(['balance', '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa'])
22
22
  class Bin < Thor
23
+ stop_on_unknown_option!
24
+
23
25
  class_option :proxy, type: :string, desc: 'HTTPS proxy for all requests, e.g. "localhost:3128"'
24
26
  class_option :attempts, type: :numeric, default: 1,
25
27
  desc: 'How many times should we try before failing'
@@ -29,14 +31,21 @@ class Sibit
29
31
  class_option :quiet, type: :boolean, default: false, desc: 'Print only informative messages'
30
32
  class_option :api, type: :array, default: %w[blockchain btc bitcoinchain blockchair cex],
31
33
  desc: 'Ordered List of APIs to use, e.g. "blockchain,btc,bitcoinchain"'
34
+ class_option :base58, type: :boolean, default: false,
35
+ desc: 'Use base58 address format instead of bech32'
32
36
 
33
37
  def self.exit_on_failure?
34
38
  true
35
39
  end
36
40
 
37
41
  def self.handle_argument_error(command, error, args, _arity)
38
- raise error unless args.include?('--help') || args.include?('-h')
39
- new.help(command.name)
42
+ return new.help(command.name) if args.include?('--help') || args.include?('-h')
43
+ unknown = args.find { |a| a.start_with?('-') }
44
+ if unknown
45
+ warn "Unknown option: #{unknown}"
46
+ exit 1
47
+ end
48
+ raise error
40
49
  end
41
50
 
42
51
  desc 'price', 'Get current price of BTC in USD'
@@ -69,7 +78,8 @@ class Sibit
69
78
  desc 'create KEY', 'Create a public Bitcoin address from the private key'
70
79
  def create(key)
71
80
  log.debug("Private key provided: #{key.ellipsized(8).inspect}")
72
- log.info(client.create(key))
81
+ k = Sibit::Key.new(key)
82
+ log.info(options[:base58] ? k.base58 : k.bech32)
73
83
  end
74
84
 
75
85
  desc 'balance ADDRESS', 'Check the balance of the Bitcoin address'
@@ -82,8 +92,6 @@ class Sibit
82
92
  'Send a new Bitcoin transaction (AMOUNT can be "MAX" to use full balance)'
83
93
  option :skip_utxo, type: :array, default: [],
84
94
  desc: 'List of UTXO that must be skipped while paying'
85
- option :base58, type: :boolean, default: false,
86
- desc: 'Convert private addresses to public in base58'
87
95
  option :yes, type: :boolean, default: false,
88
96
  desc: 'Skip confirmation prompt and send the payment immediately'
89
97
  def pay(amount, fee, sources, target, change)
data/lib/sibit/key.rb CHANGED
@@ -22,12 +22,23 @@ class Sibit
22
22
  MIN_PRIV = 0x01
23
23
  MAX_PRIV = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140
24
24
 
25
+ SECP256K1_N = OpenSSL::BN.new(
26
+ 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16
27
+ )
28
+
25
29
  attr_reader :network
26
30
 
27
31
  def self.generate(network: :mainnet)
28
32
  key = OpenSSL::PKey::EC.generate('secp256k1')
29
- pvt = key.private_key.to_s(16).rjust(64, '0').downcase
30
- new(pvt, network: network)
33
+ pvt = key.private_key
34
+ raise 'Invalid private key: zero' if pvt.zero?
35
+ raise 'Invalid private key: out of range' if pvt >= SECP256K1_N
36
+ raise 'Invalid public key: not on curve' unless key.public_key.on_curve?
37
+ hex = key.private_key.to_s(16).rjust(64, '0').downcase
38
+ raise 'Invalid private key encoding' unless hex.match?(/\A[0-9a-f]{64}\z/)
39
+ trip = OpenSSL::BN.new(hex, 16)
40
+ raise 'Private key serialization is lossy' unless trip == pvt
41
+ new(hex, network: network)
31
42
  end
32
43
 
33
44
  def initialize(privkey, network: nil)
@@ -49,11 +60,17 @@ class Sibit
49
60
 
50
61
  def bech32
51
62
  hrp = { mainnet: 'bc', testnet: 'tb', regtest: 'bcrt' }[@network]
52
- Bech32.encode(hrp, 0, hash160(pub))
63
+ 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))
53
67
  end
54
68
 
55
69
  def base58
56
- hash = hash160(pub)
70
+ 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/)
73
+ hash = hash160(hex)
57
74
  prefix = @network == :mainnet ? '00' : '6f'
58
75
  versioned = "#{prefix}#{hash}"
59
76
  checksum = Base58.new(versioned).check
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.3' unless defined?(VERSION)
12
+ VERSION = '0.32.5' unless defined?(VERSION)
13
13
  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.3
4
+ version: 0.32.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko