@@ -7,6 +7,8 @@ defmodule BSV.ExtKeyTest do
77 @ test_seed "5bd995f07cbaeeb8c1fb4d52db5884471ae80b82f7c07094bfc77b2f4742a76a1d72d25ad58d011ecff16b1b9b0ae225e2fc084cad91a176527b4bca50047025"
88 @ test_xprv "xprv9s21ZrQH143K3qcbMJpvTQQQ1zRCPaZjXUD1zPouMDtKY9QQQ9DskzrZ3Cx38GnYXpgY2awCmJfz2QXkpxLN3Pp2PmUddbnrXziFtArpZ5v"
99 @ test_xpub "xpub661MyMwAqRbcGKh4TLMvpYM8a2Fgo3Hath8cnnDWuZRJQwjYwgY8JoB2tTgiTDdwf4rdGvgUpGhGNH54Ycb8vegrhHVVpdfYCdBBii94CLF"
10+ @ test_tprv "tprv8ZgxMBicQKsPeer81sgRd42PL7qQd6bjs288rpEMqCNoKk9VPWZdGkDzxP7h8eAruGDK2gYxvfFnVG5VxAgJrT5cvQgwHxWuT6TgKvGc1DZ"
11+ @ test_tpub "tpubD6NzVbkrYhZ4Y7suuXM22TgVu9MLnRneSKiv9LGfFUBCAEQG1uPDTEqs8VmVyibBSyPXtWCMMNXK4TZfwUSNp699ktEoWAKmnambUgCsghP"
1012 @ extkey % BSV.ExtKey {
1113 chain_code: << 178 , 208 , 232 , 46 , 183 , 65 , 27 , 66 , 14 , 172 , 46 , 66 , 222 , 84 , 220 , 98 , 70 , 249 , 25 , 3 , 50 , 209 , 218 , 236 , 96 , 142 , 211 , 79 , 59 , 166 , 41 , 106 >> ,
1214 child_index: 0 ,
@@ -121,6 +123,80 @@ defmodule BSV.ExtKeyTest do
121123 end
122124 end
123125
126+ describe "Testnet (tprv/tpub)" do
127+ # switch to testnet for this describe block, and restore afterward
128+ setup do
129+ prev = BSV . network ( )
130+ Application . put_env ( :bsv , :network , :test )
131+ on_exit ( fn -> Application . put_env ( :bsv , :network , prev ) end )
132+ :ok
133+ end
134+
135+ test "from_seed/2 produces tprv" do
136+ assert { :ok , % ExtKey { } = extkey } = ExtKey . from_seed ( @ test_seed , encoding: :hex )
137+
138+ tprv = ExtKey . to_string ( extkey )
139+ assert String . starts_with? ( tprv , "tprv" )
140+ assert tprv == @ test_tprv
141+ end
142+
143+ test "to_public produces tpub" do
144+ assert { :ok , % ExtKey { } = extkey } = ExtKey . from_seed ( @ test_seed , encoding: :hex )
145+
146+ tpub = extkey |> ExtKey . to_public ( ) |> ExtKey . to_string ( )
147+ assert String . starts_with? ( tpub , "tpub" )
148+ assert tpub == @ test_tpub
149+ end
150+
151+ test "from_string/1 decodes tprv " do
152+ { :ok , % ExtKey { } = extkey } = ExtKey . from_seed ( @ test_seed , encoding: :hex )
153+ tprv = ExtKey . to_string ( extkey )
154+
155+ assert String . starts_with? ( tprv , "tprv" )
156+ assert { :ok , % ExtKey { } = parsed } = ExtKey . from_string ( tprv )
157+ assert tprv == @ @ test_tprv
158+
159+ # round-trip equality on the serialized form
160+ assert ExtKey . to_string ( parsed ) == tprv
161+
162+ # public conversion is also consistent
163+ assert ExtKey . to_public ( parsed ) |> ExtKey . to_string ( )
164+ == ExtKey . to_public ( extkey ) |> ExtKey . to_string ( )
165+ end
166+
167+ test "from_string/1 decodes tpub and round-trips" do
168+ { :ok , % ExtKey { } = extkey } = ExtKey . from_seed ( @ test_seed , encoding: :hex )
169+ tpub = extkey |> ExtKey . to_public ( ) |> ExtKey . to_string ( )
170+
171+ assert String . starts_with? ( tpub , "tpub" )
172+ assert { :ok , % ExtKey { } = parsed_pub } = ExtKey . from_string ( tpub )
173+ assert is_nil ( parsed_pub . privkey )
174+
175+ # round-trip equality on the serialized form
176+ assert ExtKey . to_public ( parsed_pub ) |> ExtKey . to_string ( ) == tpub
177+ end
178+
179+ test "to_public/1 swaps version bytes to testnet pub (tpub)" do
180+ # testnet pub version bytes per module under :test
181+ expected_pub_version = << 4 , 53 , 135 , 207 >>
182+
183+ { :ok , % ExtKey { } = extkey } = ExtKey . from_seed ( @ test_seed , encoding: :hex )
184+ pub = ExtKey . to_public ( extkey )
185+
186+ assert is_nil ( pub . privkey )
187+ assert pub . version == expected_pub_version
188+
189+ assert ExtKey . to_string ( pub ) |> String . starts_with? ( "tpub" )
190+ end
191+
192+ test "to_string/1 emits tprv for private and tpub for public on testnet" do
193+ { :ok , % ExtKey { } = extkey } = ExtKey . from_seed ( @ test_seed , encoding: :hex )
194+
195+ assert ExtKey . to_string ( extkey ) |> String . starts_with? ( "tprv" )
196+ assert ExtKey . to_public ( extkey ) |> ExtKey . to_string ( ) |> String . starts_with? ( "tpub" )
197+ end
198+ end
199+
124200 describe "ExtKey.to_public/1" do
125201 test "converts private extkey to public extkey" do
126202 assert % ExtKey { } = extkey = ExtKey . from_string! ( @ test_xprv ) |> ExtKey . to_public ( )
0 commit comments