money-tree 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.simplecov +2 -2
- data/README.md +22 -17
- data/certs/mattatgemco.pem +24 -0
- data/checksum/money-tree-0.9.0.gem.sha512 +1 -0
- data/lib/money-tree/key.rb +9 -9
- data/lib/money-tree/node.rb +4 -4
- data/lib/money-tree/version.rb +1 -1
- data/lib/openssl_extensions.rb +1 -1
- data/money-tree.gemspec +3 -3
- data/spec/lib/money-tree/node_spec.rb +190 -190
- data/spec/lib/money-tree/private_key_spec.rb +11 -1
- metadata +28 -22
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e6b1fd18c035198917d9939d44f6bcbbe4ae69ef168af5de52ab32f5778662b1
|
4
|
+
data.tar.gz: 31ef2d35cd3d2f10cf40d7fe44787a38857c1c79173494f97d0d296f7828bfba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03c0b6c55c8f290f10989870d559904a644a68f441cc0ae6498d9cde12bc4853f63babc6ce68d5ad1dfbfb3f6a67b0b4b400053fdddacb62faa9d01adc43f765
|
7
|
+
data.tar.gz: 8c37b6e7386c60be7ac9797a248039b88ff39b0f46438a07c46aa363b8c8fa30160cdeb0f6d5d54f92fc0b512f437e6a73488cc12e355c25b04fb9dcb7af5d33
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.simplecov
CHANGED
data/README.md
CHANGED
@@ -60,7 +60,7 @@ These instructions assume you have a decent understanding of how Bitcoin wallets
|
|
60
60
|
|
61
61
|
### Create a Master Node (seed)
|
62
62
|
|
63
|
-
To create a new HD Wallet, we're going to create a tree structure of private/public keypairs (nodes). You'll first want to start with a master node. This master node should be seeded with at least 16 random bytes but preferably 32 random bytes from a cryptographically secure PRNG (pseudo-random number generator).
|
63
|
+
To create a new HD Wallet, we're going to create a tree structure of private/public keypairs (nodes). You'll first want to start with a master node. This master node should be seeded with at least 16 random bytes but preferably 32 random bytes from a cryptographically secure PRNG (pseudo-random number generator).
|
64
64
|
|
65
65
|
DO NOT use a user generated password. Keep in mind that whoever controls the seed controls ALL coins in the entire tree, so it should not be left up to a human brain, because humans tend to follow patterns and patterns are subject to brute force attacks. Luckily, MoneyTree includes the seed generation by default so you don't need to create this on your own.
|
66
66
|
|
@@ -109,19 +109,19 @@ DO NOT use a user generated password. Keep in mind that whoever controls the see
|
|
109
109
|
@master.public_key.to_hex
|
110
110
|
=> "0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2"
|
111
111
|
|
112
|
-
@master.chain_code_hex
|
112
|
+
@master.chain_code_hex
|
113
113
|
=> "873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508" # Look up chain codes in the BIP0032 spec
|
114
114
|
|
115
115
|
@master.to_serialized_hex(:private)
|
116
116
|
=> "0488ade4000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d50800e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35"
|
117
117
|
|
118
|
-
@master.
|
118
|
+
@master.to_bip32(:private)
|
119
119
|
=> "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"
|
120
120
|
|
121
121
|
@master.to_serialized_hex
|
122
122
|
=> "0488b21e000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d5080339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2"
|
123
123
|
|
124
|
-
@master.
|
124
|
+
@master.to_bip32
|
125
125
|
=> "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"
|
126
126
|
```
|
127
127
|
|
@@ -140,10 +140,10 @@ To generate a child node from a given path:
|
|
140
140
|
@node.depth
|
141
141
|
=> 2
|
142
142
|
|
143
|
-
@node.
|
143
|
+
@node.to_bip32(:private)
|
144
144
|
=> "xprv9ww7sMFLzJN15m7zX5JEBXQrQq8h4fU8PVqd929Hjy3xNSMzeBf163idMNBSq47DdCakyZTK7KcC2nbz3jqUkpJj8ZR4FqrijcFcFmcoBAe"
|
145
145
|
|
146
|
-
@node.
|
146
|
+
@node.to_bip32
|
147
147
|
=> "xpub6AvUGrnEpfvJJFCTd6qEYfMaxryBU8BykimDwQYuJJawFEh9BiyFdr37Cc4wEKCWWv7TsFQRUMdezXVqV9cfBUbeUEgNYCCP4omxULbNaRr"
|
148
148
|
```
|
149
149
|
|
@@ -164,22 +164,22 @@ Because we need multiple pieces of info to reconstruct nodes in a tree, when we'
|
|
164
164
|
```
|
165
165
|
|
166
166
|
In addition to the key and the chain code, this encoding also includes info about the depth and index of the key, along with a fingerprint of its parent key (which I presume is for quickly sorting a big pile of keys into a tree).
|
167
|
-
|
167
|
+
|
168
168
|
These are the addresses that you should use to represent each node in the tree structure, however these are NOT the bitcoin addresses you should pass around for receiving money. These are more for storing inside a wallet file so that you can reconstruct the tree.
|
169
169
|
|
170
170
|
To export a node to a serialized address, you can do:
|
171
171
|
|
172
172
|
```ruby
|
173
|
-
@node.
|
173
|
+
@node.to_bip32(:private) # for private keys
|
174
174
|
=> "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"
|
175
175
|
|
176
|
-
@node.
|
176
|
+
@node.to_bip32
|
177
177
|
=> "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"
|
178
178
|
```
|
179
|
-
|
179
|
+
|
180
180
|
To import from a serialized address: (either public or private)
|
181
181
|
```ruby
|
182
|
-
@node = MoneyTree::Node.
|
182
|
+
@node = MoneyTree::Node.from_bip32 "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi"
|
183
183
|
=> MoneyTree::Node instance
|
184
184
|
```
|
185
185
|
|
@@ -198,10 +198,10 @@ For example:
|
|
198
198
|
```ruby
|
199
199
|
@node = @master.node_for_path("M/0/3") # or "m/0/3.pub" or "M/0/3.pub"...these are equivalent
|
200
200
|
|
201
|
-
@node.
|
201
|
+
@node.to_bip32
|
202
202
|
=> "xpub6AvUGrnEpfvJJFCTd6qEYfMaxryBU8BykimDwQYuJJawFEh9BiyFdr37Cc4wEKCWWv7TsFQRUMdezXVqV9cfBUbeUEgNYCCP4omxULbNaRr"
|
203
203
|
|
204
|
-
@node.
|
204
|
+
@node.to_bip32(:private)
|
205
205
|
-> raises MoneyTree::Node::PrivatePublicMismatch error
|
206
206
|
```
|
207
207
|
|
@@ -209,13 +209,13 @@ For example:
|
|
209
209
|
You can also import a node using only a public key. Keep in mind that this node will only be able to generate other public-key only nodes. You will not be able to derive child private keys using this node.
|
210
210
|
|
211
211
|
```ruby
|
212
|
-
@node = MoneyTree::Node.
|
212
|
+
@node = MoneyTree::Node.from_bip32("xpub6AvUGrnEpfvJJFCTd6qEYfMaxryBU8BykimDwQYuJJawFEh9BiyFdr37Cc4wEKCWWv7TsFQRUMdezXVqV9cfBUbeUEgNYCCP4omxULbNaRr")
|
213
213
|
=> MoneyTree::Node instance
|
214
214
|
|
215
|
-
@node.
|
215
|
+
@node.to_bip32
|
216
216
|
=> "xpub6AvUGrnEpfvJJFCTd6qEYfMaxryBU8BykimDwQYuJJawFEh9BiyFdr37Cc4wEKCWWv7TsFQRUMdezXVqV9cfBUbeUEgNYCCP4omxULbNaRr"
|
217
217
|
|
218
|
-
@node.
|
218
|
+
@node.to_bip32(:private)
|
219
219
|
-> raises MoneyTree::Node::PrivatePublicMismatch error
|
220
220
|
```
|
221
221
|
|
@@ -241,7 +241,7 @@ For instance:
|
|
241
241
|
|
242
242
|
They are all equivalent ways of saying the same thing, but the first two are just a more human readable shorthand notation. You are free to use whichever notation you prefer. This gem will parse it.
|
243
243
|
|
244
|
-
To add just a little more confusion to the mix, some wallets will use negative `i` values to also denote private derivation. Any `i` value that is negative will be processed using private derivation by this library. e.g. `"m/-1/1"`.
|
244
|
+
To add just a little more confusion to the mix, some wallets will use negative `i` values to also denote private derivation. Any `i` value that is negative will be processed using private derivation by this library. e.g. `"m/-1/1"`. (NOTE: known issue, see below)
|
245
245
|
|
246
246
|
|
247
247
|
## Contributing
|
@@ -251,3 +251,8 @@ To add just a little more confusion to the mix, some wallets will use negative `
|
|
251
251
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
252
252
|
4. Push to the branch (`git push origin my-new-feature`)
|
253
253
|
5. Create new Pull Request
|
254
|
+
|
255
|
+
## Known Issues (PRs welcome)
|
256
|
+
|
257
|
+
- Segwit ([BIP49](https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki)) address generation is not supported
|
258
|
+
- Use of negative integers in paths does _not_ produce the correct hardened derivation.
|
@@ -0,0 +1,24 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIEHDCCAoSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFtYXR0
|
3
|
+
L0RDPWdlbS9EQz1jbzAeFw0xODA1MzAyMTQwNDZaFw0xOTA1MzAyMTQwNDZaMBwx
|
4
|
+
GjAYBgNVBAMMEW1hdHQvREM9Z2VtL0RDPWNvMIIBojANBgkqhkiG9w0BAQEFAAOC
|
5
|
+
AY8AMIIBigKCAYEAxfbjMHFlxA2P+4YWPagKoGAMi4078imgXdFbD3Rloe6cGfYp
|
6
|
+
IMUQitiHrKi6fhSE0UjXmoP3qnYFddm1enN9zUAFRhHWv7xpINqSqss4PYAb5Anl
|
7
|
+
RYZu3jromop5aVodi15HUfu5z27MvBm4rAaN/dDRfh/rT2hDbTTh0HmvEaPUDfX6
|
8
|
+
TyflAttfabFvtY4qsD+ao8tks0DytqyuEWZ0tvQ6upOgHRNNuYDwDZB1T9v2dq2w
|
9
|
+
3goJFmOKBMMn7UH8WMjD3HiOuRD4tWhq5xWLjBqjzFlVPlZPgdCNyXeMMnLXER98
|
10
|
+
NY35cVWFFuqG+kZwy4MFKdE9WFTocLZxLFo0VVTNSpPara9HirbHtIo9jZNuop4S
|
11
|
+
g4JTf1F8dIWYii3sXoAYZfkl6rHVRP0G/OV5LcTfSS3QkmI5hNltz5FZzc+qI6S1
|
12
|
+
rTR1ZwTy1rRI3coFY7vDRaFWBoMbbo/DytgCE3+rfbVDxQrJa4aZ0iYDhu8LXEA1
|
13
|
+
VTtpf1EWYCOsYE1TAgMBAAGjaTBnMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0G
|
14
|
+
A1UdDgQWBBQ6QoDNre7LFgOukH2Cv+RqZyfUzjAWBgNVHREEDzANgQttYXR0QGdl
|
15
|
+
bS5jbzAWBgNVHRIEDzANgQttYXR0QGdlbS5jbzANBgkqhkiG9w0BAQsFAAOCAYEA
|
16
|
+
kOxYnOsB+NwHwLc2lHEZ8ubxanq2qIZDhvVQ4M31gwmba43xO7vq0ktFxYRvozs4
|
17
|
+
74dQ6bmY2e7njoFgeutyJwxulA+BC71mDQA1s4WsZo7Z2TRgB0GViVqHrzq+jY+M
|
18
|
+
p9mTHQqKH+2j0P9T4DXSzq4qOaBA3YROAwAzYI9N8MObeWkRt2pZ4zYQrAniP2nd
|
19
|
+
wzXs/G5lWbbntVcvQOfAAXBipSJ3X5P2EGpUytP9ZpGdezY5HZzuiJFcmCf1CM3t
|
20
|
+
VX4NZjbJak9gOY0AFD0Aw497sYenm0VBExclOmeRuZLffpWteTTL//utpG3bbFPl
|
21
|
+
jQ78uzsrexYTYW5IshjfSIf3TZxm50Z45pyOTow5EOP1Nd7OmKOcI8hrLGv5+AlD
|
22
|
+
hCnomUTUNsM4Rjwl5rzQiIn3ezv6+0tlg4rWJmVTuOGwcHk/oj1In2sPjCqm0pgx
|
23
|
+
TLnMa8gr6aUpuHR5s2N4ZH0Q2YIsaD6cv7DYXt+G4MRut3njOYHfkqsSVykO6hvr
|
24
|
+
-----END CERTIFICATE-----
|
@@ -0,0 +1 @@
|
|
1
|
+
ce3c7dc0fe6817aee65f990c7a97f89fd36c94380ac804c7579554d665a934df99d4e72ee9b2e467efcc76799a20c4d1de4c950bbba3512d42260c38a46e54b9
|
data/lib/money-tree/key.rb
CHANGED
@@ -7,12 +7,12 @@ module MoneyTree
|
|
7
7
|
include OpenSSL
|
8
8
|
include Support
|
9
9
|
extend Support
|
10
|
-
class KeyInvalid <
|
11
|
-
class KeyGenerationFailure <
|
12
|
-
class KeyImportFailure <
|
13
|
-
class KeyFormatNotFound <
|
14
|
-
class InvalidWIFFormat <
|
15
|
-
class InvalidBase64Format <
|
10
|
+
class KeyInvalid < StandardError; end
|
11
|
+
class KeyGenerationFailure < StandardError; end
|
12
|
+
class KeyImportFailure < StandardError; end
|
13
|
+
class KeyFormatNotFound < StandardError; end
|
14
|
+
class InvalidWIFFormat < StandardError; end
|
15
|
+
class InvalidBase64Format < StandardError; end
|
16
16
|
|
17
17
|
attr_reader :options, :key, :raw_key
|
18
18
|
attr_accessor :ec_key
|
@@ -70,7 +70,7 @@ module MoneyTree
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def parse_raw_key
|
73
|
-
result = if raw_key.is_a?(
|
73
|
+
result = if raw_key.is_a?(Integer) then from_integer
|
74
74
|
elsif hex_format? then from_hex
|
75
75
|
elsif base64_format? then from_base64
|
76
76
|
elsif compressed_wif_format? then from_wif
|
@@ -81,7 +81,7 @@ module MoneyTree
|
|
81
81
|
result.downcase
|
82
82
|
end
|
83
83
|
|
84
|
-
def
|
84
|
+
def from_integer(bignum = raw_key)
|
85
85
|
# TODO: does this need a byte size specification?
|
86
86
|
int_to_hex(bignum)
|
87
87
|
end
|
@@ -213,7 +213,7 @@ module MoneyTree
|
|
213
213
|
end
|
214
214
|
|
215
215
|
def parse_raw_key
|
216
|
-
result = if raw_key.is_a?(
|
216
|
+
result = if raw_key.is_a?(Integer)
|
217
217
|
set_point raw_key
|
218
218
|
elsif hex_format?
|
219
219
|
set_point hex_to_int(raw_key), compressed: false
|
data/lib/money-tree/node.rb
CHANGED
@@ -5,10 +5,10 @@ module MoneyTree
|
|
5
5
|
attr_reader :private_key, :public_key, :chain_code,
|
6
6
|
:is_private, :depth, :index, :parent
|
7
7
|
|
8
|
-
class PublicDerivationFailure <
|
9
|
-
class InvalidKeyForIndex <
|
10
|
-
class ImportError <
|
11
|
-
class PrivatePublicMismatch <
|
8
|
+
class PublicDerivationFailure < StandardError; end
|
9
|
+
class InvalidKeyForIndex < StandardError; end
|
10
|
+
class ImportError < StandardError; end
|
11
|
+
class PrivatePublicMismatch < StandardError; end
|
12
12
|
|
13
13
|
def initialize(opts = {})
|
14
14
|
opts.each { |k, v| instance_variable_set "@#{k}", v }
|
data/lib/money-tree/version.rb
CHANGED
data/lib/openssl_extensions.rb
CHANGED
data/money-tree.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["winkelspecht@gmail.com"]
|
11
11
|
spec.description = %q{A Ruby Gem implementation of Bitcoin HD Wallets}
|
12
12
|
spec.summary = %q{Bitcoin Hierarchical Deterministic Wallets in Ruby! (Bitcoin standard BIP0032)}
|
13
|
-
spec.homepage = ""
|
13
|
+
spec.homepage = "https://github.com/gemhq/money-tree"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
@@ -18,8 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
# used with gem
|
22
|
-
spec.cert_chain = ["certs/
|
21
|
+
# used with gem install ... -P HighSecurity
|
22
|
+
spec.cert_chain = ["certs/mattatgemco.pem"]
|
23
23
|
# Sign gem when evaluating spec with `gem` command
|
24
24
|
# unless ENV has set a SKIP_GEM_SIGNING
|
25
25
|
if ($0 =~ /gem\z/) and not ENV.include?("SKIP_GEM_SIGNING")
|
@@ -7,7 +7,7 @@ describe MoneyTree::Master do
|
|
7
7
|
before do
|
8
8
|
@master = MoneyTree::Master.new
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
it "generates a random seed 32 bytes long" do
|
12
12
|
expect(@master.seed.bytesize).to eql(32)
|
13
13
|
end
|
@@ -36,37 +36,37 @@ describe MoneyTree::Master do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it "generates testnet serialized private address" do
|
39
|
-
expect(@master.
|
39
|
+
expect(@master.to_bip32(:private, network: :bitcoin_testnet).slice(0, 4)).to eql("tprv")
|
40
40
|
end
|
41
41
|
|
42
42
|
it "generates testnet serialized public address" do
|
43
|
-
expect(@master.
|
43
|
+
expect(@master.to_bip32(network: :bitcoin_testnet).slice(0, 4)).to eql("tpub")
|
44
44
|
end
|
45
45
|
|
46
46
|
it "imports from testnet serialized private address" do
|
47
|
-
node = MoneyTree::Node.
|
48
|
-
expect(node.
|
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.
|
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.
|
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.
|
58
|
+
node = MoneyTree::Node.from_bip32 'tprv8ZgxMBicQKsPcuN7bfUZqq78UEYapr3Tzmc9NcDXw8BnBJ47dZYr6SusnfYj7vbAYP9CP8ZiD5aVBTUo1yU5QP56mepKVvuEbu8KZQXMKNE'
|
59
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.
|
62
|
-
expect(subnode.
|
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.
|
66
|
+
node = MoneyTree::Node.from_bip32 'tpubD6NzVbkrYhZ4YA8aUE9bBZTSyHJibBqwDny5urfwDdJc4W8od3y3Ebzy6CqsYn9CCC5P5VQ7CeZYpnT1kX3RPVPysU2rFRvYSj8BCoYYNqT'
|
67
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.
|
69
|
+
expect(subnode.to_bip32(network: :bitcoin_testnet).slice(0,4)).to eql('tpub')
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -75,349 +75,349 @@ describe MoneyTree::Master do
|
|
75
75
|
before do
|
76
76
|
@master = MoneyTree::Master.new seed_hex: "000102030405060708090a0b0c0d0e0f"
|
77
77
|
end
|
78
|
-
|
78
|
+
|
79
79
|
describe "m" do
|
80
80
|
it "has an index of 0" do
|
81
81
|
expect(@master.index).to eql(0)
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
it "is private" do
|
85
85
|
expect(@master.is_private?).to eql(true)
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
it "has a depth of 0" do
|
89
89
|
expect(@master.depth).to eql(0)
|
90
90
|
end
|
91
|
-
|
91
|
+
|
92
92
|
it "generates master node (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
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
it "generates a secret key" do
|
99
99
|
expect(@master.private_key.to_hex).to eql("e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35")
|
100
100
|
expect(@master.private_key.to_wif).to eql("L52XzL2cMkHxqxBXRyEpnPQZGUs3uKiL3R11XbAdHigRzDozKZeW")
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
it "generates a public key" do
|
104
104
|
expect(@master.public_key.to_hex).to eql("0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2")
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
it "generates a chain code" do
|
108
108
|
expect(@master.chain_code_hex).to eql("873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508")
|
109
109
|
end
|
110
|
-
|
110
|
+
|
111
111
|
it "generates a serialized private key" do
|
112
112
|
expect(@master.to_serialized_hex(:private)).to eql("0488ade4000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d50800e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35")
|
113
|
-
expect(@master.
|
113
|
+
expect(@master.to_bip32(:private)).to eql("xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi")
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
it "generates a serialized public_key" do
|
117
117
|
expect(@master.to_serialized_hex).to eql("0488b21e000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d5080339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2")
|
118
|
-
expect(@master.
|
118
|
+
expect(@master.to_bip32).to eql("xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8")
|
119
119
|
end
|
120
120
|
end
|
121
|
-
|
121
|
+
|
122
122
|
describe "m/0p" do
|
123
123
|
before do
|
124
124
|
@node = @master.node_for_path "m/0p"
|
125
125
|
end
|
126
|
-
|
126
|
+
|
127
127
|
it "has an index of 2147483648" do
|
128
128
|
expect(@node.index).to eql(2147483648)
|
129
129
|
end
|
130
|
-
|
130
|
+
|
131
131
|
it "is private" do
|
132
132
|
expect(@node.is_private?).to eql(true)
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
it "has a depth of 1" do
|
136
136
|
expect(@node.depth).to eql(1)
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
it "generates subnode" do
|
140
140
|
expect(@node.to_identifier).to eql("5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7")
|
141
141
|
expect(@node.to_fingerprint).to eql("5c1bd648")
|
142
142
|
expect(@node.to_address).to eql("19Q2WoS5hSS6T8GjhK8KZLMgmWaq4neXrh")
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
it "generates a private key" do
|
146
146
|
expect(@node.private_key.to_hex).to eql("edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea")
|
147
147
|
expect(@node.private_key.to_wif).to eql("L5BmPijJjrKbiUfG4zbiFKNqkvuJ8usooJmzuD7Z8dkRoTThYnAT")
|
148
148
|
end
|
149
|
-
|
149
|
+
|
150
150
|
it "generates a public key" do
|
151
151
|
expect(@node.public_key.to_hex).to eql("035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56")
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
it "generates a chain code" do
|
155
155
|
expect(@node.chain_code_hex).to eql("47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141")
|
156
156
|
end
|
157
|
-
|
157
|
+
|
158
158
|
it "generates a serialized private key" do
|
159
159
|
expect(@node.to_serialized_hex(:private)).to eql("0488ade4013442193e8000000047fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae623614100edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea")
|
160
|
-
expect(@node.
|
160
|
+
expect(@node.to_bip32(:private)).to eql("xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7")
|
161
161
|
end
|
162
|
-
|
162
|
+
|
163
163
|
it "generates a serialized public_key" do
|
164
164
|
expect(@node.to_serialized_hex).to eql("0488b21e013442193e8000000047fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56")
|
165
|
-
expect(@node.
|
165
|
+
expect(@node.to_bip32).to eql("xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw")
|
166
166
|
end
|
167
167
|
end
|
168
|
-
|
168
|
+
|
169
169
|
describe "m/0p.pub" do
|
170
170
|
before do
|
171
171
|
@node = @master.node_for_path "m/0p.pub"
|
172
172
|
end
|
173
|
-
|
173
|
+
|
174
174
|
it "has an index of 2147483648" do
|
175
175
|
expect(@node.index).to eql(2147483648)
|
176
176
|
end
|
177
|
-
|
177
|
+
|
178
178
|
it "is private" do
|
179
179
|
expect(@node.is_private?).to eql(true)
|
180
180
|
end
|
181
|
-
|
181
|
+
|
182
182
|
it "has a depth of 1" do
|
183
183
|
expect(@node.depth).to eql(1)
|
184
184
|
end
|
185
|
-
|
185
|
+
|
186
186
|
it "generates subnode" do
|
187
187
|
expect(@node.to_identifier).to eql("5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7")
|
188
188
|
expect(@node.to_fingerprint).to eql("5c1bd648")
|
189
189
|
expect(@node.to_address).to eql("19Q2WoS5hSS6T8GjhK8KZLMgmWaq4neXrh")
|
190
190
|
end
|
191
|
-
|
191
|
+
|
192
192
|
it "does not generate a private key" do
|
193
193
|
expect(@node.private_key).to be_nil
|
194
194
|
end
|
195
|
-
|
195
|
+
|
196
196
|
it "generates a public key" do
|
197
197
|
expect(@node.public_key.to_hex).to eql("035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56")
|
198
198
|
end
|
199
|
-
|
199
|
+
|
200
200
|
it "generates a chain code" do
|
201
201
|
expect(@node.chain_code_hex).to eql("47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141")
|
202
202
|
end
|
203
|
-
|
203
|
+
|
204
204
|
it "does not generate a serialized private key" do
|
205
205
|
expect { @node.to_serialized_hex(:private) }.to raise_error(MoneyTree::Node::PrivatePublicMismatch)
|
206
206
|
end
|
207
|
-
|
207
|
+
|
208
208
|
it "generates a serialized public_key" do
|
209
209
|
expect(@node.to_serialized_hex).to eql("0488b21e013442193e8000000047fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56")
|
210
|
-
expect(@node.
|
210
|
+
expect(@node.to_bip32).to eql("xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw")
|
211
211
|
end
|
212
212
|
end
|
213
|
-
|
213
|
+
|
214
214
|
describe "m/0'/1" do
|
215
215
|
before do
|
216
216
|
@node = @master.node_for_path "m/0'/1"
|
217
217
|
end
|
218
|
-
|
218
|
+
|
219
219
|
it "has an index of 1" do
|
220
220
|
expect(@node.index).to eql(1)
|
221
221
|
end
|
222
|
-
|
222
|
+
|
223
223
|
it "is public" do
|
224
224
|
expect(@node.is_private?).to eql(false)
|
225
225
|
end
|
226
|
-
|
226
|
+
|
227
227
|
it "has a depth of 2" do
|
228
228
|
expect(@node.depth).to eql(2)
|
229
229
|
end
|
230
|
-
|
230
|
+
|
231
231
|
it "generates subnode" do
|
232
232
|
expect(@node.to_identifier).to eql("bef5a2f9a56a94aab12459f72ad9cf8cf19c7bbe")
|
233
233
|
expect(@node.to_fingerprint).to eql("bef5a2f9")
|
234
234
|
expect(@node.to_address).to eql("1JQheacLPdM5ySCkrZkV66G2ApAXe1mqLj")
|
235
235
|
end
|
236
|
-
|
236
|
+
|
237
237
|
it "generates a private key" do
|
238
238
|
expect(@node.private_key.to_hex).to eql("3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368")
|
239
239
|
expect(@node.private_key.to_wif).to eql("KyFAjQ5rgrKvhXvNMtFB5PCSKUYD1yyPEe3xr3T34TZSUHycXtMM")
|
240
240
|
end
|
241
|
-
|
241
|
+
|
242
242
|
it "generates a public key" do
|
243
243
|
expect(@node.public_key.to_hex).to eql("03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c")
|
244
244
|
end
|
245
|
-
|
245
|
+
|
246
246
|
it "generates a chain code" do
|
247
247
|
expect(@node.chain_code_hex).to eql("2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19")
|
248
248
|
end
|
249
|
-
|
249
|
+
|
250
250
|
it "generates a serialized private key" do
|
251
251
|
expect(@node.to_serialized_hex(:private)).to eql("0488ade4025c1bd648000000012a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19003c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368")
|
252
|
-
expect(@node.
|
252
|
+
expect(@node.to_bip32(:private)).to eql("xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs")
|
253
253
|
end
|
254
|
-
|
254
|
+
|
255
255
|
it "generates a serialized public_key" do
|
256
256
|
expect(@node.to_serialized_hex).to eql("0488b21e025c1bd648000000012a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c1903501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c")
|
257
|
-
expect(@node.
|
257
|
+
expect(@node.to_bip32).to eql("xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ")
|
258
258
|
end
|
259
259
|
end
|
260
|
-
|
260
|
+
|
261
261
|
describe "M/0'/1" do
|
262
262
|
before do
|
263
263
|
@node = @master.node_for_path "M/0'/1"
|
264
264
|
end
|
265
|
-
|
265
|
+
|
266
266
|
it "has an index of 1" do
|
267
267
|
expect(@node.index).to eql(1)
|
268
268
|
end
|
269
|
-
|
269
|
+
|
270
270
|
it "is public" do
|
271
271
|
expect(@node.is_private?).to eql(false)
|
272
272
|
end
|
273
|
-
|
273
|
+
|
274
274
|
it "has a depth of 2" do
|
275
275
|
expect(@node.depth).to eql(2)
|
276
276
|
end
|
277
|
-
|
277
|
+
|
278
278
|
it "generates subnode" do
|
279
279
|
expect(@node.to_identifier).to eql("bef5a2f9a56a94aab12459f72ad9cf8cf19c7bbe")
|
280
280
|
expect(@node.to_fingerprint).to eql("bef5a2f9")
|
281
281
|
expect(@node.to_address).to eql("1JQheacLPdM5ySCkrZkV66G2ApAXe1mqLj")
|
282
282
|
end
|
283
|
-
|
283
|
+
|
284
284
|
it "does not generate a private key" do
|
285
285
|
expect(@node.private_key).to be_nil
|
286
286
|
end
|
287
|
-
|
287
|
+
|
288
288
|
it "generates a public key" do
|
289
289
|
expect(@node.public_key.to_hex).to eql("03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c")
|
290
290
|
end
|
291
|
-
|
291
|
+
|
292
292
|
it "generates a chain code" do
|
293
293
|
expect(@node.chain_code_hex).to eql("2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19")
|
294
294
|
end
|
295
|
-
|
295
|
+
|
296
296
|
it "generates a serialized private key" do
|
297
297
|
expect { @node.to_serialized_hex(:private) }.to raise_error(MoneyTree::Node::PrivatePublicMismatch)
|
298
298
|
end
|
299
|
-
|
299
|
+
|
300
300
|
it "generates a serialized public_key" do
|
301
301
|
expect(@node.to_serialized_hex).to eql("0488b21e025c1bd648000000012a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c1903501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c")
|
302
|
-
expect(@node.
|
302
|
+
expect(@node.to_bip32).to eql("xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ")
|
303
303
|
end
|
304
304
|
end
|
305
|
-
|
305
|
+
|
306
306
|
describe "m/0'/1/2p/2" do
|
307
307
|
before do
|
308
308
|
@node = @master.node_for_path "m/0'/1/2p/2"
|
309
309
|
end
|
310
|
-
|
310
|
+
|
311
311
|
it "has an index of 2" do
|
312
312
|
expect(@node.index).to eql(2)
|
313
313
|
end
|
314
|
-
|
314
|
+
|
315
315
|
it "is public" do
|
316
316
|
expect(@node.is_private?).to eql(false)
|
317
317
|
end
|
318
|
-
|
318
|
+
|
319
319
|
it "has a depth of 4" do
|
320
320
|
expect(@node.depth).to eql(4)
|
321
321
|
end
|
322
|
-
|
322
|
+
|
323
323
|
it "generates subnode" do
|
324
324
|
expect(@node.to_identifier).to eql("d880d7d893848509a62d8fb74e32148dac68412f")
|
325
325
|
expect(@node.to_fingerprint).to eql("d880d7d8")
|
326
326
|
expect(@node.to_address).to eql("1LjmJcdPnDHhNTUgrWyhLGnRDKxQjoxAgt")
|
327
327
|
end
|
328
|
-
|
328
|
+
|
329
329
|
it "generates a private key" do
|
330
330
|
expect(@node.private_key.to_hex).to eql("0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4")
|
331
331
|
expect(@node.private_key.to_wif).to eql("KwjQsVuMjbCP2Zmr3VaFaStav7NvevwjvvkqrWd5Qmh1XVnCteBR")
|
332
332
|
end
|
333
|
-
|
333
|
+
|
334
334
|
it "generates a public key" do
|
335
335
|
expect(@node.public_key.to_hex).to eql("02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29")
|
336
336
|
end
|
337
|
-
|
337
|
+
|
338
338
|
it "generates a chain code" do
|
339
339
|
expect(@node.chain_code_hex).to eql("cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd")
|
340
340
|
end
|
341
|
-
|
341
|
+
|
342
342
|
it "generates a serialized private key" do
|
343
343
|
expect(@node.to_serialized_hex(:private)).to eql("0488ade404ee7ab90c00000002cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd000f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4")
|
344
|
-
expect(@node.
|
344
|
+
expect(@node.to_bip32(:private)).to eql("xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334")
|
345
345
|
end
|
346
|
-
|
346
|
+
|
347
347
|
it "generates a serialized public_key" do
|
348
348
|
expect(@node.to_serialized_hex).to eql("0488b21e04ee7ab90c00000002cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29")
|
349
|
-
expect(@node.
|
349
|
+
expect(@node.to_bip32).to eql("xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV")
|
350
350
|
end
|
351
351
|
end
|
352
|
-
|
352
|
+
|
353
353
|
describe "m/0'/1/2'/2/1000000000" do
|
354
354
|
before do
|
355
355
|
@node = @master.node_for_path "m/0'/1/2'/2/1000000000"
|
356
356
|
end
|
357
|
-
|
357
|
+
|
358
358
|
it "has an index of 1000000000" do
|
359
359
|
expect(@node.index).to eql(1000000000)
|
360
360
|
end
|
361
|
-
|
361
|
+
|
362
362
|
it "is public" do
|
363
363
|
expect(@node.is_private?).to eql(false)
|
364
364
|
end
|
365
|
-
|
365
|
+
|
366
366
|
it "has a depth of 2" do
|
367
367
|
expect(@node.depth).to eql(5)
|
368
368
|
end
|
369
|
-
|
369
|
+
|
370
370
|
it "generates subnode" do
|
371
371
|
expect(@node.to_identifier).to eql("d69aa102255fed74378278c7812701ea641fdf32")
|
372
372
|
expect(@node.to_fingerprint).to eql("d69aa102")
|
373
373
|
expect(@node.to_address).to eql("1LZiqrop2HGR4qrH1ULZPyBpU6AUP49Uam")
|
374
374
|
end
|
375
|
-
|
375
|
+
|
376
376
|
it "generates a private key" do
|
377
377
|
expect(@node.private_key.to_hex).to eql("471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8")
|
378
378
|
expect(@node.private_key.to_wif).to eql("Kybw8izYevo5xMh1TK7aUr7jHFCxXS1zv8p3oqFz3o2zFbhRXHYs")
|
379
379
|
end
|
380
|
-
|
380
|
+
|
381
381
|
it "generates a public key" do
|
382
382
|
expect(@node.public_key.to_hex).to eql("022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011")
|
383
383
|
end
|
384
|
-
|
384
|
+
|
385
385
|
it "generates a chain code" do
|
386
386
|
expect(@node.chain_code_hex).to eql("c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e")
|
387
387
|
end
|
388
|
-
|
388
|
+
|
389
389
|
it "generates a serialized private key" do
|
390
390
|
expect(@node.to_serialized_hex(:private)).to eql("0488ade405d880d7d83b9aca00c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e00471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8")
|
391
|
-
expect(@node.
|
391
|
+
expect(@node.to_bip32(:private)).to eql("xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76")
|
392
392
|
end
|
393
|
-
|
393
|
+
|
394
394
|
it "generates a serialized public_key" do
|
395
395
|
expect(@node.to_serialized_hex).to eql("0488b21e05d880d7d83b9aca00c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011")
|
396
|
-
expect(@node.
|
396
|
+
expect(@node.to_bip32).to eql("xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy")
|
397
397
|
end
|
398
398
|
end
|
399
399
|
end
|
400
400
|
end
|
401
|
-
|
401
|
+
|
402
402
|
describe "Test vector 2" do
|
403
403
|
describe "from a seed" do
|
404
404
|
before do
|
405
405
|
@master = MoneyTree::Master.new seed_hex: "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"
|
406
406
|
end
|
407
|
-
|
407
|
+
|
408
408
|
describe "m" do
|
409
409
|
it "has an index of 0" do
|
410
410
|
expect(@master.index).to eql(0)
|
411
411
|
end
|
412
|
-
|
412
|
+
|
413
413
|
it "has a depth of 0" do
|
414
414
|
expect(@master.depth).to eql(0)
|
415
415
|
end
|
416
|
-
|
416
|
+
|
417
417
|
it "is private" do
|
418
418
|
expect(@master.is_private?).to eql(true)
|
419
419
|
end
|
420
|
-
|
420
|
+
|
421
421
|
it "generates master node (Master)" do
|
422
422
|
expect(@master.to_identifier).to eql("bd16bee53961a47d6ad888e29545434a89bdfe95")
|
423
423
|
expect(@master.to_fingerprint).to eql("bd16bee5")
|
@@ -434,71 +434,71 @@ describe MoneyTree::Master do
|
|
434
434
|
expect(@master.private_key.to_hex).to eql("4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e")
|
435
435
|
expect(@master.private_key.to_wif).to eql("KyjXhyHF9wTphBkfpxjL8hkDXDUSbE3tKANT94kXSyh6vn6nKaoy")
|
436
436
|
end
|
437
|
-
|
437
|
+
|
438
438
|
it "generates a public key" do
|
439
439
|
expect(@master.public_key.to_hex).to eql("03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7")
|
440
440
|
end
|
441
|
-
|
441
|
+
|
442
442
|
it "generates a chain code" do
|
443
443
|
expect(@master.chain_code_hex).to eql("60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689")
|
444
444
|
end
|
445
|
-
|
445
|
+
|
446
446
|
it "generates a serialized private key" do
|
447
447
|
expect(@master.to_serialized_hex(:private)).to eql("0488ade400000000000000000060499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689004b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e")
|
448
|
-
expect(@master.
|
448
|
+
expect(@master.to_bip32(:private)).to eql("xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U")
|
449
449
|
end
|
450
|
-
|
450
|
+
|
451
451
|
it "generates a serialized public_key" do
|
452
452
|
expect(@master.to_serialized_hex).to eql("0488b21e00000000000000000060499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd968903cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7")
|
453
|
-
expect(@master.
|
453
|
+
expect(@master.to_bip32).to eql("xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB")
|
454
454
|
end
|
455
455
|
end
|
456
|
-
|
456
|
+
|
457
457
|
describe "m/0 (testing imported private key)" do
|
458
458
|
before do
|
459
459
|
@master = MoneyTree::Master.new private_key: @master.private_key, chain_code: @master.chain_code
|
460
460
|
@node = @master.node_for_path "m/0"
|
461
461
|
end
|
462
|
-
|
462
|
+
|
463
463
|
it "has an index of 0" do
|
464
464
|
expect(@node.index).to eql(0)
|
465
465
|
end
|
466
|
-
|
466
|
+
|
467
467
|
it "has a depth of 1" do
|
468
468
|
expect(@node.depth).to eql(1)
|
469
469
|
end
|
470
|
-
|
470
|
+
|
471
471
|
it "is public" do
|
472
472
|
expect(@node.is_private?).to eql(false)
|
473
473
|
end
|
474
|
-
|
474
|
+
|
475
475
|
it "generates subnode" do
|
476
476
|
expect(@node.to_identifier).to eql("5a61ff8eb7aaca3010db97ebda76121610b78096")
|
477
477
|
expect(@node.to_fingerprint).to eql("5a61ff8e")
|
478
478
|
expect(@node.to_address).to eql("19EuDJdgfRkwCmRzbzVBHZWQG9QNWhftbZ")
|
479
479
|
end
|
480
|
-
|
480
|
+
|
481
481
|
it "generates a private key" do
|
482
482
|
expect(@node.private_key.to_hex).to eql("abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e")
|
483
483
|
expect(@node.private_key.to_wif).to eql("L2ysLrR6KMSAtx7uPqmYpoTeiRzydXBattRXjXz5GDFPrdfPzKbj")
|
484
484
|
end
|
485
|
-
|
485
|
+
|
486
486
|
it "generates a public key" do
|
487
487
|
expect(@node.public_key.to_hex).to eql("02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea")
|
488
488
|
end
|
489
|
-
|
489
|
+
|
490
490
|
it "generates a chain code" do
|
491
491
|
expect(@node.chain_code_hex).to eql("f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c")
|
492
492
|
end
|
493
|
-
|
493
|
+
|
494
494
|
it "generates a serialized private key" do
|
495
495
|
expect(@node.to_serialized_hex(:private)).to eql("0488ade401bd16bee500000000f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c00abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e")
|
496
|
-
expect(@node.
|
496
|
+
expect(@node.to_bip32(:private)).to eql("xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt")
|
497
497
|
end
|
498
|
-
|
498
|
+
|
499
499
|
it "generates a serialized public_key" do
|
500
500
|
expect(@node.to_serialized_hex).to eql("0488b21e01bd16bee500000000f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea")
|
501
|
-
expect(@node.
|
501
|
+
expect(@node.to_bip32).to eql("xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH")
|
502
502
|
end
|
503
503
|
end
|
504
504
|
|
@@ -507,271 +507,271 @@ describe MoneyTree::Master do
|
|
507
507
|
@master = MoneyTree::Master.new public_key: "03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7", chain_code: @master.chain_code
|
508
508
|
@node = @master.node_for_path "M/0"
|
509
509
|
end
|
510
|
-
|
510
|
+
|
511
511
|
it "has an index of 0" do
|
512
512
|
expect(@node.index).to eql(0)
|
513
513
|
end
|
514
|
-
|
514
|
+
|
515
515
|
it "has a depth of 1" do
|
516
516
|
expect(@node.depth).to eql(1)
|
517
517
|
end
|
518
|
-
|
518
|
+
|
519
519
|
it "is public" do
|
520
520
|
expect(@node.is_private?).to eql(false)
|
521
521
|
end
|
522
|
-
|
522
|
+
|
523
523
|
it "generates subnode" do
|
524
524
|
expect(@node.to_identifier).to eql("5a61ff8eb7aaca3010db97ebda76121610b78096")
|
525
525
|
expect(@node.to_fingerprint).to eql("5a61ff8e")
|
526
526
|
expect(@node.to_address).to eql("19EuDJdgfRkwCmRzbzVBHZWQG9QNWhftbZ")
|
527
527
|
end
|
528
|
-
|
528
|
+
|
529
529
|
it "does not generate a private key" do
|
530
530
|
expect(@node.private_key).to be_nil
|
531
531
|
end
|
532
|
-
|
532
|
+
|
533
533
|
it "generates a public key" do
|
534
534
|
expect(@node.public_key.to_hex).to eql("02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea")
|
535
535
|
end
|
536
|
-
|
536
|
+
|
537
537
|
it "generates a chain code" do
|
538
538
|
expect(@node.chain_code_hex).to eql("f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c")
|
539
539
|
end
|
540
|
-
|
540
|
+
|
541
541
|
it "does not generate a serialized private key" do
|
542
542
|
expect { @node.to_serialized_hex(:private) }.to raise_error(MoneyTree::Node::PrivatePublicMismatch)
|
543
|
-
expect { @node.
|
543
|
+
expect { @node.to_bip32(:private) }.to raise_error(MoneyTree::Node::PrivatePublicMismatch)
|
544
544
|
end
|
545
|
-
|
545
|
+
|
546
546
|
it "generates a serialized public_key" do
|
547
547
|
expect(@node.to_serialized_hex).to eql("0488b21e01bd16bee500000000f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea")
|
548
|
-
expect(@node.
|
548
|
+
expect(@node.to_bip32).to eql("xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH")
|
549
549
|
end
|
550
550
|
end
|
551
|
-
|
551
|
+
|
552
552
|
describe "m/0/2147483647'" do
|
553
553
|
before do
|
554
554
|
@node = @master.node_for_path "m/0/2147483647'"
|
555
555
|
end
|
556
|
-
|
556
|
+
|
557
557
|
it "has an index of 2147483647" do
|
558
558
|
expect(@node.index).to eql(4294967295)
|
559
559
|
end
|
560
|
-
|
560
|
+
|
561
561
|
it "has a depth of 2" do
|
562
562
|
expect(@node.depth).to eql(2)
|
563
563
|
end
|
564
|
-
|
564
|
+
|
565
565
|
it "is private" do
|
566
566
|
expect(@node.is_private?).to eql(true)
|
567
567
|
end
|
568
|
-
|
568
|
+
|
569
569
|
it "generates subnode" do
|
570
570
|
expect(@node.to_identifier).to eql("d8ab493736da02f11ed682f88339e720fb0379d1")
|
571
571
|
expect(@node.to_fingerprint).to eql("d8ab4937")
|
572
572
|
expect(@node.to_address).to eql("1Lke9bXGhn5VPrBuXgN12uGUphrttUErmk")
|
573
573
|
end
|
574
|
-
|
574
|
+
|
575
575
|
it "generates a private key" do
|
576
576
|
expect(@node.private_key.to_hex).to eql("877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93")
|
577
577
|
expect(@node.private_key.to_wif).to eql("L1m5VpbXmMp57P3knskwhoMTLdhAAaXiHvnGLMribbfwzVRpz2Sr")
|
578
578
|
end
|
579
|
-
|
579
|
+
|
580
580
|
it "generates a public key" do
|
581
581
|
expect(@node.public_key.to_hex).to eql("03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b")
|
582
582
|
end
|
583
|
-
|
583
|
+
|
584
584
|
it "generates a chain code" do
|
585
585
|
expect(@node.chain_code_hex).to eql("be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9")
|
586
586
|
end
|
587
|
-
|
587
|
+
|
588
588
|
it "generates a serialized private key" do
|
589
589
|
expect(@node.to_serialized_hex(:private)).to eql("0488ade4025a61ff8effffffffbe17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d900877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93")
|
590
|
-
expect(@node.
|
590
|
+
expect(@node.to_bip32(:private)).to eql("xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9")
|
591
591
|
end
|
592
|
-
|
592
|
+
|
593
593
|
it "generates a serialized public_key" do
|
594
594
|
expect(@node.to_serialized_hex).to eql("0488b21e025a61ff8effffffffbe17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d903c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b")
|
595
|
-
expect(@node.
|
595
|
+
expect(@node.to_bip32).to eql("xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a")
|
596
596
|
end
|
597
597
|
end
|
598
|
-
|
598
|
+
|
599
599
|
describe "m/0/2147483647'/1" do
|
600
600
|
before do
|
601
601
|
@node = @master.node_for_path "m/0/2147483647'/1"
|
602
602
|
end
|
603
|
-
|
603
|
+
|
604
604
|
it "has an index of 1" do
|
605
605
|
expect(@node.index).to eql(1)
|
606
606
|
end
|
607
|
-
|
607
|
+
|
608
608
|
it "has a depth of 3" do
|
609
609
|
expect(@node.depth).to eql(3)
|
610
610
|
end
|
611
|
-
|
611
|
+
|
612
612
|
it "is private" do
|
613
613
|
expect(@node.is_private?).to eql(false)
|
614
614
|
end
|
615
|
-
|
615
|
+
|
616
616
|
it "generates subnode" do
|
617
617
|
expect(@node.to_identifier).to eql("78412e3a2296a40de124307b6485bd19833e2e34")
|
618
618
|
expect(@node.to_fingerprint).to eql("78412e3a")
|
619
619
|
expect(@node.to_address).to eql("1BxrAr2pHpeBheusmd6fHDP2tSLAUa3qsW")
|
620
620
|
end
|
621
|
-
|
621
|
+
|
622
622
|
it "generates a private key" do
|
623
623
|
expect(@node.private_key.to_hex).to eql("704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7")
|
624
624
|
expect(@node.private_key.to_wif).to eql("KzyzXnznxSv249b4KuNkBwowaN3akiNeEHy5FWoPCJpStZbEKXN2")
|
625
625
|
end
|
626
|
-
|
626
|
+
|
627
627
|
it "generates a public key" do
|
628
628
|
expect(@node.public_key.to_hex).to eql("03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9")
|
629
629
|
end
|
630
|
-
|
630
|
+
|
631
631
|
it "generates a chain code" do
|
632
632
|
expect(@node.chain_code_hex).to eql("f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb")
|
633
633
|
end
|
634
|
-
|
634
|
+
|
635
635
|
it "generates a serialized private key" do
|
636
636
|
expect(@node.to_serialized_hex(:private)).to eql("0488ade403d8ab493700000001f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb00704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7")
|
637
|
-
expect(@node.
|
637
|
+
expect(@node.to_bip32(:private)).to eql("xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef")
|
638
638
|
end
|
639
|
-
|
639
|
+
|
640
640
|
it "generates a serialized public_key" do
|
641
641
|
expect(@node.to_serialized_hex).to eql("0488b21e03d8ab493700000001f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9")
|
642
|
-
expect(@node.
|
642
|
+
expect(@node.to_bip32).to eql("xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon")
|
643
643
|
end
|
644
644
|
end
|
645
|
-
|
645
|
+
|
646
646
|
describe "m/0/2147483647p/1/2147483646p" do
|
647
647
|
before do
|
648
648
|
@node = @master.node_for_path "m/0/2147483647p/1/2147483646p"
|
649
649
|
end
|
650
|
-
|
650
|
+
|
651
651
|
it "has an index of 4294967294" do
|
652
652
|
expect(@node.index).to eql(4294967294)
|
653
653
|
end
|
654
|
-
|
654
|
+
|
655
655
|
it "has a depth of 4" do
|
656
656
|
expect(@node.depth).to eql(4)
|
657
657
|
end
|
658
|
-
|
658
|
+
|
659
659
|
it "is private" do
|
660
660
|
expect(@node.is_private?).to eql(true)
|
661
661
|
end
|
662
|
-
|
662
|
+
|
663
663
|
it "generates subnode" do
|
664
664
|
expect(@node.to_identifier).to eql("31a507b815593dfc51ffc7245ae7e5aee304246e")
|
665
665
|
expect(@node.to_fingerprint).to eql("31a507b8")
|
666
666
|
expect(@node.to_address).to eql("15XVotxCAV7sRx1PSCkQNsGw3W9jT9A94R")
|
667
667
|
end
|
668
|
-
|
668
|
+
|
669
669
|
it "generates a private key" do
|
670
670
|
expect(@node.private_key.to_hex).to eql("f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d")
|
671
671
|
expect(@node.private_key.to_wif).to eql("L5KhaMvPYRW1ZoFmRjUtxxPypQ94m6BcDrPhqArhggdaTbbAFJEF")
|
672
672
|
end
|
673
|
-
|
673
|
+
|
674
674
|
it "generates a public key" do
|
675
675
|
expect(@node.public_key.to_hex).to eql("02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0")
|
676
676
|
end
|
677
|
-
|
677
|
+
|
678
678
|
it "generates a chain code" do
|
679
679
|
expect(@node.chain_code_hex).to eql("637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e29")
|
680
680
|
end
|
681
|
-
|
681
|
+
|
682
682
|
it "generates a serialized private key" do
|
683
683
|
expect(@node.to_serialized_hex(:private)).to eql("0488ade40478412e3afffffffe637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e2900f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d")
|
684
|
-
expect(@node.
|
684
|
+
expect(@node.to_bip32(:private)).to eql("xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc")
|
685
685
|
end
|
686
|
-
|
686
|
+
|
687
687
|
it "generates a serialized public_key" do
|
688
688
|
expect(@node.to_serialized_hex).to eql("0488b21e0478412e3afffffffe637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e2902d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0")
|
689
|
-
expect(@node.
|
689
|
+
expect(@node.to_bip32).to eql("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL")
|
690
690
|
end
|
691
691
|
end
|
692
|
-
|
692
|
+
|
693
693
|
describe "m/0/2147483647p/1/2147483646p/2" do
|
694
694
|
before do
|
695
695
|
@node = @master.node_for_path "m/0/2147483647p/1/2147483646p/2"
|
696
696
|
end
|
697
|
-
|
697
|
+
|
698
698
|
it "has an index of 2" do
|
699
699
|
expect(@node.index).to eql(2)
|
700
700
|
end
|
701
|
-
|
701
|
+
|
702
702
|
it "has a depth of 4" do
|
703
703
|
expect(@node.depth).to eql(5)
|
704
704
|
end
|
705
|
-
|
705
|
+
|
706
706
|
it "is public" do
|
707
707
|
expect(@node.is_private?).to eql(false)
|
708
708
|
end
|
709
|
-
|
709
|
+
|
710
710
|
it "generates subnode" do
|
711
711
|
expect(@node.to_identifier).to eql("26132fdbe7bf89cbc64cf8dafa3f9f88b8666220")
|
712
712
|
expect(@node.to_fingerprint).to eql("26132fdb")
|
713
713
|
expect(@node.to_address).to eql("14UKfRV9ZPUp6ZC9PLhqbRtxdihW9em3xt")
|
714
714
|
end
|
715
|
-
|
715
|
+
|
716
716
|
it "generates a private key" do
|
717
717
|
expect(@node.private_key.to_hex).to eql("bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23")
|
718
718
|
expect(@node.private_key.to_wif).to eql("L3WAYNAZPxx1fr7KCz7GN9nD5qMBnNiqEJNJMU1z9MMaannAt4aK")
|
719
719
|
end
|
720
|
-
|
720
|
+
|
721
721
|
it "generates a public key" do
|
722
722
|
expect(@node.public_key.to_hex).to eql("024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c")
|
723
723
|
end
|
724
|
-
|
724
|
+
|
725
725
|
it "generates a chain code" do
|
726
726
|
expect(@node.chain_code_hex).to eql("9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271")
|
727
727
|
end
|
728
|
-
|
728
|
+
|
729
729
|
it "generates a serialized private key" do
|
730
730
|
expect(@node.to_serialized_hex(:private)).to eql("0488ade40531a507b8000000029452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed27100bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23")
|
731
|
-
expect(@node.
|
731
|
+
expect(@node.to_bip32(:private)).to eql("xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j")
|
732
732
|
end
|
733
|
-
|
733
|
+
|
734
734
|
it "generates a serialized public_key" do
|
735
735
|
expect(@node.to_serialized_hex).to eql("0488b21e0531a507b8000000029452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c")
|
736
|
-
expect(@node.
|
736
|
+
expect(@node.to_bip32).to eql("xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt")
|
737
737
|
end
|
738
738
|
end
|
739
739
|
end
|
740
740
|
end
|
741
|
-
|
741
|
+
|
742
742
|
describe "negative index" do
|
743
743
|
before do
|
744
744
|
@master = MoneyTree::Master.new seed_hex: "000102030405060708090a0b0c0d0e0f"
|
745
745
|
@node = @master.node_for_path "m/0'/-1"
|
746
746
|
end
|
747
|
-
|
747
|
+
|
748
748
|
it "has an index of 1" do
|
749
749
|
expect(@node.index).to eql(-1)
|
750
750
|
end
|
751
|
-
|
751
|
+
|
752
752
|
it "is public" do
|
753
753
|
expect(@node.is_private?).to eql(true)
|
754
754
|
end
|
755
|
-
|
755
|
+
|
756
756
|
it "has a depth of 2" do
|
757
757
|
expect(@node.depth).to eql(2)
|
758
758
|
end
|
759
|
-
|
759
|
+
|
760
760
|
it "generates a serialized private key" do
|
761
761
|
expect(@node.to_serialized_hex(:private)).to eql("0488ade4025c1bd648ffffffff0f9ca680ee23c81a305d96b86f811947e65590200b6f74d66ecf83936313a9c900235893db08ad0efc6ae4a1eac5b31a90a7d0906403d139d4d7f3c6796fb42c4e")
|
762
|
-
expect(@node.
|
762
|
+
expect(@node.to_bip32(:private)).to eql("xprv9wTYmMFvAM7JHf3RuUidc24a4y2t4gN7aNP5ABreWAqt6BUBcf6xE8RNQxj2vUssYWM8iAZiZi5H1fmKkkpXjtwDCDv1pg8fSfQMk9rhHYt")
|
763
763
|
end
|
764
|
-
|
764
|
+
|
765
765
|
it "generates a serialized public_key" do
|
766
766
|
expect(@node.to_serialized_hex).to eql("0488b21e025c1bd648ffffffff0f9ca680ee23c81a305d96b86f811947e65590200b6f74d66ecf83936313a9c902adb7979a5e99bf8acdfec3680bf482feac9898b28808c22d47db62e98de5d3fa")
|
767
|
-
expect(@node.
|
767
|
+
expect(@node.to_bip32).to eql("xpub6ASuArnozifbW97u1WFdyA1JczsNU95xwbJfxaGG4WNrxyoLACRCmvjrGEojsRsoZULf5FyZXv6AWAtce2UErsshvkpjNaT1fP6sMgTZdc1")
|
768
768
|
end
|
769
769
|
end
|
770
|
-
|
770
|
+
|
771
771
|
describe "importing node" do
|
772
|
-
describe ".
|
772
|
+
describe ".from_bip32(address)" do
|
773
773
|
it "imports a valid private node address" do
|
774
|
-
@node = MoneyTree::Node.
|
774
|
+
@node = MoneyTree::Node.from_bip32 "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7"
|
775
775
|
expect(@node.private_key.to_hex).to eql("edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea")
|
776
776
|
expect(@node.index).to eql(2147483648)
|
777
777
|
expect(@node.is_private?).to eql(true)
|
@@ -780,9 +780,9 @@ describe MoneyTree::Master do
|
|
780
780
|
expect(@node.chain_code_hex).to eql("47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141")
|
781
781
|
expect(@node.parent_fingerprint).to eql("3442193e")
|
782
782
|
end
|
783
|
-
|
783
|
+
|
784
784
|
it "imports a valid public node address" do
|
785
|
-
@node = MoneyTree::Node.
|
785
|
+
@node = MoneyTree::Node.from_bip32 "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw"
|
786
786
|
expect(@node.private_key).to be_nil
|
787
787
|
expect(@node.index).to eql(2147483648)
|
788
788
|
expect(@node.is_private?).to eql(true)
|
@@ -797,9 +797,9 @@ describe MoneyTree::Master do
|
|
797
797
|
describe "deriving a child node" do
|
798
798
|
describe "#node_for_path" do
|
799
799
|
it "correctly derives from a node with a chain code represented in 31 bytes" do
|
800
|
-
@node = MoneyTree::Node.
|
800
|
+
@node = MoneyTree::Node.from_bip32 "tpubD6NzVbkrYhZ4WM42MZZmUZ7LjxyjBf5bGjEeLf9nJnMZqocGJWu94drvpqWsE9jE7k3h22v6gjpPGnqgBrqwGsRYwDXVRfQ2M9dfHbXP5zA"
|
801
801
|
@subnode = @node.node_for_path('m/1')
|
802
|
-
expect(@subnode.
|
802
|
+
expect(@subnode.to_bip32(network: :bitcoin_testnet)).to eql("tpubDA7bCxb3Nrcz2ChXyPqXxbG4q5oiAZUHR7wD3LAiXukuxmT65weWw84XYmjhkJTkJEM6LhNWioWTpKEkQp7j2fgVccj3PPc271xHDeMsaTY")
|
803
803
|
end
|
804
804
|
end
|
805
805
|
end
|