sibit 0.33.0 → 0.34.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 +4 -4
- data/Gemfile +4 -5
- data/Gemfile.lock +78 -58
- data/README.md +21 -2
- data/Rakefile +1 -1
- data/bin/sibit +6 -4
- data/cross/alpine.df +6 -0
- data/cross/centos.df +8 -0
- data/cross/debian.df +9 -0
- data/cross/fedora.df +7 -0
- data/cross/opensuse.df +17 -0
- data/cross/rocky.df +8 -0
- data/cross/ubuntu.df +9 -0
- data/features/step_definitions/steps.rb +5 -5
- data/features/support/env.rb +1 -1
- data/lib/sibit/base58.rb +3 -6
- data/lib/sibit/bech32.rb +23 -15
- data/lib/sibit/bestof.rb +41 -11
- data/lib/sibit/bin.rb +68 -54
- data/lib/sibit/bitcoinchain.rb +10 -10
- data/lib/sibit/blockchain.rb +10 -20
- data/lib/sibit/blockchair.rb +14 -24
- data/lib/sibit/btc.rb +51 -60
- data/lib/sibit/cex.rb +12 -11
- data/lib/sibit/coins.rb +35 -0
- data/lib/sibit/cryptoapis.rb +35 -30
- data/lib/sibit/firstof.rb +8 -5
- data/lib/sibit/httpproxy.rb +1 -1
- data/lib/sibit/json.rb +8 -9
- data/lib/sibit/key.rb +39 -41
- data/lib/sibit/script.rb +3 -6
- data/lib/sibit/sochain.rb +180 -0
- data/lib/sibit/tx.rb +75 -36
- data/lib/sibit/txbuilder.rb +15 -3
- data/lib/sibit/version.rb +1 -2
- data/lib/sibit.rb +80 -62
- data/sibit.gemspec +11 -11
- metadata +10 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 469905d53f542975d0fe59c8b429289423762f4b36aca8b703928d54f5ba394f
|
|
4
|
+
data.tar.gz: c68a4237d70f25a11ea2e98c36d76c7b0917a6355353e6d23c22336eedd94f31
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f5aa717192c0417c572226c3a0f79924f61e5d70b0bc84efe53d0cc760c16515f3cd6ef63b00de57e4228dbcd82fdb60a269f35df858b0c1ff8bec81006db6bc
|
|
7
|
+
data.tar.gz: fe9f402e207051f02e31b54d0a4e41cca76efd2a0260fbc6dfb3fb69f1aa543af2a9af6045590bd653c6c26472c97fdb6d5ba3a8b5a98f4ca282e351d88f53ee
|
data/Gemfile
CHANGED
|
@@ -6,10 +6,8 @@
|
|
|
6
6
|
source 'https://rubygems.org'
|
|
7
7
|
gemspec
|
|
8
8
|
|
|
9
|
-
# gem 'debase', '0.2.4.1', require: false
|
|
10
|
-
|
|
11
9
|
gem 'aruba', '~>2.2', require: false
|
|
12
|
-
gem 'cucumber', '~>
|
|
10
|
+
gem 'cucumber', '~>11.0', require: false
|
|
13
11
|
gem 'donce', '~>0.2', require: false
|
|
14
12
|
gem 'logger', '~>1.7', require: false
|
|
15
13
|
gem 'minitest', '~>6.0', require: false
|
|
@@ -18,8 +16,9 @@ gem 'nokogiri', '~>1.18', require: false
|
|
|
18
16
|
gem 'os', '~>1.1', require: false
|
|
19
17
|
gem 'qbash', '~>0.0', require: false
|
|
20
18
|
gem 'rake', '~>13.2', require: false
|
|
21
|
-
gem 'rdoc', '~>
|
|
22
|
-
gem 'rubocop', '~>1.
|
|
19
|
+
gem 'rdoc', '~>8.0', require: false
|
|
20
|
+
gem 'rubocop', '~>1.72', require: false
|
|
21
|
+
gem 'rubocop-elegant', '~>0.5', require: false
|
|
23
22
|
gem 'rubocop-minitest', '~>0.38', require: false
|
|
24
23
|
gem 'rubocop-performance', '~>1.25', require: false
|
|
25
24
|
gem 'rubocop-rake', '~>0.7', require: false
|
data/Gemfile.lock
CHANGED
|
@@ -16,133 +16,152 @@ PATH
|
|
|
16
16
|
GEM
|
|
17
17
|
remote: https://rubygems.org/
|
|
18
18
|
specs:
|
|
19
|
-
addressable (2.
|
|
19
|
+
addressable (2.9.0)
|
|
20
20
|
public_suffix (>= 2.0.2, < 8.0)
|
|
21
|
-
ansi (1.
|
|
22
|
-
aruba (2.
|
|
21
|
+
ansi (1.6.0)
|
|
22
|
+
aruba (2.4.1)
|
|
23
23
|
bundler (>= 1.17)
|
|
24
24
|
contracts (>= 0.16.0, < 0.18.0)
|
|
25
|
-
cucumber (>= 8.0, <
|
|
25
|
+
cucumber (>= 8.0, < 12.0)
|
|
26
|
+
irb (~> 1.16)
|
|
26
27
|
rspec-expectations (>= 3.4, < 5.0)
|
|
27
28
|
thor (~> 1.0)
|
|
28
29
|
ast (2.4.3)
|
|
29
30
|
backtrace (0.4.1)
|
|
30
31
|
base64 (0.3.0)
|
|
31
|
-
bigdecimal (4.
|
|
32
|
+
bigdecimal (4.1.2)
|
|
32
33
|
builder (3.3.0)
|
|
33
34
|
contracts (0.17.3)
|
|
34
35
|
crack (1.0.1)
|
|
35
36
|
bigdecimal
|
|
36
37
|
rexml
|
|
37
|
-
cucumber (
|
|
38
|
+
cucumber (11.1.1)
|
|
38
39
|
base64 (~> 0.2)
|
|
39
40
|
builder (~> 3.2)
|
|
40
41
|
cucumber-ci-environment (> 9, < 12)
|
|
41
|
-
cucumber-core (
|
|
42
|
+
cucumber-core (>= 16.2.0, < 17)
|
|
42
43
|
cucumber-cucumber-expressions (> 17, < 20)
|
|
43
|
-
cucumber-html-formatter (> 21, <
|
|
44
|
+
cucumber-html-formatter (> 21, < 24)
|
|
44
45
|
diff-lcs (~> 1.5)
|
|
45
46
|
logger (~> 1.6)
|
|
46
47
|
mini_mime (~> 1.1)
|
|
47
48
|
multi_test (~> 1.1)
|
|
48
|
-
sys-uname (~> 1.
|
|
49
|
+
sys-uname (~> 1.5)
|
|
49
50
|
cucumber-ci-environment (11.0.0)
|
|
50
|
-
cucumber-core (16.
|
|
51
|
+
cucumber-core (16.2.0)
|
|
51
52
|
cucumber-gherkin (> 36, < 40)
|
|
52
53
|
cucumber-messages (> 31, < 33)
|
|
53
54
|
cucumber-tag-expressions (> 6, < 9)
|
|
54
|
-
cucumber-cucumber-expressions (
|
|
55
|
+
cucumber-cucumber-expressions (19.0.1)
|
|
55
56
|
bigdecimal
|
|
56
|
-
cucumber-gherkin (
|
|
57
|
-
cucumber-messages (>= 31, <
|
|
58
|
-
cucumber-html-formatter (
|
|
57
|
+
cucumber-gherkin (39.1.0)
|
|
58
|
+
cucumber-messages (>= 31, < 33)
|
|
59
|
+
cucumber-html-formatter (23.1.0)
|
|
59
60
|
cucumber-messages (> 23, < 33)
|
|
60
|
-
cucumber-messages (
|
|
61
|
+
cucumber-messages (32.3.1)
|
|
61
62
|
cucumber-tag-expressions (8.1.0)
|
|
62
|
-
date (3.5.1)
|
|
63
63
|
decoor (0.1.0)
|
|
64
64
|
diff-lcs (1.6.2)
|
|
65
65
|
docile (1.4.1)
|
|
66
|
-
donce (0.
|
|
66
|
+
donce (0.7.0)
|
|
67
67
|
backtrace (~> 0.3)
|
|
68
68
|
os (~> 1.1)
|
|
69
69
|
qbash (~> 0.3)
|
|
70
|
-
|
|
70
|
+
drb (2.2.3)
|
|
71
|
+
elapsed (0.3.1)
|
|
71
72
|
loog (~> 0.6)
|
|
72
73
|
tago (~> 0.1)
|
|
73
74
|
ellipsized (0.3.0)
|
|
74
|
-
erb (6.0.
|
|
75
|
-
ffi (1.17.
|
|
76
|
-
ffi (1.17.
|
|
75
|
+
erb (6.0.6)
|
|
76
|
+
ffi (1.17.4-arm64-darwin)
|
|
77
|
+
ffi (1.17.4-x86_64-linux-gnu)
|
|
77
78
|
hashdiff (1.2.1)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
io-console (0.8.2)
|
|
80
|
+
irb (1.18.0)
|
|
81
|
+
pp (>= 0.6.0)
|
|
82
|
+
prism (>= 1.3.0)
|
|
83
|
+
rdoc (>= 4.0.0)
|
|
84
|
+
reline (>= 0.4.2)
|
|
85
|
+
iri (0.11.8)
|
|
86
|
+
json (2.21.1)
|
|
87
|
+
language_server-protocol (3.17.0.6)
|
|
81
88
|
lint_roller (1.1.0)
|
|
82
89
|
logger (1.7.0)
|
|
83
|
-
loog (0.
|
|
90
|
+
loog (0.8.0)
|
|
91
|
+
ellipsized
|
|
84
92
|
logger (~> 1.0)
|
|
85
93
|
memoist3 (1.0.0)
|
|
86
94
|
mini_mime (1.1.5)
|
|
87
|
-
minitest (6.0.
|
|
95
|
+
minitest (6.0.6)
|
|
96
|
+
drb (~> 2.0)
|
|
88
97
|
prism (~> 1.5)
|
|
89
|
-
minitest-reporters (1.
|
|
98
|
+
minitest-reporters (1.8.0)
|
|
90
99
|
ansi
|
|
91
100
|
builder
|
|
92
|
-
minitest (>= 5.0)
|
|
101
|
+
minitest (>= 5.0, < 7)
|
|
93
102
|
ruby-progressbar
|
|
94
103
|
multi_test (1.1.0)
|
|
95
|
-
nokogiri (1.19.
|
|
104
|
+
nokogiri (1.19.4-arm64-darwin)
|
|
96
105
|
racc (~> 1.4)
|
|
97
|
-
nokogiri (1.19.
|
|
106
|
+
nokogiri (1.19.4-x86_64-linux-gnu)
|
|
98
107
|
racc (~> 1.4)
|
|
99
|
-
openssl (3.3.
|
|
108
|
+
openssl (3.3.3)
|
|
100
109
|
os (1.1.4)
|
|
101
|
-
parallel (1.
|
|
102
|
-
parser (3.3.
|
|
110
|
+
parallel (2.1.0)
|
|
111
|
+
parser (3.3.12.0)
|
|
103
112
|
ast (~> 2.4.1)
|
|
104
113
|
racc
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
public_suffix (7.0.
|
|
110
|
-
qbash (0.
|
|
114
|
+
pp (0.6.4)
|
|
115
|
+
prettyprint
|
|
116
|
+
prettyprint (0.2.0)
|
|
117
|
+
prism (1.9.0)
|
|
118
|
+
public_suffix (7.0.5)
|
|
119
|
+
qbash (0.8.4)
|
|
111
120
|
backtrace (> 0)
|
|
112
121
|
elapsed (> 0)
|
|
113
122
|
loog (> 0)
|
|
114
123
|
tago (> 0)
|
|
115
124
|
racc (1.8.1)
|
|
116
125
|
rainbow (3.1.1)
|
|
117
|
-
rake (13.
|
|
118
|
-
|
|
126
|
+
rake (13.4.2)
|
|
127
|
+
rbs (4.0.3)
|
|
128
|
+
logger
|
|
129
|
+
prism (>= 1.6.0)
|
|
130
|
+
tsort
|
|
131
|
+
rdoc (8.0.0)
|
|
119
132
|
erb
|
|
120
|
-
|
|
133
|
+
prism (>= 1.6.0)
|
|
134
|
+
rbs (>= 4.0.0)
|
|
121
135
|
tsort
|
|
122
|
-
regexp_parser (2.
|
|
123
|
-
|
|
136
|
+
regexp_parser (2.12.0)
|
|
137
|
+
reline (0.6.3)
|
|
138
|
+
io-console (~> 0.5)
|
|
139
|
+
retriable (3.8.0)
|
|
124
140
|
retriable_proxy (1.0.2)
|
|
125
141
|
retriable (>= 2.0, < 4.0)
|
|
126
142
|
rexml (3.4.4)
|
|
127
143
|
rspec-expectations (3.13.5)
|
|
128
144
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
129
145
|
rspec-support (~> 3.13.0)
|
|
130
|
-
rspec-support (3.13.
|
|
131
|
-
rubocop (1.
|
|
146
|
+
rspec-support (3.13.7)
|
|
147
|
+
rubocop (1.88.2)
|
|
132
148
|
json (~> 2.3)
|
|
133
149
|
language_server-protocol (~> 3.17.0.2)
|
|
134
150
|
lint_roller (~> 1.1.0)
|
|
135
|
-
parallel (
|
|
151
|
+
parallel (>= 1.10)
|
|
136
152
|
parser (>= 3.3.0.2)
|
|
137
153
|
rainbow (>= 2.2.2, < 4.0)
|
|
138
154
|
regexp_parser (>= 2.9.3, < 3.0)
|
|
139
|
-
rubocop-ast (>= 1.
|
|
155
|
+
rubocop-ast (>= 1.49.0, < 2.0)
|
|
140
156
|
ruby-progressbar (~> 1.7)
|
|
141
157
|
unicode-display_width (>= 2.4.0, < 4.0)
|
|
142
|
-
rubocop-ast (1.
|
|
158
|
+
rubocop-ast (1.50.0)
|
|
143
159
|
parser (>= 3.3.7.2)
|
|
144
160
|
prism (~> 1.7)
|
|
145
|
-
rubocop-
|
|
161
|
+
rubocop-elegant (0.7.1)
|
|
162
|
+
lint_roller (~> 1.1)
|
|
163
|
+
rubocop (~> 1.75)
|
|
164
|
+
rubocop-minitest (0.40.0)
|
|
146
165
|
lint_roller (~> 1.1)
|
|
147
166
|
rubocop (>= 1.75.0, < 2.0)
|
|
148
167
|
rubocop-ast (>= 1.38.0, < 2.0)
|
|
@@ -158,22 +177,21 @@ GEM
|
|
|
158
177
|
docile (~> 1.1)
|
|
159
178
|
simplecov-html (~> 0.11)
|
|
160
179
|
simplecov_json_formatter (~> 0.1)
|
|
161
|
-
simplecov-cobertura (3.
|
|
180
|
+
simplecov-cobertura (3.2.0)
|
|
162
181
|
rexml
|
|
163
182
|
simplecov (~> 0.19)
|
|
164
183
|
simplecov-html (0.13.2)
|
|
165
184
|
simplecov_json_formatter (0.1.4)
|
|
166
|
-
|
|
167
|
-
sys-uname (1.4.1)
|
|
185
|
+
sys-uname (1.5.1)
|
|
168
186
|
ffi (~> 1.1)
|
|
169
187
|
memoist3 (~> 1.0.0)
|
|
170
|
-
tago (0.
|
|
188
|
+
tago (0.7.0)
|
|
171
189
|
thor (1.5.0)
|
|
172
190
|
tsort (0.2.0)
|
|
173
191
|
unicode-display_width (3.2.0)
|
|
174
192
|
unicode-emoji (~> 4.1)
|
|
175
193
|
unicode-emoji (4.2.0)
|
|
176
|
-
webmock (3.26.
|
|
194
|
+
webmock (3.26.2)
|
|
177
195
|
addressable (>= 2.8.0)
|
|
178
196
|
crack (>= 0.3.2)
|
|
179
197
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
@@ -182,11 +200,12 @@ PLATFORMS
|
|
|
182
200
|
arm64-darwin-22
|
|
183
201
|
arm64-darwin-23
|
|
184
202
|
arm64-darwin-24
|
|
203
|
+
arm64-darwin-25
|
|
185
204
|
x86_64-linux
|
|
186
205
|
|
|
187
206
|
DEPENDENCIES
|
|
188
207
|
aruba (~> 2.2)
|
|
189
|
-
cucumber (~>
|
|
208
|
+
cucumber (~> 11.0)
|
|
190
209
|
donce (~> 0.2)
|
|
191
210
|
logger (~> 1.7)
|
|
192
211
|
minitest (~> 6.0)
|
|
@@ -195,8 +214,9 @@ DEPENDENCIES
|
|
|
195
214
|
os (~> 1.1)
|
|
196
215
|
qbash (~> 0.0)
|
|
197
216
|
rake (~> 13.2)
|
|
198
|
-
rdoc (~>
|
|
199
|
-
rubocop (~> 1.
|
|
217
|
+
rdoc (~> 8.0)
|
|
218
|
+
rubocop (~> 1.72)
|
|
219
|
+
rubocop-elegant (~> 0.5)
|
|
200
220
|
rubocop-minitest (~> 0.38)
|
|
201
221
|
rubocop-performance (~> 1.25)
|
|
202
222
|
rubocop-rake (~> 0.7)
|
data/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://github.com/yegor256/sibit/actions/workflows/rake.yml)
|
|
8
8
|
[](https://www.0pdd.com/p?name=yegor256/sibit)
|
|
9
9
|
[](https://badge.fury.io/rb/sibit)
|
|
10
|
-
[](https://github.com/yegor256/
|
|
10
|
+
[](https://github.com/yegor256/sibit/blob/master/LICENSE.txt)
|
|
11
11
|
[](https://codecov.io/github/yegor256/sibit?branch=master)
|
|
12
12
|
[](https://hitsofcode.com/view/github/yegor256/sibit)
|
|
13
13
|
|
|
@@ -80,7 +80,7 @@ Not all [UTXOs] may be used, but only the necessary amount of them.
|
|
|
80
80
|
|
|
81
81
|
By default, the fee is paid on top of the payment amount you are sending.
|
|
82
82
|
Say, you are sending 0.5 BTC and the fee is 0.0001 BTC.
|
|
83
|
-
|
|
83
|
+
In total, you spend 0.5001 BTC.
|
|
84
84
|
However, you can make Sibit deduct the fee from the payment amount.
|
|
85
85
|
In this case you should provide a negative amount
|
|
86
86
|
of the fee or one of `S-`, `M-`, `L-`, `XL-`.
|
|
@@ -91,6 +91,18 @@ It is recommended to run it with `--dry --verbose` options first,
|
|
|
91
91
|
If everything looks correct, remove the `--dry` and run again,
|
|
92
92
|
the transaction is pushed to the network.
|
|
93
93
|
|
|
94
|
+
To require a minimum number of confirmations on every UTXO before it is
|
|
95
|
+
spent, or before it counts toward the reported balance, pass `--trust`:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
sibit --trust=6 balance 1PfsYNygsuVL8fvBarJNQnHytkg4rGih1U
|
|
99
|
+
sibit --trust=6 pay 10000 S P1,P2 TARGET CHANGE
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The default is `0`, which preserves the existing behavior.
|
|
103
|
+
The same option is available from the Ruby SDK via the `trust:` keyword
|
|
104
|
+
argument on `Sibit#balance` and `Sibit#pay`.
|
|
105
|
+
|
|
94
106
|
To use an HTTPS proxy for all requests:
|
|
95
107
|
|
|
96
108
|
```bash
|
|
@@ -103,6 +115,11 @@ The proxy address may include authentication credentials:
|
|
|
103
115
|
sibit --proxy=user:password@host:port balance 1PfsYNygsuVL8fvBarJNQnHytkg4rGih1U
|
|
104
116
|
```
|
|
105
117
|
|
|
118
|
+
Some providers accept an API key, read from an environment variable:
|
|
119
|
+
`SIBIT_BLOCKCHAIR_KEY` for [Blockchair.com] and
|
|
120
|
+
`SIBIT_CRYPTOAPIS_KEY` for [Cryptoapis.io].
|
|
121
|
+
When the variable is set, requests to that provider use the authenticated tier.
|
|
122
|
+
|
|
106
123
|
All operations are performed through the [Blockchain API].
|
|
107
124
|
Transactions are pushed to the Bitcoin network via [this relay].
|
|
108
125
|
|
|
@@ -135,6 +152,7 @@ At the moment we work with the following APIs:
|
|
|
135
152
|
* [Bitcoinchain.com] - `Sibit::Bitcoinchain`
|
|
136
153
|
* [Blockchair.com] - `Sibit::Blockchair`
|
|
137
154
|
* [Cex.io] - `Sibit::Cex`
|
|
155
|
+
* [SoChain] - `Sibit::Sochain`
|
|
138
156
|
|
|
139
157
|
The first one in this list is used by default.
|
|
140
158
|
If you want to use a different one,
|
|
@@ -211,6 +229,7 @@ If it's clean and you don't see any error messages, submit your pull request.
|
|
|
211
229
|
[Cex.io]: https://cex.io/rest-api
|
|
212
230
|
[Cryptoapis.io]: https://docs.cryptoapis.io/rest-apis/blockchain-as-a-service-apis/btc/index
|
|
213
231
|
[Electrum]: https://electrum.org/
|
|
232
|
+
[SoChain]: https://sochain.com/api
|
|
214
233
|
[miner fee]: https://en.bitcoin.it/wiki/Miner_fees
|
|
215
234
|
[private key]: https://en.bitcoin.it/wiki/Private_key
|
|
216
235
|
[Ruby]: https://www.ruby-lang.org/en/
|
data/Rakefile
CHANGED
|
@@ -35,7 +35,7 @@ task :picks do
|
|
|
35
35
|
next if OS.windows?
|
|
36
36
|
%w[lib].each do |d|
|
|
37
37
|
Dir["#{d}/**/*.rb"].each do |f|
|
|
38
|
-
qbash("bundle exec ruby #{Shellwords.escape(f)}",
|
|
38
|
+
qbash("bundle exec ruby #{Shellwords.escape(f)}", stdout: $stdout, env: { 'PICKS' => 'yes' })
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
end
|
data/bin/sibit
CHANGED
|
@@ -10,23 +10,25 @@ require 'backtrace'
|
|
|
10
10
|
require 'loog'
|
|
11
11
|
require_relative '../lib/sibit'
|
|
12
12
|
require_relative '../lib/sibit/bin'
|
|
13
|
-
require_relative '../lib/sibit/http'
|
|
14
|
-
require_relative '../lib/sibit/httpproxy'
|
|
15
13
|
require_relative '../lib/sibit/bitcoinchain'
|
|
16
14
|
require_relative '../lib/sibit/blockchain'
|
|
17
15
|
require_relative '../lib/sibit/blockchair'
|
|
18
16
|
require_relative '../lib/sibit/btc'
|
|
19
17
|
require_relative '../lib/sibit/cex'
|
|
18
|
+
require_relative '../lib/sibit/cryptoapis'
|
|
20
19
|
require_relative '../lib/sibit/dry'
|
|
21
20
|
require_relative '../lib/sibit/fake'
|
|
22
21
|
require_relative '../lib/sibit/firstof'
|
|
22
|
+
require_relative '../lib/sibit/http'
|
|
23
|
+
require_relative '../lib/sibit/httpproxy'
|
|
24
|
+
require_relative '../lib/sibit/sochain'
|
|
23
25
|
require_relative '../lib/sibit/version'
|
|
24
26
|
|
|
25
27
|
begin
|
|
26
28
|
Sibit::Bin.start(ARGV)
|
|
27
29
|
rescue StandardError => e
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
wants = ARGV.include?('--verbose') || ENV.fetch('SIBIT_VERBOSE', nil)
|
|
31
|
+
verbose = !ARGV.include?('--quiet') && wants
|
|
30
32
|
log = verbose ? Loog::VERBOSE : Loog::REGULAR
|
|
31
33
|
if verbose
|
|
32
34
|
log.error(Backtrace.new(e))
|
data/cross/alpine.df
ADDED
data/cross/centos.df
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
FROM quay.io/centos/centos:stream9
|
|
5
|
+
|
|
6
|
+
RUN dnf module enable -y ruby:3.3 && \
|
|
7
|
+
dnf install -y ruby ruby-devel gcc make openssl-devel redhat-rpm-config && \
|
|
8
|
+
dnf clean all
|
data/cross/debian.df
ADDED
data/cross/fedora.df
ADDED
data/cross/opensuse.df
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
FROM opensuse/tumbleweed
|
|
5
|
+
|
|
6
|
+
RUN ok=; \
|
|
7
|
+
for i in 1 2 3 4 5; do \
|
|
8
|
+
if zypper --non-interactive --gpg-auto-import-keys refresh && \
|
|
9
|
+
zypper --non-interactive install ruby ruby-devel gcc make libopenssl-devel bash; then \
|
|
10
|
+
ok=1; break; \
|
|
11
|
+
fi; \
|
|
12
|
+
echo "zypper attempt $i failed, retrying in 15s"; sleep 15; \
|
|
13
|
+
done; \
|
|
14
|
+
test -n "$ok" && \
|
|
15
|
+
zypper clean --all && \
|
|
16
|
+
gem update --system --no-document && \
|
|
17
|
+
sed -i '/format.executable/d' /etc/gemrc
|
data/cross/rocky.df
ADDED
data/cross/ubuntu.df
ADDED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
# SPDX-FileCopyrightText: Copyright (c) 2019-2026 Yegor Bugayenko
|
|
4
4
|
# SPDX-License-Identifier: MIT
|
|
5
5
|
|
|
6
|
+
require 'English'
|
|
6
7
|
require 'nokogiri'
|
|
7
8
|
require 'tmpdir'
|
|
8
|
-
require 'English'
|
|
9
9
|
require_relative '../../lib/sibit'
|
|
10
10
|
|
|
11
11
|
Before do
|
|
@@ -32,19 +32,19 @@ When(%r{^I run bin/sibit with "([^"]*)"$}) do |arg|
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
Then(/^Stdout contains "([^"]*)"$/) do |txt|
|
|
35
|
-
raise "STDOUT doesn't contain '#{txt}':\n#{@stdout}" unless @stdout.include?(txt)
|
|
35
|
+
raise(StandardError, "STDOUT doesn't contain '#{txt}':\n#{@stdout}") unless @stdout.include?(txt)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
Then(/^Stdout is empty$/) do
|
|
39
|
-
raise "STDOUT is not empty:\n#{@stdout}" unless @stdout == ''
|
|
39
|
+
raise(StandardError, "STDOUT is not empty:\n#{@stdout}") unless @stdout == ''
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
Then(/^Exit code is zero$/) do
|
|
43
|
-
raise "Non-zero exit #{@exitstatus}:\n#{@stdout}" unless @exitstatus.zero?
|
|
43
|
+
raise(StandardError, "Non-zero exit #{@exitstatus}:\n#{@stdout}") unless @exitstatus.zero?
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
Then(/^Exit code is not zero$/) do
|
|
47
|
-
raise 'Zero exit code' if @exitstatus.zero?
|
|
47
|
+
raise(StandardError, 'Zero exit code') if @exitstatus.zero?
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
When(/^I run bash with "([^"]*)"$/) do |text|
|
data/features/support/env.rb
CHANGED
data/lib/sibit/base58.rb
CHANGED
|
@@ -23,28 +23,25 @@ class Sibit
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def encode
|
|
26
|
-
bytes = [@data].pack('H*')
|
|
27
|
-
leading = bytes.match(/^\x00*/)[0].length
|
|
28
26
|
num = @data.to_i(16)
|
|
29
27
|
result = ''
|
|
30
28
|
while num.positive?
|
|
31
29
|
num, remainder = num.divmod(58)
|
|
32
30
|
result = ALPHABET[remainder] + result
|
|
33
31
|
end
|
|
34
|
-
('1' *
|
|
32
|
+
('1' * [@data].pack('H*').match(/^\x00*/)[0].length) + result
|
|
35
33
|
end
|
|
36
34
|
|
|
37
35
|
def decode
|
|
38
|
-
leading = @data.match(/^1*/)[0].length
|
|
39
36
|
num = 0
|
|
40
37
|
@data.each_char do |c|
|
|
41
38
|
idx = ALPHABET.index(c)
|
|
42
|
-
raise
|
|
39
|
+
raise(Sibit::Error, "Invalid Base58 character '#{c}' in address '#{@data}'") if idx.nil?
|
|
43
40
|
num = (num * 58) + idx
|
|
44
41
|
end
|
|
45
42
|
hex = num.zero? ? '' : num.to_s(16)
|
|
46
43
|
hex = "0#{hex}" if hex.length.odd?
|
|
47
|
-
('00' *
|
|
44
|
+
('00' * @data.match(/^1*/)[0].length) + hex
|
|
48
45
|
end
|
|
49
46
|
|
|
50
47
|
def check
|
data/lib/sibit/bech32.rb
CHANGED
|
@@ -19,15 +19,13 @@ class Sibit
|
|
|
19
19
|
GENERATOR = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3].freeze
|
|
20
20
|
|
|
21
21
|
def self.encode(hrp, ver, prog)
|
|
22
|
-
|
|
23
|
-
data = [ver] + bits(bytes, 8, 5, true)
|
|
22
|
+
data = [ver] + bits([prog].pack('H*').bytes, 8, 5, true)
|
|
24
23
|
chk = checksum(hrp, data)
|
|
25
24
|
"#{hrp}1#{(data + chk).map { |d| CHARSET[d] }.join}"
|
|
26
25
|
end
|
|
27
26
|
|
|
28
27
|
def self.checksum(hrp, data)
|
|
29
|
-
|
|
30
|
-
poly = pm(values) ^ 1
|
|
28
|
+
poly = pm(expanded(hrp) + data + [0, 0, 0, 0, 0, 0]) ^ 1
|
|
31
29
|
(0..5).map { |i| (poly >> (5 * (5 - i))) & 31 }
|
|
32
30
|
end
|
|
33
31
|
|
|
@@ -68,8 +66,18 @@ class Sibit
|
|
|
68
66
|
|
|
69
67
|
def witness
|
|
70
68
|
hrp, data = parse
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
ver = data[0]
|
|
70
|
+
unless ver.between?(0, 16)
|
|
71
|
+
raise(Sibit::Error, "Unsupported witness version #{ver} in '#{@addr}'")
|
|
72
|
+
end
|
|
73
|
+
raise(Sibit::Error, "Invalid Bech32 checksum in '#{@addr}'") unless verified?(hrp, data)
|
|
74
|
+
prog = convert(data[1..-7], 5, 8)
|
|
75
|
+
if ver.zero? && [20, 32].none?(prog.length)
|
|
76
|
+
raise(Sibit::Error, "Witness v0 program in '#{@addr}' must be 20 or 32 bytes")
|
|
77
|
+
end
|
|
78
|
+
unless prog.length.between?(2, 40)
|
|
79
|
+
raise(Sibit::Error, "Witness program in '#{@addr}' must be 2 to 40 bytes")
|
|
80
|
+
end
|
|
73
81
|
prog.pack('C*').unpack1('H*')
|
|
74
82
|
end
|
|
75
83
|
|
|
@@ -82,18 +90,16 @@ class Sibit
|
|
|
82
90
|
|
|
83
91
|
def parse
|
|
84
92
|
pos = @addr.rindex('1')
|
|
85
|
-
raise
|
|
86
|
-
hrp = @addr[0...pos]
|
|
93
|
+
raise(Sibit::Error, "Invalid Bech32 address '#{@addr}': no separator") if pos.nil? || pos < 1
|
|
87
94
|
rest = @addr[(pos + 1)..]
|
|
88
|
-
raise
|
|
95
|
+
raise(Sibit::Error, "Invalid Bech32 address '#{@addr}': data too short") if rest.length < 6
|
|
89
96
|
data = rest.chars.map { |c| CHARSET.index(c) }
|
|
90
|
-
raise
|
|
91
|
-
[
|
|
97
|
+
raise(Sibit::Error, "Invalid Bech32 character in '#{@addr}'") if data.include?(nil)
|
|
98
|
+
[@addr[0...pos], data]
|
|
92
99
|
end
|
|
93
100
|
|
|
94
101
|
def verified?(hrp, data)
|
|
95
|
-
|
|
96
|
-
[1, 0x2bc830a3].include?(chk)
|
|
102
|
+
polymod(expand(hrp) + data) == (data[0].zero? ? 1 : 0x2bc830a3)
|
|
97
103
|
end
|
|
98
104
|
|
|
99
105
|
def expand(hrp)
|
|
@@ -110,7 +116,7 @@ class Sibit
|
|
|
110
116
|
chk
|
|
111
117
|
end
|
|
112
118
|
|
|
113
|
-
def convert(data, frombits, tobits
|
|
119
|
+
def convert(data, frombits, tobits)
|
|
114
120
|
acc = 0
|
|
115
121
|
bits = 0
|
|
116
122
|
result = []
|
|
@@ -123,7 +129,9 @@ class Sibit
|
|
|
123
129
|
result << ((acc >> bits) & maxv)
|
|
124
130
|
end
|
|
125
131
|
end
|
|
126
|
-
|
|
132
|
+
if bits >= frombits || (acc << (tobits - bits)).anybits?(maxv)
|
|
133
|
+
raise(Sibit::Error, "Non-zero padding in Bech32 address '#{@addr}'")
|
|
134
|
+
end
|
|
127
135
|
result
|
|
128
136
|
end
|
|
129
137
|
end
|