sibit 0.30.6 → 0.30.7
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 +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +11 -9
- data/LICENSE.txt +1 -1
- data/LICENSES/MIT.txt +1 -1
- data/Rakefile +1 -1
- data/bin/sibit +3 -1
- data/cucumber.yml +1 -1
- data/features/cli.feature +1 -1
- data/features/dry.feature +1 -1
- data/features/gem_package.feature +1 -1
- data/features/step_definitions/steps.rb +1 -1
- data/features/support/env.rb +1 -1
- data/lib/sibit/base58.rb +2 -2
- data/lib/sibit/bech32.rb +48 -4
- data/lib/sibit/bestof.rb +2 -2
- data/lib/sibit/bitcoinchain.rb +2 -2
- data/lib/sibit/blockchain.rb +2 -2
- data/lib/sibit/blockchair.rb +2 -2
- data/lib/sibit/btc.rb +2 -2
- data/lib/sibit/cex.rb +2 -2
- data/lib/sibit/cryptoapis.rb +2 -2
- data/lib/sibit/dry.rb +2 -2
- data/lib/sibit/error.rb +2 -2
- data/lib/sibit/fake.rb +2 -2
- data/lib/sibit/firstof.rb +2 -2
- data/lib/sibit/http.rb +2 -2
- data/lib/sibit/httpproxy.rb +2 -2
- data/lib/sibit/json.rb +2 -2
- data/lib/sibit/key.rb +19 -8
- data/lib/sibit/script.rb +22 -5
- data/lib/sibit/tx.rb +88 -13
- data/lib/sibit/txbuilder.rb +12 -7
- data/lib/sibit/version.rb +3 -3
- data/lib/sibit.rb +9 -6
- data/sibit.gemspec +2 -1
- metadata +15 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3c1f18b76d75fe20bb741ac3c033bde8df69a6f54bb31e0b26f03e900d04f635
|
|
4
|
+
data.tar.gz: ae570fa1bf67e683ac1c3a6f7754c225d6a6eea3e2376d2d2d96fc18a39504bf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 60685974e155e059ccc11607b731b32e27df7cec9b51db25701a174c3dee9ac1a22890e922d9b61727bd886b480f01819848b35869b18f2fc96e9fd045d2074e
|
|
7
|
+
data.tar.gz: 773589a2fd128215dd2d16ddcd3ad0a89c983367dbd5c224afd90f4f1894cd37d07ee255406ce8372f0ac05327fe7d3efc44e8bf5db1c696c41781d4ea1a53df
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -5,6 +5,7 @@ PATH
|
|
|
5
5
|
backtrace (~> 0.3)
|
|
6
6
|
decoor (~> 0.1)
|
|
7
7
|
elapsed (~> 0.2)
|
|
8
|
+
ellipsized (~> 0.3)
|
|
8
9
|
iri (~> 0.5)
|
|
9
10
|
json (~> 2.18)
|
|
10
11
|
loog (~> 0.6)
|
|
@@ -62,18 +63,19 @@ GEM
|
|
|
62
63
|
decoor (0.1.0)
|
|
63
64
|
diff-lcs (1.6.2)
|
|
64
65
|
docile (1.4.1)
|
|
65
|
-
donce (0.
|
|
66
|
+
donce (0.3.0)
|
|
66
67
|
backtrace (~> 0.3)
|
|
67
68
|
os (~> 1.1)
|
|
68
69
|
qbash (~> 0.3)
|
|
69
70
|
elapsed (0.2.1)
|
|
70
71
|
loog (~> 0.6)
|
|
71
72
|
tago (~> 0.1)
|
|
73
|
+
ellipsized (0.3.0)
|
|
72
74
|
erb (6.0.1)
|
|
73
|
-
ffi (1.17.
|
|
74
|
-
ffi (1.17.
|
|
75
|
+
ffi (1.17.3-arm64-darwin)
|
|
76
|
+
ffi (1.17.3-x86_64-linux-gnu)
|
|
75
77
|
hashdiff (1.2.1)
|
|
76
|
-
iri (0.11.
|
|
78
|
+
iri (0.11.4)
|
|
77
79
|
json (2.18.0)
|
|
78
80
|
language_server-protocol (3.17.0.5)
|
|
79
81
|
lint_roller (1.1.0)
|
|
@@ -82,7 +84,6 @@ GEM
|
|
|
82
84
|
logger (~> 1.0)
|
|
83
85
|
memoist3 (1.0.0)
|
|
84
86
|
mini_mime (1.1.5)
|
|
85
|
-
mini_portile2 (2.8.9)
|
|
86
87
|
minitest (6.0.1)
|
|
87
88
|
prism (~> 1.5)
|
|
88
89
|
minitest-reporters (1.7.1)
|
|
@@ -91,8 +92,9 @@ GEM
|
|
|
91
92
|
minitest (>= 5.0)
|
|
92
93
|
ruby-progressbar
|
|
93
94
|
multi_test (1.1.0)
|
|
94
|
-
nokogiri (1.
|
|
95
|
-
|
|
95
|
+
nokogiri (1.19.0-arm64-darwin)
|
|
96
|
+
racc (~> 1.4)
|
|
97
|
+
nokogiri (1.19.0-x86_64-linux-gnu)
|
|
96
98
|
racc (~> 1.4)
|
|
97
99
|
openssl (3.3.2)
|
|
98
100
|
os (1.1.4)
|
|
@@ -137,9 +139,9 @@ GEM
|
|
|
137
139
|
rubocop-ast (>= 1.48.0, < 2.0)
|
|
138
140
|
ruby-progressbar (~> 1.7)
|
|
139
141
|
unicode-display_width (>= 2.4.0, < 4.0)
|
|
140
|
-
rubocop-ast (1.
|
|
142
|
+
rubocop-ast (1.49.0)
|
|
141
143
|
parser (>= 3.3.7.2)
|
|
142
|
-
prism (~> 1.
|
|
144
|
+
prism (~> 1.7)
|
|
143
145
|
rubocop-minitest (0.38.2)
|
|
144
146
|
lint_roller (~> 1.1)
|
|
145
147
|
rubocop (>= 1.75.0, < 2.0)
|
data/LICENSE.txt
CHANGED
data/LICENSES/MIT.txt
CHANGED
data/Rakefile
CHANGED
data/bin/sibit
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
4
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
5
5
|
# SPDX-License-Identifier: MIT
|
|
6
6
|
|
|
7
7
|
$stdout.sync = true
|
|
8
8
|
|
|
9
9
|
require 'backtrace'
|
|
10
|
+
require 'ellipsized'
|
|
10
11
|
require 'loog'
|
|
11
12
|
require 'retriable_proxy'
|
|
12
13
|
require 'slop'
|
|
@@ -110,6 +111,7 @@ begin
|
|
|
110
111
|
when 'create'
|
|
111
112
|
pvt = opts.arguments[1]
|
|
112
113
|
raise 'Private key argument is required' if pvt.nil?
|
|
114
|
+
log.debug("Private key provided: #{pvt.ellipsized(8).inspect}")
|
|
113
115
|
log.info(sibit.create(pvt))
|
|
114
116
|
when 'balance'
|
|
115
117
|
address = opts.arguments[1]
|
data/cucumber.yml
CHANGED
data/features/cli.feature
CHANGED
data/features/dry.feature
CHANGED
data/features/support/env.rb
CHANGED
data/lib/sibit/base58.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'digest'
|
|
@@ -13,7 +13,7 @@ class Sibit
|
|
|
13
13
|
# Encapsulates hex data and provides encoding/decoding functionality.
|
|
14
14
|
#
|
|
15
15
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
16
|
-
# Copyright:: Copyright (c) 2019-
|
|
16
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
17
17
|
# License:: MIT
|
|
18
18
|
class Base58
|
|
19
19
|
ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
data/lib/sibit/bech32.rb
CHANGED
|
@@ -1,23 +1,67 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require_relative 'error'
|
|
7
7
|
|
|
8
8
|
# Sibit main class.
|
|
9
9
|
class Sibit
|
|
10
|
-
# Bech32 decoding for SegWit addresses.
|
|
10
|
+
# Bech32 encoding and decoding for SegWit addresses.
|
|
11
11
|
#
|
|
12
|
-
#
|
|
12
|
+
# Encodes witness programs to Bech32 addresses (bc1...) and decodes them back.
|
|
13
13
|
#
|
|
14
14
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
15
|
-
# Copyright:: Copyright (c) 2019-
|
|
15
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
16
16
|
# License:: MIT
|
|
17
17
|
class Bech32
|
|
18
18
|
CHARSET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'
|
|
19
19
|
GENERATOR = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3].freeze
|
|
20
20
|
|
|
21
|
+
def self.encode(hrp, ver, prog)
|
|
22
|
+
bytes = [prog].pack('H*').bytes
|
|
23
|
+
data = [ver] + bits(bytes, 8, 5, true)
|
|
24
|
+
chk = checksum(hrp, data)
|
|
25
|
+
"#{hrp}1#{(data + chk).map { |d| CHARSET[d] }.join}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.checksum(hrp, data)
|
|
29
|
+
values = expanded(hrp) + data + [0, 0, 0, 0, 0, 0]
|
|
30
|
+
poly = pm(values) ^ 1
|
|
31
|
+
(0..5).map { |i| (poly >> (5 * (5 - i))) & 31 }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.expanded(hrp)
|
|
35
|
+
hrp.chars.map { |c| c.ord >> 5 } + [0] + hrp.chars.map { |c| c.ord & 31 }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.pm(values)
|
|
39
|
+
chk = 1
|
|
40
|
+
values.each do |v|
|
|
41
|
+
top = chk >> 25
|
|
42
|
+
chk = ((chk & 0x1ffffff) << 5) ^ v
|
|
43
|
+
5.times { |i| chk ^= GENERATOR[i] if (top >> i).allbits?(1) }
|
|
44
|
+
end
|
|
45
|
+
chk
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.bits(data, frombits, tobits, pad)
|
|
49
|
+
acc = 0
|
|
50
|
+
num = 0
|
|
51
|
+
result = []
|
|
52
|
+
maxv = (1 << tobits) - 1
|
|
53
|
+
data.each do |v|
|
|
54
|
+
acc = (acc << frombits) | v
|
|
55
|
+
num += frombits
|
|
56
|
+
while num >= tobits
|
|
57
|
+
num -= tobits
|
|
58
|
+
result << ((acc >> num) & maxv)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
result << ((acc << (tobits - num)) & maxv) if pad && num.positive?
|
|
62
|
+
result
|
|
63
|
+
end
|
|
64
|
+
|
|
21
65
|
def initialize(addr)
|
|
22
66
|
@addr = addr.downcase
|
|
23
67
|
end
|
data/lib/sibit/bestof.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'backtrace'
|
|
@@ -10,7 +10,7 @@ require_relative 'error'
|
|
|
10
10
|
# API best of.
|
|
11
11
|
#
|
|
12
12
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
13
|
-
# Copyright:: Copyright (c) 2019-
|
|
13
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
14
14
|
# License:: MIT
|
|
15
15
|
class Sibit::BestOf
|
|
16
16
|
# Constructor.
|
data/lib/sibit/bitcoinchain.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'iri'
|
|
@@ -15,7 +15,7 @@ require_relative 'version'
|
|
|
15
15
|
# Bitcoinchain.com API.
|
|
16
16
|
#
|
|
17
17
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
18
|
-
# Copyright:: Copyright (c) 2019-
|
|
18
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
19
19
|
# License:: MIT
|
|
20
20
|
class Sibit::Bitcoinchain
|
|
21
21
|
# Constructor.
|
data/lib/sibit/blockchain.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'iri'
|
|
@@ -18,7 +18,7 @@ require_relative 'version'
|
|
|
18
18
|
# https://www.blockchain.com/api/blockchain_api
|
|
19
19
|
#
|
|
20
20
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
21
|
-
# Copyright:: Copyright (c) 2019-
|
|
21
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
22
22
|
# License:: MIT
|
|
23
23
|
class Sibit::Blockchain
|
|
24
24
|
# Constructor.
|
data/lib/sibit/blockchair.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'cgi'
|
|
@@ -16,7 +16,7 @@ require_relative 'version'
|
|
|
16
16
|
# Blockchair.com API.
|
|
17
17
|
#
|
|
18
18
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
19
|
-
# Copyright:: Copyright (c) 2019-
|
|
19
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
20
20
|
# License:: MIT
|
|
21
21
|
class Sibit::Blockchair
|
|
22
22
|
# Constructor.
|
data/lib/sibit/btc.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'iri'
|
|
@@ -17,7 +17,7 @@ require_relative 'version'
|
|
|
17
17
|
# Here: https://btc.com/api-doc
|
|
18
18
|
#
|
|
19
19
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
20
|
-
# Copyright:: Copyright (c) 2019-
|
|
20
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
21
21
|
# License:: MIT
|
|
22
22
|
class Sibit::Btc
|
|
23
23
|
# Constructor.
|
data/lib/sibit/cex.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'iri'
|
|
@@ -14,7 +14,7 @@ require_relative 'json'
|
|
|
14
14
|
# Cex.io API.
|
|
15
15
|
#
|
|
16
16
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
17
|
-
# Copyright:: Copyright (c) 2019-
|
|
17
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
18
18
|
# License:: MIT
|
|
19
19
|
class Sibit::Cex
|
|
20
20
|
# Constructor.
|
data/lib/sibit/cryptoapis.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'iri'
|
|
@@ -15,7 +15,7 @@ require_relative 'version'
|
|
|
15
15
|
# Cryptoapis.io API.
|
|
16
16
|
#
|
|
17
17
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
18
|
-
# Copyright:: Copyright (c) 2019-
|
|
18
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
19
19
|
# License:: MIT
|
|
20
20
|
class Sibit::Cryptoapis
|
|
21
21
|
# Constructor.
|
data/lib/sibit/dry.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'decoor'
|
|
@@ -12,7 +12,7 @@ require 'loog'
|
|
|
12
12
|
# All other methods are delegated to the wrapped API unchanged.
|
|
13
13
|
#
|
|
14
14
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
15
|
-
# Copyright:: Copyright (c) 2019-
|
|
15
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
16
16
|
# License:: MIT
|
|
17
17
|
class Sibit::Dry
|
|
18
18
|
def initialize(api, log: Loog::NULL)
|
data/lib/sibit/error.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
# The error.
|
|
7
7
|
#
|
|
8
8
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
9
|
-
# Copyright:: Copyright (c) 2019-
|
|
9
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
10
10
|
# License:: MIT
|
|
11
11
|
class Sibit
|
|
12
12
|
# The error.
|
data/lib/sibit/fake.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require_relative 'version'
|
|
@@ -8,7 +8,7 @@ require_relative 'version'
|
|
|
8
8
|
# Fake API.
|
|
9
9
|
#
|
|
10
10
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
11
|
-
# Copyright:: Copyright (c) 2019-
|
|
11
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
12
12
|
# License:: MIT
|
|
13
13
|
class Sibit::Fake
|
|
14
14
|
def price(_cur = 'USD')
|
data/lib/sibit/firstof.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'backtrace'
|
|
@@ -10,7 +10,7 @@ require_relative 'error'
|
|
|
10
10
|
# API first of.
|
|
11
11
|
#
|
|
12
12
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
13
|
-
# Copyright:: Copyright (c) 2019-
|
|
13
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
14
14
|
# License:: MIT
|
|
15
15
|
class Sibit::FirstOf
|
|
16
16
|
# Constructor.
|
data/lib/sibit/http.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'net/http'
|
|
@@ -10,7 +10,7 @@ class Sibit
|
|
|
10
10
|
# HTTP interface.
|
|
11
11
|
#
|
|
12
12
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
13
|
-
# Copyright:: Copyright (c) 2019-
|
|
13
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
14
14
|
# License:: MIT
|
|
15
15
|
class Http
|
|
16
16
|
def client(uri)
|
data/lib/sibit/httpproxy.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'net/http'
|
|
@@ -12,7 +12,7 @@ class Sibit
|
|
|
12
12
|
# Accepts proxy address in format: host:port or user:password@host:port
|
|
13
13
|
#
|
|
14
14
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
15
|
-
# Copyright:: Copyright (c) 2019-
|
|
15
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
16
16
|
# License:: MIT
|
|
17
17
|
class HttpProxy
|
|
18
18
|
def initialize(addr)
|
data/lib/sibit/json.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'cgi'
|
|
@@ -18,7 +18,7 @@ require_relative 'version'
|
|
|
18
18
|
# https://www.blockchain.com/api/blockchain_api
|
|
19
19
|
#
|
|
20
20
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
21
|
-
# Copyright:: Copyright (c) 2019-
|
|
21
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
22
22
|
# License:: MIT
|
|
23
23
|
class Sibit::Json
|
|
24
24
|
# Constructor.
|
data/lib/sibit/key.rb
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'digest'
|
|
7
7
|
require 'openssl'
|
|
8
8
|
require_relative 'base58'
|
|
9
|
+
require_relative 'bech32'
|
|
9
10
|
|
|
10
11
|
# Sibit main class.
|
|
11
12
|
class Sibit
|
|
@@ -15,7 +16,7 @@ class Sibit
|
|
|
15
16
|
# of using deprecated mutable key APIs.
|
|
16
17
|
#
|
|
17
18
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
18
|
-
# Copyright:: Copyright (c) 2019-
|
|
19
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
19
20
|
# License:: MIT
|
|
20
21
|
class Key
|
|
21
22
|
MIN_PRIV = 0x01
|
|
@@ -23,13 +24,14 @@ class Sibit
|
|
|
23
24
|
|
|
24
25
|
attr_reader :network
|
|
25
26
|
|
|
26
|
-
def self.generate
|
|
27
|
+
def self.generate(network: :mainnet)
|
|
27
28
|
key = OpenSSL::PKey::EC.generate('secp256k1')
|
|
28
29
|
pvt = key.private_key.to_s(16).rjust(64, '0').downcase
|
|
29
|
-
new(pvt)
|
|
30
|
+
new(pvt, network: network)
|
|
30
31
|
end
|
|
31
32
|
|
|
32
|
-
def initialize(privkey)
|
|
33
|
+
def initialize(privkey, network: nil)
|
|
34
|
+
@override = network
|
|
33
35
|
@network = :mainnet
|
|
34
36
|
@compressed = true
|
|
35
37
|
@privkey = decode(privkey)
|
|
@@ -45,7 +47,12 @@ class Sibit
|
|
|
45
47
|
point.to_octet_string(@compressed ? :compressed : :uncompressed).unpack1('H*')
|
|
46
48
|
end
|
|
47
49
|
|
|
48
|
-
def
|
|
50
|
+
def bech32
|
|
51
|
+
hrp = { mainnet: 'bc', testnet: 'tb', regtest: 'bcrt' }[@network]
|
|
52
|
+
Bech32.encode(hrp, 0, hash160(pub))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def base58
|
|
49
56
|
hash = hash160(pub)
|
|
50
57
|
prefix = @network == :mainnet ? '00' : '6f'
|
|
51
58
|
versioned = "#{prefix}#{hash}"
|
|
@@ -88,10 +95,14 @@ class Sibit
|
|
|
88
95
|
end
|
|
89
96
|
|
|
90
97
|
def decode(key)
|
|
91
|
-
|
|
98
|
+
if key.length == 64 && key.match?(/\A[0-9a-f]+\z/i)
|
|
99
|
+
@network = @override || :mainnet
|
|
100
|
+
return key
|
|
101
|
+
end
|
|
92
102
|
raw = Base58.new(key).decode
|
|
93
103
|
version = raw[0, 2]
|
|
94
|
-
|
|
104
|
+
detected = version == '80' ? :mainnet : :testnet
|
|
105
|
+
@network = @override || detected
|
|
95
106
|
body = raw[2..-9]
|
|
96
107
|
@compressed = body.length == 66 && body.end_with?('01')
|
|
97
108
|
@compressed ? body[0, 64] : body
|
data/lib/sibit/script.rb
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'digest'
|
|
7
7
|
require_relative 'base58'
|
|
8
|
+
require_relative 'bech32'
|
|
8
9
|
|
|
9
10
|
# Sibit main class.
|
|
10
11
|
class Sibit
|
|
11
12
|
# Bitcoin Script parser.
|
|
12
13
|
#
|
|
13
|
-
# Parses standard P2PKH scripts to extract addresses.
|
|
14
|
+
# Parses standard P2PKH and P2WPKH scripts to extract addresses.
|
|
14
15
|
#
|
|
15
16
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
16
|
-
# Copyright:: Copyright (c) 2019-
|
|
17
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
17
18
|
# License:: MIT
|
|
18
19
|
class Script
|
|
20
|
+
OP_0 = 0x00
|
|
19
21
|
OP_DUP = 0x76
|
|
20
22
|
OP_HASH160 = 0xa9
|
|
21
23
|
OP_EQUALVERIFY = 0x88
|
|
@@ -26,6 +28,7 @@ class Sibit
|
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
def address(network = :mainnet)
|
|
31
|
+
return p2wpkh_address(network) if p2wpkh?
|
|
29
32
|
return p2pkh_address(network) if p2pkh?
|
|
30
33
|
nil
|
|
31
34
|
end
|
|
@@ -39,9 +42,16 @@ class Sibit
|
|
|
39
42
|
@bytes[24] == OP_CHECKSIG
|
|
40
43
|
end
|
|
41
44
|
|
|
45
|
+
def p2wpkh?
|
|
46
|
+
@bytes.length == 22 &&
|
|
47
|
+
@bytes[0] == OP_0 &&
|
|
48
|
+
@bytes[1] == 20
|
|
49
|
+
end
|
|
50
|
+
|
|
42
51
|
def hash160
|
|
43
|
-
return
|
|
44
|
-
@bytes[3, 20].pack('C*').unpack1('H*')
|
|
52
|
+
return @bytes[2, 20].pack('C*').unpack1('H*') if p2wpkh?
|
|
53
|
+
return @bytes[3, 20].pack('C*').unpack1('H*') if p2pkh?
|
|
54
|
+
nil
|
|
45
55
|
end
|
|
46
56
|
|
|
47
57
|
private
|
|
@@ -54,5 +64,12 @@ class Sibit
|
|
|
54
64
|
checksum = Base58.new(versioned).check
|
|
55
65
|
Base58.new(versioned + checksum).encode
|
|
56
66
|
end
|
|
67
|
+
|
|
68
|
+
def p2wpkh_address(network)
|
|
69
|
+
h = hash160
|
|
70
|
+
return nil unless h
|
|
71
|
+
hrp = { mainnet: 'bc', testnet: 'tb', regtest: 'bcrt' }[network]
|
|
72
|
+
Bech32.encode(hrp, 0, h)
|
|
73
|
+
end
|
|
57
74
|
end
|
|
58
75
|
end
|
data/lib/sibit/tx.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'digest'
|
|
@@ -14,7 +14,7 @@ class Sibit
|
|
|
14
14
|
# Bitcoin Transaction structure.
|
|
15
15
|
#
|
|
16
16
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
17
|
-
# Copyright:: Copyright (c) 2019-
|
|
17
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
18
18
|
# License:: MIT
|
|
19
19
|
class Tx
|
|
20
20
|
SIGHASH_ALL = 0x01
|
|
@@ -28,8 +28,8 @@ class Sibit
|
|
|
28
28
|
@outputs = []
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
def add_input(hash:, index:, script:, key:)
|
|
32
|
-
@inputs << Input.new(hash, index, script, key)
|
|
31
|
+
def add_input(hash:, index:, script:, key:, value: 0)
|
|
32
|
+
@inputs << Input.new(hash, index, script, key, value)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def add_output(value, address)
|
|
@@ -60,18 +60,20 @@ class Sibit
|
|
|
60
60
|
# Transaction input.
|
|
61
61
|
#
|
|
62
62
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
63
|
-
# Copyright:: Copyright (c) 2019-
|
|
63
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
64
64
|
# License:: MIT
|
|
65
65
|
class Input
|
|
66
|
-
attr_reader :hash, :index, :prev_script, :key
|
|
67
|
-
attr_accessor :script_sig
|
|
66
|
+
attr_reader :hash, :index, :prev_script, :key, :value
|
|
67
|
+
attr_accessor :script_sig, :witness
|
|
68
68
|
|
|
69
|
-
def initialize(hash, index, script, key)
|
|
69
|
+
def initialize(hash, index, script, key, value)
|
|
70
70
|
@hash = hash
|
|
71
71
|
@index = index
|
|
72
72
|
@prev_script = script
|
|
73
73
|
@key = key
|
|
74
|
+
@value = value
|
|
74
75
|
@script_sig = ''
|
|
76
|
+
@witness = []
|
|
75
77
|
end
|
|
76
78
|
|
|
77
79
|
def prev_out
|
|
@@ -81,12 +83,17 @@ class Sibit
|
|
|
81
83
|
def prev_out_index
|
|
82
84
|
@index
|
|
83
85
|
end
|
|
86
|
+
|
|
87
|
+
def segwit?
|
|
88
|
+
bytes = [@prev_script].pack('H*').bytes
|
|
89
|
+
bytes.length == 22 && bytes[0].zero? && bytes[1] == 20
|
|
90
|
+
end
|
|
84
91
|
end
|
|
85
92
|
|
|
86
93
|
# Transaction output.
|
|
87
94
|
#
|
|
88
95
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
89
|
-
# Copyright:: Copyright (c) 2019-
|
|
96
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
90
97
|
# License:: MIT
|
|
91
98
|
class Output
|
|
92
99
|
attr_reader :value
|
|
@@ -97,10 +104,14 @@ class Sibit
|
|
|
97
104
|
end
|
|
98
105
|
|
|
99
106
|
def script
|
|
100
|
-
return segwit_script if
|
|
107
|
+
return segwit_script if segwit?
|
|
101
108
|
p2pkh_script
|
|
102
109
|
end
|
|
103
110
|
|
|
111
|
+
def segwit?
|
|
112
|
+
@address.downcase.start_with?('bc1', 'tb1', 'bcrt1')
|
|
113
|
+
end
|
|
114
|
+
|
|
104
115
|
def script_hex
|
|
105
116
|
script.unpack1('H*')
|
|
106
117
|
end
|
|
@@ -123,21 +134,67 @@ class Sibit
|
|
|
123
134
|
|
|
124
135
|
private
|
|
125
136
|
|
|
137
|
+
def witness?
|
|
138
|
+
@inputs.any?(&:segwit?)
|
|
139
|
+
end
|
|
140
|
+
|
|
126
141
|
def sign_inputs
|
|
127
142
|
@inputs.each_with_index do |input, idx|
|
|
128
|
-
sighash =
|
|
143
|
+
sighash = input.segwit? ? segwit_sighash(idx) : legacy_sighash(idx)
|
|
129
144
|
sig = sign(input.key, sighash)
|
|
130
145
|
pubkey = [input.key.pub].pack('H*')
|
|
131
|
-
input.
|
|
146
|
+
if input.segwit?
|
|
147
|
+
witness_sig = sig + [SIGHASH_ALL].pack('C')
|
|
148
|
+
input.witness = [witness_sig.bytes, pubkey.bytes]
|
|
149
|
+
else
|
|
150
|
+
input.script_sig = der_sig(sig) + pubkey_script(pubkey)
|
|
151
|
+
end
|
|
132
152
|
end
|
|
133
153
|
end
|
|
134
154
|
|
|
135
|
-
def
|
|
155
|
+
def legacy_sighash(idx)
|
|
136
156
|
tx_copy = serialize_for_signing(idx)
|
|
137
157
|
hash_type = [SIGHASH_ALL].pack('V')
|
|
138
158
|
Digest::SHA256.digest(Digest::SHA256.digest(tx_copy + hash_type))
|
|
139
159
|
end
|
|
140
160
|
|
|
161
|
+
def segwit_sighash(idx)
|
|
162
|
+
input = @inputs[idx]
|
|
163
|
+
preimage = [VERSION].pack('V')
|
|
164
|
+
preimage += hash_prevouts
|
|
165
|
+
preimage += hash_sequence
|
|
166
|
+
preimage += [input.hash].pack('H*').reverse
|
|
167
|
+
preimage += [input.index].pack('V')
|
|
168
|
+
preimage += script_code(input)
|
|
169
|
+
preimage += [input.value].pack('Q<')
|
|
170
|
+
preimage += [SEQUENCE].pack('V')
|
|
171
|
+
preimage += hash_outputs
|
|
172
|
+
preimage += [0].pack('V')
|
|
173
|
+
preimage += [SIGHASH_ALL].pack('V')
|
|
174
|
+
Digest::SHA256.digest(Digest::SHA256.digest(preimage))
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def hash_prevouts
|
|
178
|
+
data = @inputs.map { |i| [i.hash].pack('H*').reverse + [i.index].pack('V') }.join
|
|
179
|
+
Digest::SHA256.digest(Digest::SHA256.digest(data))
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def hash_sequence
|
|
183
|
+
data = @inputs.map { [SEQUENCE].pack('V') }.join
|
|
184
|
+
Digest::SHA256.digest(Digest::SHA256.digest(data))
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def hash_outputs
|
|
188
|
+
data = @outputs.map { |o| [o.value].pack('Q<') + varint(o.script.length) + o.script }.join
|
|
189
|
+
Digest::SHA256.digest(Digest::SHA256.digest(data))
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def script_code(input)
|
|
193
|
+
hash160 = input.prev_script[4..]
|
|
194
|
+
code = [0x76, 0xa9, 0x14].pack('C*') + [hash160].pack('H*') + [0x88, 0xac].pack('C*')
|
|
195
|
+
varint(code.length) + code
|
|
196
|
+
end
|
|
197
|
+
|
|
141
198
|
def sign(key, hash)
|
|
142
199
|
der = key.sign(hash)
|
|
143
200
|
repack(der)
|
|
@@ -173,6 +230,7 @@ class Sibit
|
|
|
173
230
|
|
|
174
231
|
def serialize
|
|
175
232
|
result = [VERSION].pack('V')
|
|
233
|
+
result += [0x00, 0x01].pack('CC') if witness?
|
|
176
234
|
result += varint(@inputs.length)
|
|
177
235
|
@inputs.each do |input|
|
|
178
236
|
result += [input.hash].pack('H*').reverse
|
|
@@ -188,10 +246,27 @@ class Sibit
|
|
|
188
246
|
result += varint(script.length)
|
|
189
247
|
result += script
|
|
190
248
|
end
|
|
249
|
+
result += serialize_witness if witness?
|
|
191
250
|
result += [0].pack('V')
|
|
192
251
|
result
|
|
193
252
|
end
|
|
194
253
|
|
|
254
|
+
def serialize_witness
|
|
255
|
+
result = ''.b
|
|
256
|
+
@inputs.each do |input|
|
|
257
|
+
if input.segwit?
|
|
258
|
+
result += varint(input.witness.length)
|
|
259
|
+
input.witness.each do |item|
|
|
260
|
+
result += varint(item.length)
|
|
261
|
+
result += item.pack('C*')
|
|
262
|
+
end
|
|
263
|
+
else
|
|
264
|
+
result += varint(0)
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
result
|
|
268
|
+
end
|
|
269
|
+
|
|
195
270
|
def serialize_for_signing(idx)
|
|
196
271
|
result = [VERSION].pack('V')
|
|
197
272
|
result += varint(@inputs.length)
|
data/lib/sibit/txbuilder.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require_relative 'key'
|
|
@@ -14,7 +14,7 @@ class Sibit
|
|
|
14
14
|
# building and signing Bitcoin transactions.
|
|
15
15
|
#
|
|
16
16
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
17
|
-
# Copyright:: Copyright (c) 2019-
|
|
17
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
18
18
|
# License:: MIT
|
|
19
19
|
class TxBuilder
|
|
20
20
|
def initialize
|
|
@@ -39,7 +39,8 @@ class Sibit
|
|
|
39
39
|
hash: inp.prev_out_hash,
|
|
40
40
|
index: inp.prev_out_idx,
|
|
41
41
|
script: inp.script,
|
|
42
|
-
key: inp.key
|
|
42
|
+
key: inp.key,
|
|
43
|
+
value: inp.amount
|
|
43
44
|
)
|
|
44
45
|
end
|
|
45
46
|
total_out = @outputs.sum { |o| o[:value] }
|
|
@@ -54,10 +55,10 @@ class Sibit
|
|
|
54
55
|
# Input builder for collecting input parameters.
|
|
55
56
|
#
|
|
56
57
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
57
|
-
# Copyright:: Copyright (c) 2019-
|
|
58
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
58
59
|
# License:: MIT
|
|
59
60
|
class Input
|
|
60
|
-
attr_reader :prev_out_hash, :prev_out_idx, :script, :key
|
|
61
|
+
attr_reader :prev_out_hash, :prev_out_idx, :script, :key, :amount
|
|
61
62
|
|
|
62
63
|
def prev_out(hash)
|
|
63
64
|
@prev_out_hash = hash
|
|
@@ -71,6 +72,10 @@ class Sibit
|
|
|
71
72
|
@script = scr
|
|
72
73
|
end
|
|
73
74
|
|
|
75
|
+
def prev_out_value(val)
|
|
76
|
+
@amount = val
|
|
77
|
+
end
|
|
78
|
+
|
|
74
79
|
def signature_key(key)
|
|
75
80
|
@key = key
|
|
76
81
|
end
|
|
@@ -79,7 +84,7 @@ class Sibit
|
|
|
79
84
|
# Wrapper for built transaction with convenience methods.
|
|
80
85
|
#
|
|
81
86
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
82
|
-
# Copyright:: Copyright (c) 2019-
|
|
87
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
83
88
|
# License:: MIT
|
|
84
89
|
class Built
|
|
85
90
|
def initialize(txn, inputs, outputs)
|
|
@@ -115,7 +120,7 @@ class Sibit
|
|
|
115
120
|
# Wrapper for payload with hex conversion.
|
|
116
121
|
#
|
|
117
122
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
118
|
-
# Copyright:: Copyright (c) 2019-
|
|
123
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
119
124
|
# License:: MIT
|
|
120
125
|
class Payload
|
|
121
126
|
def initialize(bytes)
|
data/lib/sibit/version.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
# Sibit main class.
|
|
7
7
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
8
|
-
# Copyright:: Copyright (c) 2019-
|
|
8
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
9
9
|
# License:: MIT
|
|
10
10
|
class Sibit
|
|
11
11
|
# Current version of the library.
|
|
12
|
-
VERSION = '0.30.
|
|
12
|
+
VERSION = '0.30.7' unless defined?(VERSION)
|
|
13
13
|
end
|
data/lib/sibit.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'loog'
|
|
@@ -15,7 +15,7 @@ require_relative 'sibit/version'
|
|
|
15
15
|
# Sibit main class.
|
|
16
16
|
#
|
|
17
17
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
|
18
|
-
# Copyright:: Copyright (c) 2019-
|
|
18
|
+
# Copyright:: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
19
19
|
# License:: MIT
|
|
20
20
|
class Sibit
|
|
21
21
|
# Minimum fee we must pay for transaction processing:
|
|
@@ -58,7 +58,8 @@ class Sibit
|
|
|
58
58
|
|
|
59
59
|
# Creates Bitcoin address using the private key in Hash160 format.
|
|
60
60
|
def create(pvt)
|
|
61
|
-
|
|
61
|
+
raise Error, 'Invalid private key (must be 64 chars)' unless /^[0-9a-f]{64}$/.match?(pvt)
|
|
62
|
+
Key.new(pvt).bech32
|
|
62
63
|
end
|
|
63
64
|
|
|
64
65
|
# Gets the balance of the address, in satoshi.
|
|
@@ -101,11 +102,12 @@ class Sibit
|
|
|
101
102
|
# +sources+: the list of private bitcoin keys where the coins are now
|
|
102
103
|
# +target+: the target address to send to
|
|
103
104
|
# +change+: the address where the change has to be sent to
|
|
104
|
-
|
|
105
|
+
# +network+: optional network override (:mainnet, :testnet, :regtest)
|
|
106
|
+
def pay(amount, fee, sources, target, change, skip_utxo: [], network: nil)
|
|
105
107
|
p = price('USD')
|
|
106
|
-
keys = sources.map { |k| Key.new(k) }
|
|
108
|
+
keys = sources.map { |k| Key.new(k, network: network) }
|
|
107
109
|
network = keys.first&.network || :mainnet
|
|
108
|
-
sources = keys.to_h { |k| [k.
|
|
110
|
+
sources = keys.to_h { |k| [k.bech32, k.priv] }
|
|
109
111
|
satoshi = satoshi(amount)
|
|
110
112
|
builder = TxBuilder.new
|
|
111
113
|
unspent = 0
|
|
@@ -127,6 +129,7 @@ class Sibit
|
|
|
127
129
|
i.prev_out(utxo[:hash])
|
|
128
130
|
i.prev_out_index(utxo[:index])
|
|
129
131
|
i.prev_out_script = script_hex(utxo[:script])
|
|
132
|
+
i.prev_out_value(utxo[:value])
|
|
130
133
|
address = Script.new(script_hex(utxo[:script])).address(network)
|
|
131
134
|
k = sources[address]
|
|
132
135
|
raise Error, "UTXO arrived to #{address} is incorrect" unless k
|
data/sibit.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# SPDX-FileCopyrightText: Copyright (c) 2019-
|
|
3
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
6
|
require 'English'
|
|
@@ -32,6 +32,7 @@ Gem::Specification.new do |s|
|
|
|
32
32
|
s.add_dependency 'backtrace', '~> 0.3'
|
|
33
33
|
s.add_dependency 'decoor', '~> 0.1'
|
|
34
34
|
s.add_dependency 'elapsed', '~> 0.2'
|
|
35
|
+
s.add_dependency 'ellipsized', '~> 0.3'
|
|
35
36
|
s.add_dependency 'iri', '~> 0.5'
|
|
36
37
|
s.add_dependency 'json', '~> 2.18'
|
|
37
38
|
s.add_dependency 'loog', '~> 0.6'
|
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.30.
|
|
4
|
+
version: 0.30.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yegor Bugayenko
|
|
@@ -51,6 +51,20 @@ dependencies:
|
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '0.2'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: ellipsized
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0.3'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0.3'
|
|
54
68
|
- !ruby/object:Gem::Dependency
|
|
55
69
|
name: iri
|
|
56
70
|
requirement: !ruby/object:Gem::Requirement
|