money-tree 0.11.0 → 0.11.2
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/.github/workflows/code.yml +44 -0
- data/.github/workflows/docs.yml +26 -0
- data/.github/workflows/spec.yml +4 -2
- data/Gemfile +13 -2
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/checksum/money-tree-0.11.0.gem.sha512 +1 -0
- data/checksum/money-tree-0.11.1.gem.sha512 +1 -0
- data/checksum/money-tree-0.9.0.gem.sha512 +1 -1
- data/config/openssl.conf +14 -0
- data/lib/money-tree/address.rb +14 -4
- data/lib/money-tree/key.rb +45 -31
- data/lib/money-tree/networks.rb +16 -15
- data/lib/money-tree/node.rb +65 -45
- data/lib/money-tree/support.rb +42 -17
- data/lib/money-tree/version.rb +1 -1
- data/lib/money-tree.rb +6 -6
- data/lib/openssl_extensions.rb +6 -4
- data/money-tree.gemspec +24 -18
- data/spec/{lib/money-tree → money-tree}/address_spec.rb +23 -5
- data/spec/money-tree/money_tree_spec.rb +9 -0
- data/spec/{lib/money-tree → money-tree}/node_spec.rb +552 -15
- data/spec/{lib/money-tree → money-tree}/openssl_extensions_spec.rb +4 -4
- data/spec/{lib/money-tree → money-tree}/private_key_spec.rb +10 -10
- data/spec/{lib/money-tree → money-tree}/public_key_spec.rb +51 -22
- data/spec/{lib/money-tree → money-tree}/support_spec.rb +1 -1
- data/spec/spec_helper.rb +15 -2
- metadata +39 -68
- data/certs/mattatgemco.pem +0 -24
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
# Test vectors from https://en.bitcoin.it/wiki/BIP_0032_TestVectors
|
4
4
|
describe MoneyTree::Master do
|
@@ -28,11 +28,11 @@ describe MoneyTree::Master do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it "generates testnet compressed wif" do
|
31
|
-
expect(@master.private_key.to_wif(network: :bitcoin_testnet)[0]).to eql(
|
31
|
+
expect(@master.private_key.to_wif(network: :bitcoin_testnet)[0]).to eql("c")
|
32
32
|
end
|
33
33
|
|
34
34
|
it "generates testnet uncompressed wif" do
|
35
|
-
expect(@master.private_key.to_wif(compressed: false, network: :bitcoin_testnet)[0]).to eql(
|
35
|
+
expect(@master.private_key.to_wif(compressed: false, network: :bitcoin_testnet)[0]).to eql("9")
|
36
36
|
end
|
37
37
|
|
38
38
|
it "generates testnet serialized private address" do
|
@@ -44,29 +44,29 @@ describe MoneyTree::Master do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
it "imports from testnet serialized private address" do
|
47
|
-
node = MoneyTree::Node.from_bip32
|
48
|
-
expect(node.to_bip32(:private, network: :bitcoin_testnet)).to eql(
|
47
|
+
node = MoneyTree::Node.from_bip32 "tprv8ZgxMBicQKsPcuN7bfUZqq78UEYapr3Tzmc9NcDXw8BnBJ47dZYr6SusnfYj7vbAYP9CP8ZiD5aVBTUo1yU5QP56mepKVvuEbu8KZQXMKNE"
|
48
|
+
expect(node.to_bip32(:private, network: :bitcoin_testnet)).to eql("tprv8ZgxMBicQKsPcuN7bfUZqq78UEYapr3Tzmc9NcDXw8BnBJ47dZYr6SusnfYj7vbAYP9CP8ZiD5aVBTUo1yU5QP56mepKVvuEbu8KZQXMKNE")
|
49
49
|
end
|
50
50
|
|
51
51
|
it "imports from testnet serialized public address" do
|
52
|
-
node = MoneyTree::Node.from_bip32
|
52
|
+
node = MoneyTree::Node.from_bip32 "tpubD6NzVbkrYhZ4YA8aUE9bBZTSyHJibBqwDny5urfwDdJc4W8od3y3Ebzy6CqsYn9CCC5P5VQ7CeZYpnT1kX3RPVPysU2rFRvYSj8BCoYYNqT"
|
53
53
|
expect(%w(m n)).to include(node.public_key.to_s(network: :bitcoin_testnet)[0])
|
54
|
-
expect(node.to_bip32(network: :bitcoin_testnet)).to eql(
|
54
|
+
expect(node.to_bip32(network: :bitcoin_testnet)).to eql("tpubD6NzVbkrYhZ4YA8aUE9bBZTSyHJibBqwDny5urfwDdJc4W8od3y3Ebzy6CqsYn9CCC5P5VQ7CeZYpnT1kX3RPVPysU2rFRvYSj8BCoYYNqT")
|
55
55
|
end
|
56
56
|
|
57
57
|
it "generates testnet subnodes from serialized private address" do
|
58
|
-
node = MoneyTree::Node.from_bip32
|
59
|
-
subnode = node.node_for_path(
|
58
|
+
node = MoneyTree::Node.from_bip32 "tprv8ZgxMBicQKsPcuN7bfUZqq78UEYapr3Tzmc9NcDXw8BnBJ47dZYr6SusnfYj7vbAYP9CP8ZiD5aVBTUo1yU5QP56mepKVvuEbu8KZQXMKNE"
|
59
|
+
subnode = node.node_for_path("1/1/1")
|
60
60
|
expect(%w(m n)).to include(subnode.public_key.to_s(network: :bitcoin_testnet)[0])
|
61
|
-
expect(subnode.to_bip32(:private, network: :bitcoin_testnet).slice(0,4)).to eql(
|
62
|
-
expect(subnode.to_bip32(network: :bitcoin_testnet).slice(0,4)).to eql(
|
61
|
+
expect(subnode.to_bip32(:private, network: :bitcoin_testnet).slice(0, 4)).to eql("tprv")
|
62
|
+
expect(subnode.to_bip32(network: :bitcoin_testnet).slice(0, 4)).to eql("tpub")
|
63
63
|
end
|
64
64
|
|
65
65
|
it "generates testnet subnodes from serialized public address" do
|
66
|
-
node = MoneyTree::Node.from_bip32
|
67
|
-
subnode = node.node_for_path(
|
66
|
+
node = MoneyTree::Node.from_bip32 "tpubD6NzVbkrYhZ4YA8aUE9bBZTSyHJibBqwDny5urfwDdJc4W8od3y3Ebzy6CqsYn9CCC5P5VQ7CeZYpnT1kX3RPVPysU2rFRvYSj8BCoYYNqT"
|
67
|
+
subnode = node.node_for_path("1/1/1")
|
68
68
|
expect(%w(m n)).to include(subnode.public_key.to_s(network: :bitcoin_testnet)[0])
|
69
|
-
expect(subnode.to_bip32(network: :bitcoin_testnet).slice(0,4)).to eql(
|
69
|
+
expect(subnode.to_bip32(network: :bitcoin_testnet).slice(0, 4)).to eql("tpub")
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -93,6 +93,8 @@ describe MoneyTree::Master do
|
|
93
93
|
expect(@master.to_identifier).to eql("3442193e1bb70916e914552172cd4e2dbc9df811")
|
94
94
|
expect(@master.to_fingerprint).to eql("3442193e")
|
95
95
|
expect(@master.to_address).to eql("15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma")
|
96
|
+
expect(@master.to_p2wpkh_p2sh).to eql("3PpgpssV7mcAGpZRWiCWhodUTnjpoSZg7a")
|
97
|
+
expect(@master.to_bech32_address).to eql("bc1qx3ppj0smkuy3d6g525sh9n2w9k7fm7q3x30rtg")
|
96
98
|
end
|
97
99
|
|
98
100
|
it "generates a secret key" do
|
@@ -119,6 +121,104 @@ describe MoneyTree::Master do
|
|
119
121
|
end
|
120
122
|
end
|
121
123
|
|
124
|
+
describe "m/2147483648" do
|
125
|
+
before do
|
126
|
+
@node = @master.node_for_path "m/2147483648"
|
127
|
+
end
|
128
|
+
|
129
|
+
it "has an index of 2147483648" do
|
130
|
+
expect(@node.index).to eql(2147483648)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "is private" do
|
134
|
+
expect(@node.is_private?).to eql(true)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "has a depth of 1" do
|
138
|
+
expect(@node.depth).to eql(1)
|
139
|
+
end
|
140
|
+
|
141
|
+
it "generates subnode" do
|
142
|
+
expect(@node.to_identifier).to eql("5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7")
|
143
|
+
expect(@node.to_fingerprint).to eql("5c1bd648")
|
144
|
+
expect(@node.to_address).to eql("19Q2WoS5hSS6T8GjhK8KZLMgmWaq4neXrh")
|
145
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3AbBmNbPDSzeZKHywDrH3h5v2rL8xGfT7e")
|
146
|
+
expect(@node.to_bech32_address).to eql("bc1qtsdavj8dyw49l4gt554jg47pr60gpf48ww2ens")
|
147
|
+
end
|
148
|
+
|
149
|
+
it "generates a private key" do
|
150
|
+
expect(@node.private_key.to_hex).to eql("edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea")
|
151
|
+
expect(@node.private_key.to_wif).to eql("L5BmPijJjrKbiUfG4zbiFKNqkvuJ8usooJmzuD7Z8dkRoTThYnAT")
|
152
|
+
end
|
153
|
+
|
154
|
+
it "generates a public key" do
|
155
|
+
expect(@node.public_key.to_hex).to eql("035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56")
|
156
|
+
end
|
157
|
+
|
158
|
+
it "generates a chain code" do
|
159
|
+
expect(@node.chain_code_hex).to eql("47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141")
|
160
|
+
end
|
161
|
+
|
162
|
+
it "generates a serialized private key" do
|
163
|
+
expect(@node.to_serialized_hex(:private)).to eql("0488ade4013442193e8000000047fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae623614100edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea")
|
164
|
+
expect(@node.to_bip32(:private)).to eql("xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7")
|
165
|
+
end
|
166
|
+
|
167
|
+
it "generates a serialized public_key" do
|
168
|
+
expect(@node.to_serialized_hex).to eql("0488b21e013442193e8000000047fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56")
|
169
|
+
expect(@node.to_bip32).to eql("xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "m/-0" do
|
174
|
+
before do
|
175
|
+
@node = @master.node_for_path "m/-0"
|
176
|
+
end
|
177
|
+
|
178
|
+
it "has an index of 2147483648" do
|
179
|
+
expect(@node.index).to eql(2147483648)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "is private" do
|
183
|
+
expect(@node.is_private?).to eql(true)
|
184
|
+
end
|
185
|
+
|
186
|
+
it "has a depth of 1" do
|
187
|
+
expect(@node.depth).to eql(1)
|
188
|
+
end
|
189
|
+
|
190
|
+
it "generates subnode" do
|
191
|
+
expect(@node.to_identifier).to eql("5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7")
|
192
|
+
expect(@node.to_fingerprint).to eql("5c1bd648")
|
193
|
+
expect(@node.to_address).to eql("19Q2WoS5hSS6T8GjhK8KZLMgmWaq4neXrh")
|
194
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3AbBmNbPDSzeZKHywDrH3h5v2rL8xGfT7e")
|
195
|
+
expect(@node.to_bech32_address).to eql("bc1qtsdavj8dyw49l4gt554jg47pr60gpf48ww2ens")
|
196
|
+
end
|
197
|
+
|
198
|
+
it "generates a private key" do
|
199
|
+
expect(@node.private_key.to_hex).to eql("edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea")
|
200
|
+
expect(@node.private_key.to_wif).to eql("L5BmPijJjrKbiUfG4zbiFKNqkvuJ8usooJmzuD7Z8dkRoTThYnAT")
|
201
|
+
end
|
202
|
+
|
203
|
+
it "generates a public key" do
|
204
|
+
expect(@node.public_key.to_hex).to eql("035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56")
|
205
|
+
end
|
206
|
+
|
207
|
+
it "generates a chain code" do
|
208
|
+
expect(@node.chain_code_hex).to eql("47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141")
|
209
|
+
end
|
210
|
+
|
211
|
+
it "generates a serialized private key" do
|
212
|
+
expect(@node.to_serialized_hex(:private)).to eql("0488ade4013442193e8000000047fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae623614100edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea")
|
213
|
+
expect(@node.to_bip32(:private)).to eql("xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7")
|
214
|
+
end
|
215
|
+
|
216
|
+
it "generates a serialized public_key" do
|
217
|
+
expect(@node.to_serialized_hex).to eql("0488b21e013442193e8000000047fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56")
|
218
|
+
expect(@node.to_bip32).to eql("xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw")
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
122
222
|
describe "m/0p" do
|
123
223
|
before do
|
124
224
|
@node = @master.node_for_path "m/0p"
|
@@ -140,6 +240,8 @@ describe MoneyTree::Master do
|
|
140
240
|
expect(@node.to_identifier).to eql("5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7")
|
141
241
|
expect(@node.to_fingerprint).to eql("5c1bd648")
|
142
242
|
expect(@node.to_address).to eql("19Q2WoS5hSS6T8GjhK8KZLMgmWaq4neXrh")
|
243
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3AbBmNbPDSzeZKHywDrH3h5v2rL8xGfT7e")
|
244
|
+
expect(@node.to_bech32_address).to eql("bc1qtsdavj8dyw49l4gt554jg47pr60gpf48ww2ens")
|
143
245
|
end
|
144
246
|
|
145
247
|
it "generates a private key" do
|
@@ -187,6 +289,8 @@ describe MoneyTree::Master do
|
|
187
289
|
expect(@node.to_identifier).to eql("5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7")
|
188
290
|
expect(@node.to_fingerprint).to eql("5c1bd648")
|
189
291
|
expect(@node.to_address).to eql("19Q2WoS5hSS6T8GjhK8KZLMgmWaq4neXrh")
|
292
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3AbBmNbPDSzeZKHywDrH3h5v2rL8xGfT7e")
|
293
|
+
expect(@node.to_bech32_address).to eql("bc1qtsdavj8dyw49l4gt554jg47pr60gpf48ww2ens")
|
190
294
|
end
|
191
295
|
|
192
296
|
it "does not generate a private key" do
|
@@ -232,6 +336,8 @@ describe MoneyTree::Master do
|
|
232
336
|
expect(@node.to_identifier).to eql("bef5a2f9a56a94aab12459f72ad9cf8cf19c7bbe")
|
233
337
|
expect(@node.to_fingerprint).to eql("bef5a2f9")
|
234
338
|
expect(@node.to_address).to eql("1JQheacLPdM5ySCkrZkV66G2ApAXe1mqLj")
|
339
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3DymAvEWH38HuzHZ3VwLus673bNZnYwNXu")
|
340
|
+
expect(@node.to_bech32_address).to eql("bc1qhm6697d9d2224vfyt8mj4kw03ncec7a7fdafvt")
|
235
341
|
end
|
236
342
|
|
237
343
|
it "generates a private key" do
|
@@ -279,6 +385,8 @@ describe MoneyTree::Master do
|
|
279
385
|
expect(@node.to_identifier).to eql("bef5a2f9a56a94aab12459f72ad9cf8cf19c7bbe")
|
280
386
|
expect(@node.to_fingerprint).to eql("bef5a2f9")
|
281
387
|
expect(@node.to_address).to eql("1JQheacLPdM5ySCkrZkV66G2ApAXe1mqLj")
|
388
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3DymAvEWH38HuzHZ3VwLus673bNZnYwNXu")
|
389
|
+
expect(@node.to_bech32_address).to eql("bc1qhm6697d9d2224vfyt8mj4kw03ncec7a7fdafvt")
|
282
390
|
end
|
283
391
|
|
284
392
|
it "does not generate a private key" do
|
@@ -324,6 +432,8 @@ describe MoneyTree::Master do
|
|
324
432
|
expect(@node.to_identifier).to eql("d880d7d893848509a62d8fb74e32148dac68412f")
|
325
433
|
expect(@node.to_fingerprint).to eql("d880d7d8")
|
326
434
|
expect(@node.to_address).to eql("1LjmJcdPnDHhNTUgrWyhLGnRDKxQjoxAgt")
|
435
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3PxPuCJMQGgkPYArciuUFakdiKC58j3Df6")
|
436
|
+
expect(@node.to_bech32_address).to eql("bc1qmzqd0kynsjzsnf3d37m5uvs53kkxssf0dr5zvn")
|
327
437
|
end
|
328
438
|
|
329
439
|
it "generates a private key" do
|
@@ -371,6 +481,8 @@ describe MoneyTree::Master do
|
|
371
481
|
expect(@node.to_identifier).to eql("d69aa102255fed74378278c7812701ea641fdf32")
|
372
482
|
expect(@node.to_fingerprint).to eql("d69aa102")
|
373
483
|
expect(@node.to_address).to eql("1LZiqrop2HGR4qrH1ULZPyBpU6AUP49Uam")
|
484
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3BuqWierKkrD7XEeJL4hucMGqVCe5G4WK7")
|
485
|
+
expect(@node.to_bech32_address).to eql("bc1q66d2zq39tlkhgduz0rrczfcpafjplhejmtgugz")
|
374
486
|
end
|
375
487
|
|
376
488
|
it "generates a private key" do
|
@@ -422,10 +534,14 @@ describe MoneyTree::Master do
|
|
422
534
|
expect(@master.to_identifier).to eql("bd16bee53961a47d6ad888e29545434a89bdfe95")
|
423
535
|
expect(@master.to_fingerprint).to eql("bd16bee5")
|
424
536
|
expect(@master.to_address).to eql("1JEoxevbLLG8cVqeoGKQiAwoWbNYSUyYjg")
|
537
|
+
expect(@master.to_p2wpkh_p2sh).to eql("3QaGQQTfBvSxXnsggeGxF3zfTAo3uyeREG")
|
538
|
+
expect(@master.to_bech32_address).to eql("bc1qh5ttaefevxj866kc3r3f232rf2ymml54ypyvy3")
|
425
539
|
end
|
426
540
|
|
427
541
|
it "generates compressed and uncompressed addresses" do
|
428
542
|
expect(@master.to_address).to eql("1JEoxevbLLG8cVqeoGKQiAwoWbNYSUyYjg")
|
543
|
+
expect(@master.to_p2wpkh_p2sh).to eql("3QaGQQTfBvSxXnsggeGxF3zfTAo3uyeREG")
|
544
|
+
expect(@master.to_bech32_address).to eql("bc1qh5ttaefevxj866kc3r3f232rf2ymml54ypyvy3")
|
429
545
|
expect(@master.to_address(true)).to eql("1JEoxevbLLG8cVqeoGKQiAwoWbNYSUyYjg")
|
430
546
|
expect(@master.to_address(false)).to eql("1AEg9dFEw29kMgaN4BNHALu7AzX5XUfzSU")
|
431
547
|
end
|
@@ -476,6 +592,8 @@ describe MoneyTree::Master do
|
|
476
592
|
expect(@node.to_identifier).to eql("5a61ff8eb7aaca3010db97ebda76121610b78096")
|
477
593
|
expect(@node.to_fingerprint).to eql("5a61ff8e")
|
478
594
|
expect(@node.to_address).to eql("19EuDJdgfRkwCmRzbzVBHZWQG9QNWhftbZ")
|
595
|
+
expect(@node.to_p2wpkh_p2sh).to eql("39cFMGtVaEw6AfksMcaLpu8frZxmqngh8c")
|
596
|
+
expect(@node.to_bech32_address).to eql("bc1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qykp3q3we")
|
479
597
|
end
|
480
598
|
|
481
599
|
it "generates a private key" do
|
@@ -524,6 +642,8 @@ describe MoneyTree::Master do
|
|
524
642
|
expect(@node.to_identifier).to eql("5a61ff8eb7aaca3010db97ebda76121610b78096")
|
525
643
|
expect(@node.to_fingerprint).to eql("5a61ff8e")
|
526
644
|
expect(@node.to_address).to eql("19EuDJdgfRkwCmRzbzVBHZWQG9QNWhftbZ")
|
645
|
+
expect(@node.to_p2wpkh_p2sh).to eql("39cFMGtVaEw6AfksMcaLpu8frZxmqngh8c")
|
646
|
+
expect(@node.to_bech32_address).to eql("bc1qtfsllr4h4t9rqyxmjl4a5asjzcgt0qykp3q3we")
|
527
647
|
end
|
528
648
|
|
529
649
|
it "does not generate a private key" do
|
@@ -570,6 +690,8 @@ describe MoneyTree::Master do
|
|
570
690
|
expect(@node.to_identifier).to eql("d8ab493736da02f11ed682f88339e720fb0379d1")
|
571
691
|
expect(@node.to_fingerprint).to eql("d8ab4937")
|
572
692
|
expect(@node.to_address).to eql("1Lke9bXGhn5VPrBuXgN12uGUphrttUErmk")
|
693
|
+
expect(@node.to_p2wpkh_p2sh).to eql("39oYp2KWMueN9LSVyDGUGAeDeAgdj43suV")
|
694
|
+
expect(@node.to_bech32_address).to eql("bc1qmz45jdekmgp0z8kkstugxw08yrasx7w3dse4fe")
|
573
695
|
end
|
574
696
|
|
575
697
|
it "generates a private key" do
|
@@ -617,6 +739,8 @@ describe MoneyTree::Master do
|
|
617
739
|
expect(@node.to_identifier).to eql("78412e3a2296a40de124307b6485bd19833e2e34")
|
618
740
|
expect(@node.to_fingerprint).to eql("78412e3a")
|
619
741
|
expect(@node.to_address).to eql("1BxrAr2pHpeBheusmd6fHDP2tSLAUa3qsW")
|
742
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3McFiyStLZ4GzqN9Hx7rG7iyVjaX5Hf7VH")
|
743
|
+
expect(@node.to_bech32_address).to eql("bc1q0pqjuw3zj6jqmcfyxpakfpdarxpnut35gr8lsl")
|
620
744
|
end
|
621
745
|
|
622
746
|
it "generates a private key" do
|
@@ -664,6 +788,8 @@ describe MoneyTree::Master do
|
|
664
788
|
expect(@node.to_identifier).to eql("31a507b815593dfc51ffc7245ae7e5aee304246e")
|
665
789
|
expect(@node.to_fingerprint).to eql("31a507b8")
|
666
790
|
expect(@node.to_address).to eql("15XVotxCAV7sRx1PSCkQNsGw3W9jT9A94R")
|
791
|
+
expect(@node.to_p2wpkh_p2sh).to eql("35aip4nbX3wM2V3NMxHgPz1wEUQ2T7BJPY")
|
792
|
+
expect(@node.to_bech32_address).to eql("bc1qxxjs0wq4ty7lc50lcuj94el94m3sgfrwfvky9p")
|
667
793
|
end
|
668
794
|
|
669
795
|
it "generates a private key" do
|
@@ -711,6 +837,8 @@ describe MoneyTree::Master do
|
|
711
837
|
expect(@node.to_identifier).to eql("26132fdbe7bf89cbc64cf8dafa3f9f88b8666220")
|
712
838
|
expect(@node.to_fingerprint).to eql("26132fdb")
|
713
839
|
expect(@node.to_address).to eql("14UKfRV9ZPUp6ZC9PLhqbRtxdihW9em3xt")
|
840
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3NUwiFMvp3CN1MYXkUjkoboYk7mHuQTTUn")
|
841
|
+
expect(@node.to_bech32_address).to eql("bc1qycfjlkl8h7yuh3jvlrd050ul3zuxvc3qphdmd3")
|
714
842
|
end
|
715
843
|
|
716
844
|
it "generates a private key" do
|
@@ -739,6 +867,386 @@ describe MoneyTree::Master do
|
|
739
867
|
end
|
740
868
|
end
|
741
869
|
|
870
|
+
describe "Test vector 3" do
|
871
|
+
describe "from a seed" do
|
872
|
+
before do
|
873
|
+
@master = MoneyTree::Master.new seed_hex: "4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be"
|
874
|
+
end
|
875
|
+
|
876
|
+
describe "m" do
|
877
|
+
it "has an index of 0" do
|
878
|
+
expect(@master.index).to eql(0)
|
879
|
+
end
|
880
|
+
|
881
|
+
it "is private" do
|
882
|
+
expect(@master.is_private?).to eql(true)
|
883
|
+
end
|
884
|
+
|
885
|
+
it "has a depth of 0" do
|
886
|
+
expect(@master.depth).to eql(0)
|
887
|
+
end
|
888
|
+
|
889
|
+
it "generates master node (Master)" do
|
890
|
+
expect(@master.to_identifier).to eql("41d63b50d8dd5e730cdf4c79a56fc929a757c548")
|
891
|
+
expect(@master.to_fingerprint).to eql("41d63b50")
|
892
|
+
expect(@master.to_address).to eql("1717ZYpXhZW5CqAbWSjDJbCey3FyKUmCSf")
|
893
|
+
expect(@master.to_p2wpkh_p2sh).to eql("3B4MJ7rJ9c5UfgKMfwqeB4Uh7kGNwqQhK6")
|
894
|
+
expect(@master.to_bech32_address).to eql("bc1qg8trk5xcm408xrxlf3u62m7f9xn4032gl36vmu")
|
895
|
+
end
|
896
|
+
|
897
|
+
it "generates a secret key" do
|
898
|
+
expect(@master.private_key.to_hex).to eql("00ddb80b067e0d4993197fe10f2657a844a384589847602d56f0c629c81aae32")
|
899
|
+
expect(@master.private_key.to_wif).to eql("KwFPqAq9SKx1sPg15Qk56mqkHwrfGPuywtLUxoWPkiTSBoxCs8am")
|
900
|
+
end
|
901
|
+
|
902
|
+
it "generates a public key" do
|
903
|
+
expect(@master.public_key.to_hex).to eql("03683af1ba5743bdfc798cf814efeeab2735ec52d95eced528e692b8e34c4e5669")
|
904
|
+
end
|
905
|
+
|
906
|
+
it "generates a chain code" do
|
907
|
+
expect(@master.chain_code_hex).to eql("01d28a3e53cffa419ec122c968b3259e16b65076495494d97cae10bbfec3c36f")
|
908
|
+
end
|
909
|
+
|
910
|
+
it "generates a serialized private key" do
|
911
|
+
expect(@master.to_serialized_hex(:private)).to eql("0488ade400000000000000000001d28a3e53cffa419ec122c968b3259e16b65076495494d97cae10bbfec3c36f0000ddb80b067e0d4993197fe10f2657a844a384589847602d56f0c629c81aae32")
|
912
|
+
expect(@master.to_bip32(:private)).to eql("xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6")
|
913
|
+
end
|
914
|
+
|
915
|
+
it "generates a serialized public_key" do
|
916
|
+
expect(@master.to_serialized_hex).to eql("0488b21e00000000000000000001d28a3e53cffa419ec122c968b3259e16b65076495494d97cae10bbfec3c36f03683af1ba5743bdfc798cf814efeeab2735ec52d95eced528e692b8e34c4e5669")
|
917
|
+
expect(@master.to_bip32).to eql("xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13")
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
describe "m/0p" do
|
922
|
+
before do
|
923
|
+
@node = @master.node_for_path "m/0p"
|
924
|
+
end
|
925
|
+
|
926
|
+
it "has an index of 2147483648" do
|
927
|
+
expect(@node.index).to eql(2147483648)
|
928
|
+
end
|
929
|
+
|
930
|
+
it "is private" do
|
931
|
+
expect(@node.is_private?).to eql(true)
|
932
|
+
end
|
933
|
+
|
934
|
+
it "has a depth of 1" do
|
935
|
+
expect(@node.depth).to eql(1)
|
936
|
+
end
|
937
|
+
|
938
|
+
it "generates subnode" do
|
939
|
+
expect(@node.to_identifier).to eql("c61368bb50e066acd95bd04a0b23d3837fb75698")
|
940
|
+
expect(@node.to_fingerprint).to eql("c61368bb")
|
941
|
+
expect(@node.to_address).to eql("1K4L3YxEwg8HkSEapM4iSiGuR6HeQ53KPX")
|
942
|
+
expect(@node.to_p2wpkh_p2sh).to eql("34WHhyr9rrVxVVuYpDqwUmd4yXdWFoKxLf")
|
943
|
+
expect(@node.to_bech32_address).to eql("bc1qccfk3w6supn2ek2m6p9qkg7nsdlmw45cj06e96")
|
944
|
+
end
|
945
|
+
|
946
|
+
it "generates a private key" do
|
947
|
+
expect(@node.private_key.to_hex).to eql("491f7a2eebc7b57028e0d3faa0acda02e75c33b03c48fb288c41e2ea44e1daef")
|
948
|
+
expect(@node.private_key.to_wif).to eql("KyfrPaeirL5yYAoZvfzyoKXSdszeLqg5vb6dNy9ymvjzZrMZY8GW")
|
949
|
+
end
|
950
|
+
|
951
|
+
it "generates a public key" do
|
952
|
+
expect(@node.public_key.to_hex).to eql("026557fdda1d5d43d79611f784780471f086d58e8126b8c40acb82272a7712e7f2")
|
953
|
+
end
|
954
|
+
|
955
|
+
it "generates a chain code" do
|
956
|
+
expect(@node.chain_code_hex).to eql("e5fea12a97b927fc9dc3d2cb0d1ea1cf50aa5a1fdc1f933e8906bb38df3377bd")
|
957
|
+
end
|
958
|
+
|
959
|
+
it "generates a serialized private key" do
|
960
|
+
expect(@node.to_serialized_hex(:private)).to eql("0488ade40141d63b5080000000e5fea12a97b927fc9dc3d2cb0d1ea1cf50aa5a1fdc1f933e8906bb38df3377bd00491f7a2eebc7b57028e0d3faa0acda02e75c33b03c48fb288c41e2ea44e1daef")
|
961
|
+
expect(@node.to_bip32(:private)).to eql("xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L")
|
962
|
+
end
|
963
|
+
|
964
|
+
it "generates a serialized public_key" do
|
965
|
+
expect(@node.to_serialized_hex).to eql("0488b21e0141d63b5080000000e5fea12a97b927fc9dc3d2cb0d1ea1cf50aa5a1fdc1f933e8906bb38df3377bd026557fdda1d5d43d79611f784780471f086d58e8126b8c40acb82272a7712e7f2")
|
966
|
+
expect(@node.to_bip32).to eql("xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y")
|
967
|
+
end
|
968
|
+
end
|
969
|
+
end
|
970
|
+
end
|
971
|
+
|
972
|
+
describe "Test vector 4" do
|
973
|
+
describe "from a seed" do
|
974
|
+
before do
|
975
|
+
@master = MoneyTree::Master.new seed_hex: "3ddd5602285899a946114506157c7997e5444528f3003f6134712147db19b678"
|
976
|
+
end
|
977
|
+
|
978
|
+
describe "m" do
|
979
|
+
it "has an index of 0" do
|
980
|
+
expect(@master.index).to eql(0)
|
981
|
+
end
|
982
|
+
|
983
|
+
it "is private" do
|
984
|
+
expect(@master.is_private?).to eql(true)
|
985
|
+
end
|
986
|
+
|
987
|
+
it "has a depth of 0" do
|
988
|
+
expect(@master.depth).to eql(0)
|
989
|
+
end
|
990
|
+
|
991
|
+
it "generates master node (Master)" do
|
992
|
+
expect(@master.to_identifier).to eql("ad85d95573bc609b98f2af5e06e150351f818ba9")
|
993
|
+
expect(@master.to_fingerprint).to eql("ad85d955")
|
994
|
+
expect(@master.to_address).to eql("1GpWFBBE37FQumRkrVUL6HB1bqSWCuYsKt")
|
995
|
+
expect(@master.to_p2wpkh_p2sh).to eql("33Koj9buBXM1UsNZjNdHSNeBCjxRLqVyRE")
|
996
|
+
expect(@master.to_bech32_address).to eql("bc1q4kzaj4tnh3sfhx8j4a0qdc2sx50crzaf2ka04w")
|
997
|
+
end
|
998
|
+
|
999
|
+
it "generates a secret key" do
|
1000
|
+
expect(@master.private_key.to_hex).to eql("12c0d59c7aa3a10973dbd3f478b65f2516627e3fe61e00c345be9a477ad2e215")
|
1001
|
+
expect(@master.private_key.to_wif).to eql("KwrAWXgyy1L75ZBRp1PzHj2aWBoYcddgrEMfF6iBJFuw8adwRNLu")
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
it "generates a public key" do
|
1005
|
+
expect(@master.public_key.to_hex).to eql("026f6fedc9240f61daa9c7144b682a430a3a1366576f840bf2d070101fcbc9a02d")
|
1006
|
+
end
|
1007
|
+
|
1008
|
+
it "generates a chain code" do
|
1009
|
+
expect(@master.chain_code_hex).to eql("d0c8a1f6edf2500798c3e0b54f1b56e45f6d03e6076abd36e5e2f54101e44ce6")
|
1010
|
+
end
|
1011
|
+
|
1012
|
+
it "generates a serialized private key" do
|
1013
|
+
expect(@master.to_serialized_hex(:private)).to eql("0488ade4000000000000000000d0c8a1f6edf2500798c3e0b54f1b56e45f6d03e6076abd36e5e2f54101e44ce60012c0d59c7aa3a10973dbd3f478b65f2516627e3fe61e00c345be9a477ad2e215")
|
1014
|
+
expect(@master.to_bip32(:private)).to eql("xprv9s21ZrQH143K48vGoLGRPxgo2JNkJ3J3fqkirQC2zVdk5Dgd5w14S7fRDyHH4dWNHUgkvsvNDCkvAwcSHNAQwhwgNMgZhLtQC63zxwhQmRv")
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
it "generates a serialized public_key" do
|
1018
|
+
expect(@master.to_serialized_hex).to eql("0488b21e000000000000000000d0c8a1f6edf2500798c3e0b54f1b56e45f6d03e6076abd36e5e2f54101e44ce6026f6fedc9240f61daa9c7144b682a430a3a1366576f840bf2d070101fcbc9a02d")
|
1019
|
+
expect(@master.to_bip32).to eql("xpub661MyMwAqRbcGczjuMoRm6dXaLDEhW1u34gKenbeYqAix21mdUKJyuyu5F1rzYGVxyL6tmgBUAEPrEz92mBXjByMRiJdba9wpnN37RLLAXa")
|
1020
|
+
end
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
describe "m/0p" do
|
1024
|
+
before do
|
1025
|
+
@node = @master.node_for_path "m/0p"
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
it "has an index of 2147483648" do
|
1029
|
+
expect(@node.index).to eql(2147483648)
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
it "is private" do
|
1033
|
+
expect(@node.is_private?).to eql(true)
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
it "has a depth of 1" do
|
1037
|
+
expect(@node.depth).to eql(1)
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
it "generates subnode" do
|
1041
|
+
expect(@node.to_identifier).to eql("cfa61281b1762be25710658757221a6437cbcdd6")
|
1042
|
+
expect(@node.to_fingerprint).to eql("cfa61281")
|
1043
|
+
expect(@node.to_address).to eql("1KvwpccVR6CsN3ve2LZpxkSZ5od5262b75")
|
1044
|
+
expect(@node.to_p2wpkh_p2sh).to eql("369UTJMek2ve1ANb18R91S9638scFYWJm3")
|
1045
|
+
expect(@node.to_bech32_address).to eql("bc1qe7np9qd3wc47y4csvkr4wgs6vsmuhnwkve50q9")
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
it "generates a private key" do
|
1049
|
+
expect(@node.private_key.to_hex).to eql("00d948e9261e41362a688b916f297121ba6bfb2274a3575ac0e456551dfd7f7e")
|
1050
|
+
expect(@node.private_key.to_wif).to eql("KwFMsuZ3pmk7ebtbTiPirTpdcPkS6wvnSazU3bvixwiCw1bNQLhG")
|
1051
|
+
end
|
1052
|
+
|
1053
|
+
it "generates a public key" do
|
1054
|
+
expect(@node.public_key.to_hex).to eql("039382d2b6003446792d2917f7ac4b3edf079a1a94dd4eb010dc25109dda680a9d")
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
it "generates a chain code" do
|
1058
|
+
expect(@node.chain_code_hex).to eql("cdc0f06456a14876c898790e0b3b1a41c531170aec69da44ff7b7265bfe7743b")
|
1059
|
+
end
|
1060
|
+
|
1061
|
+
it "generates a serialized private key" do
|
1062
|
+
expect(@node.to_serialized_hex(:private)).to eql("0488ade401ad85d95580000000cdc0f06456a14876c898790e0b3b1a41c531170aec69da44ff7b7265bfe7743b0000d948e9261e41362a688b916f297121ba6bfb2274a3575ac0e456551dfd7f7e")
|
1063
|
+
expect(@node.to_bip32(:private)).to eql("xprv9vB7xEWwNp9kh1wQRfCCQMnZUEG21LpbR9NPCNN1dwhiZkjjeGRnaALmPXCX7SgjFTiCTT6bXes17boXtjq3xLpcDjzEuGLQBM5ohqkao9G")
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
it "generates a serialized public_key" do
|
1067
|
+
expect(@node.to_serialized_hex).to eql("0488b21e01ad85d95580000000cdc0f06456a14876c898790e0b3b1a41c531170aec69da44ff7b7265bfe7743b039382d2b6003446792d2917f7ac4b3edf079a1a94dd4eb010dc25109dda680a9d")
|
1068
|
+
expect(@node.to_bip32).to eql("xpub69AUMk3qDBi3uW1sXgjCmVjJ2G6WQoYSnNHyzkmdCHEhSZ4tBok37xfFEqHd2AddP56Tqp4o56AePAgCjYdvpW2PU2jbUPFKsav5ut6Ch1m")
|
1069
|
+
end
|
1070
|
+
end
|
1071
|
+
|
1072
|
+
describe "m/0'/1p" do
|
1073
|
+
before do
|
1074
|
+
@node = @master.node_for_path "m/0'/1p"
|
1075
|
+
end
|
1076
|
+
|
1077
|
+
it "has an index of 1" do
|
1078
|
+
expect(@node.index).to eql(2147483649)
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
it "is public" do
|
1082
|
+
expect(@node.is_private?).to eql(true)
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
it "has a depth of 2" do
|
1086
|
+
expect(@node.depth).to eql(2)
|
1087
|
+
end
|
1088
|
+
|
1089
|
+
it "generates subnode" do
|
1090
|
+
expect(@node.to_identifier).to eql("48b2a62638e9cb9b68f87671bc80041dbd3acf70")
|
1091
|
+
expect(@node.to_fingerprint).to eql("48b2a626")
|
1092
|
+
expect(@node.to_address).to eql("17dPfZg9P2zjrdkhsSAYt5YU7TwFpU6Acd")
|
1093
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3JvZhix4hLkSJXiWbpx7ZGXJb3AXJg5xZ3")
|
1094
|
+
expect(@node.to_bech32_address).to eql("bc1qfze2vf3ca89ek68cwecmeqqyrk7n4nmsml42sp")
|
1095
|
+
end
|
1096
|
+
|
1097
|
+
it "generates a private key" do
|
1098
|
+
expect(@node.private_key.to_hex).to eql("3a2086edd7d9df86c3487a5905a1712a9aa664bce8cc268141e07549eaa8661d")
|
1099
|
+
expect(@node.private_key.to_wif).to eql("KyAhgkU6sXTCm3eiHu81ev4jhcnEs6Toppbr8hqcm82jUFxbLX3u")
|
1100
|
+
end
|
1101
|
+
|
1102
|
+
it "generates a public key" do
|
1103
|
+
expect(@node.public_key.to_hex).to eql("032edaf9e591ee27f3c69c36221e3c54c38088ef34e93fbb9bb2d4d9b92364cbbd")
|
1104
|
+
end
|
1105
|
+
|
1106
|
+
it "generates a chain code" do
|
1107
|
+
expect(@node.chain_code_hex).to eql("a48ee6674c5264a237703fd383bccd9fad4d9378ac98ab05e6e7029b06360c0d")
|
1108
|
+
end
|
1109
|
+
|
1110
|
+
it "generates a serialized private key" do
|
1111
|
+
expect(@node.to_serialized_hex(:private)).to eql("0488ade402cfa6128180000001a48ee6674c5264a237703fd383bccd9fad4d9378ac98ab05e6e7029b06360c0d003a2086edd7d9df86c3487a5905a1712a9aa664bce8cc268141e07549eaa8661d")
|
1112
|
+
expect(@node.to_bip32(:private)).to eql("xprv9xJocDuwtYCMNAo3Zw76WENQeAS6WGXQ55RCy7tDJ8oALr4FWkuVoHJeHVAcAqiZLE7Je3vZJHxspZdFHfnBEjHqU5hG1Jaj32dVoS6XLT1")
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
it "generates a serialized public_key" do
|
1116
|
+
expect(@node.to_serialized_hex).to eql("0488b21e02cfa6128180000001a48ee6674c5264a237703fd383bccd9fad4d9378ac98ab05e6e7029b06360c0d032edaf9e591ee27f3c69c36221e3c54c38088ef34e93fbb9bb2d4d9b92364cbbd")
|
1117
|
+
expect(@node.to_bip32).to eql("xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt")
|
1118
|
+
end
|
1119
|
+
end
|
1120
|
+
|
1121
|
+
describe "M/0'/1p" do
|
1122
|
+
before do
|
1123
|
+
@node = @master.node_for_path "M/0'/1p"
|
1124
|
+
end
|
1125
|
+
|
1126
|
+
it "has an index of 1" do
|
1127
|
+
expect(@node.index).to eql(2147483649)
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
it "is public" do
|
1131
|
+
expect(@node.is_private?).to eql(true)
|
1132
|
+
end
|
1133
|
+
|
1134
|
+
it "has a depth of 2" do
|
1135
|
+
expect(@node.depth).to eql(2)
|
1136
|
+
end
|
1137
|
+
|
1138
|
+
it "generates subnode" do
|
1139
|
+
expect(@node.to_identifier).to eql("48b2a62638e9cb9b68f87671bc80041dbd3acf70")
|
1140
|
+
expect(@node.to_fingerprint).to eql("48b2a626")
|
1141
|
+
expect(@node.to_address).to eql("17dPfZg9P2zjrdkhsSAYt5YU7TwFpU6Acd")
|
1142
|
+
expect(@node.to_p2wpkh_p2sh).to eql("3JvZhix4hLkSJXiWbpx7ZGXJb3AXJg5xZ3")
|
1143
|
+
expect(@node.to_bech32_address).to eql("bc1qfze2vf3ca89ek68cwecmeqqyrk7n4nmsml42sp")
|
1144
|
+
end
|
1145
|
+
|
1146
|
+
it "does not generate a private key" do
|
1147
|
+
expect(@node.private_key).to be_nil
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
it "generates a public key" do
|
1151
|
+
expect(@node.public_key.to_hex).to eql("032edaf9e591ee27f3c69c36221e3c54c38088ef34e93fbb9bb2d4d9b92364cbbd")
|
1152
|
+
end
|
1153
|
+
|
1154
|
+
it "generates a chain code" do
|
1155
|
+
expect(@node.chain_code_hex).to eql("a48ee6674c5264a237703fd383bccd9fad4d9378ac98ab05e6e7029b06360c0d")
|
1156
|
+
end
|
1157
|
+
|
1158
|
+
it "generates a serialized private key" do
|
1159
|
+
expect { @node.to_serialized_hex(:private) }.to raise_error(MoneyTree::Node::PrivatePublicMismatch)
|
1160
|
+
end
|
1161
|
+
|
1162
|
+
it "generates a serialized public_key" do
|
1163
|
+
expect(@node.to_serialized_hex).to eql("0488b21e02cfa6128180000001a48ee6674c5264a237703fd383bccd9fad4d9378ac98ab05e6e7029b06360c0d032edaf9e591ee27f3c69c36221e3c54c38088ef34e93fbb9bb2d4d9b92364cbbd")
|
1164
|
+
expect(@node.to_bip32).to eql("xpub6BJA1jSqiukeaesWfxe6sNK9CCGaujFFSJLomWHprUL9DePQ4JDkM5d88n49sMGJxrhpjazuXYWdMf17C9T5XnxkopaeS7jGk1GyyVziaMt")
|
1165
|
+
end
|
1166
|
+
end
|
1167
|
+
end
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
describe "Test vector 5" do
|
1171
|
+
describe "from an invalid bip32 key" do
|
1172
|
+
# it "recognizes pubkey version / prvkey mismatch" do
|
1173
|
+
# MoneyTree::Node.from_bip32 "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6LBpB85b3D2yc8sfvZU521AAwdZafEz7mnzBBsz4wKY5fTtTQBm"
|
1174
|
+
# end
|
1175
|
+
|
1176
|
+
# it "recognizes prvkey version / pubkey mismatch" do
|
1177
|
+
# MoneyTree::Node.from_bip32 "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGTQQD3dC4H2D5GBj7vWvSQaaBv5cxi9gafk7NF3pnBju6dwKvH"
|
1178
|
+
# end
|
1179
|
+
|
1180
|
+
it "recognizes invalid pubkey prefix 04" do
|
1181
|
+
expect {
|
1182
|
+
MoneyTree::Node.from_bip32 "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Txnt3siSujt9RCVYsx4qHZGc62TG4McvMGcAUjeuwZdduYEvFn"
|
1183
|
+
}.to raise_error MoneyTree::Node::ImportError
|
1184
|
+
end
|
1185
|
+
|
1186
|
+
it "recognizes invalid prvkey prefix 04" do
|
1187
|
+
expect {
|
1188
|
+
MoneyTree::Node.from_bip32 "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFGpWnsj83BHtEy5Zt8CcDr1UiRXuWCmTQLxEK9vbz5gPstX92JQ"
|
1189
|
+
}.to raise_error MoneyTree::Node::ImportError
|
1190
|
+
end
|
1191
|
+
|
1192
|
+
it "recognizes invalid pubkey prefix 01" do
|
1193
|
+
expect {
|
1194
|
+
MoneyTree::Node.from_bip32 "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6N8ZMMXctdiCjxTNq964yKkwrkBJJwpzZS4HS2fxvyYUA4q2Xe4"
|
1195
|
+
}.to raise_error MoneyTree::Node::ImportError
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
it "recognizes invalid prvkey prefix 01" do
|
1199
|
+
expect {
|
1200
|
+
MoneyTree::Node.from_bip32 "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fEQ3Qen6J"
|
1201
|
+
}.to raise_error MoneyTree::Node::ImportError
|
1202
|
+
end
|
1203
|
+
|
1204
|
+
# it "recognizes zero depth with non-zero parent fingerprint" do
|
1205
|
+
# MoneyTree::Node.from_bip32 "xprv9s2SPatNQ9Vc6GTbVMFPFo7jsaZySyzk7L8n2uqKXJen3KUmvQNTuLh3fhZMBoG3G4ZW1N2kZuHEPY53qmbZzCHshoQnNf4GvELZfqTUrcv"
|
1206
|
+
# end
|
1207
|
+
|
1208
|
+
# it "recognizes zero depth with non-zero parent fingerprint" do
|
1209
|
+
# MoneyTree::Node.from_bip32 "xpub661no6RGEX3uJkY4bNnPcw4URcQTrSibUZ4NqJEw5eBkv7ovTwgiT91XX27VbEXGENhYRCf7hyEbWrR3FewATdCEebj6znwMfQkhRYHRLpJ"
|
1210
|
+
# end
|
1211
|
+
|
1212
|
+
# it "recognizes zero depth with non-zero index" do
|
1213
|
+
# MoneyTree::Node.from_bip32 "xprv9s21ZrQH4r4TsiLvyLXqM9P7k1K3EYhA1kkD6xuquB5i39AU8KF42acDyL3qsDbU9NmZn6MsGSUYZEsuoePmjzsB3eFKSUEh3Gu1N3cqVUN"
|
1214
|
+
# end
|
1215
|
+
|
1216
|
+
# it "recognizes zero depth with non-zero index" do
|
1217
|
+
# MoneyTree::Node.from_bip32 "xpub661MyMwAuDcm6CRQ5N4qiHKrJ39Xe1R1NyfouMKTTWcguwVcfrZJaNvhpebzGerh7gucBvzEQWRugZDuDXjNDRmXzSZe4c7mnTK97pTvGS8"
|
1218
|
+
# end
|
1219
|
+
|
1220
|
+
# it "recognizes unknown extended key version" do
|
1221
|
+
# MoneyTree::Node.from_bip32 "DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHGMQzT7ayAmfo4z3gY5KfbrZWZ6St24UVf2Qgo6oujFktLHdHY4"
|
1222
|
+
# end
|
1223
|
+
|
1224
|
+
# it "recognizes unknown extended key version" do
|
1225
|
+
# MoneyTree::Node.from_bip32 "DMwo58pR1QLEFihHiXPVykYB6fJmsTeHvyTp7hRThAtCX8CvYzgPcn8XnmdfHPmHJiEDXkTiJTVV9rHEBUem2mwVbbNfvT2MTcAqj3nesx8uBf9"
|
1226
|
+
# end
|
1227
|
+
|
1228
|
+
# it "recognizes private key 0 not in 1..n-1" do
|
1229
|
+
# MoneyTree::Node.from_bip32 "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx"
|
1230
|
+
# end
|
1231
|
+
|
1232
|
+
# it "recognizes private key n not in 1..n-1" do
|
1233
|
+
# MoneyTree::Node.from_bip32 "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD5SDKr24z3aiUvKr9bJpdrcLg1y3G"
|
1234
|
+
# end
|
1235
|
+
|
1236
|
+
it "recognizes invalid pubkey 020000000000000000000000000000000000000000000000000000000000000007" do
|
1237
|
+
expect {
|
1238
|
+
MoneyTree::Node.from_bip32 "xpub661MyMwAqRbcEYS8w7XLSVeEsBXy79zSzH1J8vCdxAZningWLdN3zgtU6Q5JXayek4PRsn35jii4veMimro1xefsM58PgBMrvdYre8QyULY"
|
1239
|
+
}.to raise_error OpenSSL::PKey::EC::Point::Error
|
1240
|
+
end
|
1241
|
+
|
1242
|
+
it "recognizes invalid checksum" do
|
1243
|
+
expect {
|
1244
|
+
MoneyTree::Node.from_bip32 "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHL"
|
1245
|
+
}.to raise_error EncodingError
|
1246
|
+
end
|
1247
|
+
end
|
1248
|
+
end
|
1249
|
+
|
742
1250
|
describe "negative index" do
|
743
1251
|
before do
|
744
1252
|
@master = MoneyTree::Master.new seed_hex: "000102030405060708090a0b0c0d0e0f"
|
@@ -798,10 +1306,39 @@ describe MoneyTree::Master do
|
|
798
1306
|
describe "#node_for_path" do
|
799
1307
|
it "correctly derives from a node with a chain code represented in 31 bytes" do
|
800
1308
|
@node = MoneyTree::Node.from_bip32 "tpubD6NzVbkrYhZ4WM42MZZmUZ7LjxyjBf5bGjEeLf9nJnMZqocGJWu94drvpqWsE9jE7k3h22v6gjpPGnqgBrqwGsRYwDXVRfQ2M9dfHbXP5zA"
|
801
|
-
@subnode = @node.node_for_path(
|
1309
|
+
@subnode = @node.node_for_path("m/1")
|
802
1310
|
expect(@subnode.to_bip32(network: :bitcoin_testnet)).to eql("tpubDA7bCxb3Nrcz2ChXyPqXxbG4q5oiAZUHR7wD3LAiXukuxmT65weWw84XYmjhkJTkJEM6LhNWioWTpKEkQp7j2fgVccj3PPc271xHDeMsaTY")
|
803
1311
|
end
|
804
1312
|
end
|
805
1313
|
end
|
1314
|
+
|
1315
|
+
describe "deriving a parent node" do
|
1316
|
+
before do
|
1317
|
+
@master = MoneyTree::Master.new seed_hex: "000102030405060708090a0b0c0d0e0f"
|
1318
|
+
@node = @master.node_for_path("m/101p")
|
1319
|
+
@subnode = @node.node_for_path("1")
|
1320
|
+
end
|
1321
|
+
context "m/101'/1 -> m/101'" do
|
1322
|
+
it "correctly derives from a subnode with priv key to a node knowing it's public key" do
|
1323
|
+
node_priv_hex = @node.private_key.to_hex
|
1324
|
+
@node.strip_private_info!
|
1325
|
+
expect(@subnode.derive_parent_node(@node).private_key.to_hex).to eq(node_priv_hex)
|
1326
|
+
end
|
1327
|
+
end
|
1328
|
+
context "m/101' -> master" do
|
1329
|
+
it "unable to derive from a hardened node with priv key to a master node knowing it's public key" do
|
1330
|
+
master_priv_hex = @master.private_key.to_hex
|
1331
|
+
@master.strip_private_info!
|
1332
|
+
expect(@node.derive_parent_node(@master).private_key.to_hex).to_not eq(master_priv_hex)
|
1333
|
+
end
|
1334
|
+
end
|
1335
|
+
context "m/101 -> master" do
|
1336
|
+
it "correctly derives from a non-hardened node with priv key to a master node knowing it's public key" do
|
1337
|
+
@node = @master.node_for_path("m/101")
|
1338
|
+
master_priv_hex = @master.private_key.to_hex
|
1339
|
+
expect(@node.derive_parent_node(@master).private_key.to_hex).to eq(master_priv_hex)
|
1340
|
+
end
|
1341
|
+
end
|
1342
|
+
end
|
806
1343
|
end
|
807
1344
|
end
|