diff --git a/hd_key_test.go b/hd_key_test.go index 9d44a6f..7b3f9bd 100644 --- a/hd_key_test.go +++ b/hd_key_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/bitcoinsv/bsvd/bsvec" + "github.com/bitcoinsv/bsvutil" "github.com/bitcoinsv/bsvutil/hdkeychain" ) @@ -108,6 +109,7 @@ func ExampleGenerateHDKeyPair() { fmt.Printf("error occurred: %s", err.Error()) return } + // Cannot show the private/public key since they change each time fmt.Printf("created HD key successfully! (xPrivateKey length: %d) (xPublicKey length: %d)", len(xPrivateKey), len(xPublicKey)) @@ -395,3 +397,252 @@ func BenchmarkGetHDKeyChild(b *testing.B) { _, _ = GetHDKeyChild(hdKey, 0) } } + +// TestGenerateHDKeyFromString will test the method GenerateHDKeyFromString() +func TestGenerateHDKeyFromString(t *testing.T) { + t.Parallel() + + // Create the list of tests + var tests = []struct { + input string + expectedNil bool + expectedError bool + }{ + {"", true, true}, + {"0", true, true}, + {"1234567", true, true}, + {"xprv9s21ZrQH143K3PZSwbEeXEYq74EbnfMngzAiMCZcfjzyRpUvt2vQJnaHRTZjeuEmLXeN6BzYRoFsEckfobxE9XaRzeLGfQoxzPzTRyRb6oE", false, false}, + {"xprv9s21ZrQH143K3PZSwbEeXEYq74EbnfMngzAiMCZcfjzyRpUv", true, true}, + {"xprv9s21ZrQH143K3XJueaaswvbJ38UX3FhnXkcA7xF8kqeN62qEu116M1XnqaDpSE7SoKp8NxejVJG9dfpuvBC314VZNdB7W1kQN3Viwgkjr8L", false, false}, + } + + // Run tests + for _, test := range tests { + if hdKey, err := GenerateHDKeyFromString(test.input); err != nil && !test.expectedError { + t.Errorf("%s Failed: [%s] inputted and error not expected but got: %s", t.Name(), test.input, err.Error()) + } else if err == nil && test.expectedError { + t.Errorf("%s Failed: [%s] inputted and error was expected", t.Name(), test.input) + } else if hdKey == nil && !test.expectedNil { + t.Errorf("%s Failed: [%s] inputted and was nil but not expected", t.Name(), test.input) + } else if hdKey != nil && test.expectedNil { + t.Errorf("%s Failed: [%s] inputted and was NOT nil but expected to be nil", t.Name(), test.input) + } else if hdKey != nil && hdKey.String() != test.input { + t.Errorf("%s Failed: [%s] inputted [%s] expected but got: %s", t.Name(), test.input, test.input, hdKey.String()) + } + } +} + +// ExampleGenerateHDKeyFromString example using GenerateHDKeyFromString() +func ExampleGenerateHDKeyFromString() { + + hdKey, err := GenerateHDKeyFromString("xprv9s21ZrQH143K3PZSwbEeXEYq74EbnfMngzAiMCZcfjzyRpUvt2vQJnaHRTZjeuEmLXeN6BzYRoFsEckfobxE9XaRzeLGfQoxzPzTRyRb6oE") + if err != nil { + fmt.Printf("error occurred: %s", err.Error()) + return + } + + fmt.Printf("hd key generated from: %s", hdKey.String()) + // Output:hd key generated from: xprv9s21ZrQH143K3PZSwbEeXEYq74EbnfMngzAiMCZcfjzyRpUvt2vQJnaHRTZjeuEmLXeN6BzYRoFsEckfobxE9XaRzeLGfQoxzPzTRyRb6oE +} + +// BenchmarkGenerateHDKeyFromString benchmarks the method GenerateHDKeyFromString() +func BenchmarkGenerateHDKeyFromString(b *testing.B) { + xPriv, _, _ := GenerateHDKeyPair(SecureSeedLength) + for i := 0; i < b.N; i++ { + _, _ = GenerateHDKeyFromString(xPriv) + } +} + +// TestGetPrivateKeyFromHDKey will test the method GetPrivateKeyFromHDKey() +func TestGetPrivateKeyFromHDKey(t *testing.T) { + t.Parallel() + + validHdKey, err := GenerateHDKeyFromString("xprv9s21ZrQH143K4FdJCmPQe1CFUvK3PKVrcp3b5xVr5Bs3cP5ab6ytszeHggTmHoqTXpaa8CgYPxZZzigSGCDjtyWdUDJqPogb1JGWAPkBLdF") + if err != nil { + t.Fatalf("error occurred: %s", err.Error()) + } + + // Create the list of tests + var tests = []struct { + input *hdkeychain.ExtendedKey + expectedKey string + expectedNil bool + expectedError bool + }{ + {nil, "", true, true}, + {new(hdkeychain.ExtendedKey), "", true, true}, + {validHdKey, "8511f5e1e35ab748e7639aa68666df71857866af13fda1d081d5917948a6cd34", false, false}, + } + + // Run tests + for _, test := range tests { + if privateKey, err := GetPrivateKeyFromHDKey(test.input); err != nil && !test.expectedError { + t.Errorf("%s Failed: [%v] inputted and error not expected but got: %s", t.Name(), test.input, err.Error()) + } else if err == nil && test.expectedError { + t.Errorf("%s Failed: [%v] inputted and error was expected", t.Name(), test.input) + } else if privateKey == nil && !test.expectedNil { + t.Errorf("%s Failed: [%v] inputted and was nil but not expected", t.Name(), test.input) + } else if privateKey != nil && test.expectedNil { + t.Errorf("%s Failed: [%v] inputted and was NOT nil but expected to be nil", t.Name(), test.input) + } else if privateKey != nil && hex.EncodeToString(privateKey.Serialize()) != test.expectedKey { + t.Errorf("%s Failed: [%v] inputted [%s] expected but got: %s", t.Name(), test.input, test.expectedKey, hex.EncodeToString(privateKey.Serialize())) + } + } +} + +// ExampleGetPrivateKeyFromHDKey example using GetPrivateKeyFromHDKey() +func ExampleGetPrivateKeyFromHDKey() { + + hdKey, err := GenerateHDKeyFromString("xprv9s21ZrQH143K3PZSwbEeXEYq74EbnfMngzAiMCZcfjzyRpUvt2vQJnaHRTZjeuEmLXeN6BzYRoFsEckfobxE9XaRzeLGfQoxzPzTRyRb6oE") + if err != nil { + fmt.Printf("error occurred: %s", err.Error()) + return + } + + var privateKey *bsvec.PrivateKey + if privateKey, err = GetPrivateKeyFromHDKey(hdKey); err != nil { + fmt.Printf("error occurred: %s", err.Error()) + return + } + + fmt.Printf("private key: %s", hex.EncodeToString(privateKey.Serialize())) + // Output:private key: 0ccf07f2cbe10dbe6f6034b7efbf62fc83cac3d44f49d67aa22ac8893d294e7a +} + +// BenchmarkGetPrivateKeyFromHDKey benchmarks the method GetPrivateKeyFromHDKey() +func BenchmarkGetPrivateKeyFromHDKey(b *testing.B) { + hdKey, _ := GenerateHDKey(SecureSeedLength) + for i := 0; i < b.N; i++ { + _, _ = GetPrivateKeyFromHDKey(hdKey) + } +} + +// TestGetPublicKeyFromHDKey will test the method GetPublicKeyFromHDKey() +func TestGetPublicKeyFromHDKey(t *testing.T) { + t.Parallel() + + validHdKey, err := GenerateHDKeyFromString("xprv9s21ZrQH143K4FdJCmPQe1CFUvK3PKVrcp3b5xVr5Bs3cP5ab6ytszeHggTmHoqTXpaa8CgYPxZZzigSGCDjtyWdUDJqPogb1JGWAPkBLdF") + if err != nil { + t.Fatalf("error occurred: %s", err.Error()) + } + + // Create the list of tests + var tests = []struct { + input *hdkeychain.ExtendedKey + expectedKey string + expectedNil bool + expectedError bool + }{ + {nil, "", true, true}, + {new(hdkeychain.ExtendedKey), "", true, true}, + {validHdKey, "02f2a2942b9d1dba033d36ab0c193e680415f5c8c1ff5d854f805c8c42ed9dd1fd", false, false}, + } + + // Run tests + var publicKey *bsvec.PublicKey + for _, test := range tests { + if publicKey, err = GetPublicKeyFromHDKey(test.input); err != nil && !test.expectedError { + t.Errorf("%s Failed: [%v] inputted and error not expected but got: %s", t.Name(), test.input, err.Error()) + } else if err == nil && test.expectedError { + t.Errorf("%s Failed: [%v] inputted and error was expected", t.Name(), test.input) + } else if publicKey == nil && !test.expectedNil { + t.Errorf("%s Failed: [%v] inputted and was nil but not expected", t.Name(), test.input) + } else if publicKey != nil && test.expectedNil { + t.Errorf("%s Failed: [%v] inputted and was NOT nil but expected to be nil", t.Name(), test.input) + } else if publicKey != nil && hex.EncodeToString(publicKey.SerializeCompressed()) != test.expectedKey { + t.Errorf("%s Failed: [%v] inputted [%s] expected but got: %s", t.Name(), test.input, test.expectedKey, hex.EncodeToString(publicKey.SerializeCompressed())) + } + } +} + +// ExampleGetPublicKeyFromHDKey example using GetPublicKeyFromHDKey() +func ExampleGetPublicKeyFromHDKey() { + + hdKey, err := GenerateHDKeyFromString("xprv9s21ZrQH143K3PZSwbEeXEYq74EbnfMngzAiMCZcfjzyRpUvt2vQJnaHRTZjeuEmLXeN6BzYRoFsEckfobxE9XaRzeLGfQoxzPzTRyRb6oE") + if err != nil { + fmt.Printf("error occurred: %s", err.Error()) + return + } + + var publicKey *bsvec.PublicKey + if publicKey, err = GetPublicKeyFromHDKey(hdKey); err != nil { + fmt.Printf("error occurred: %s", err.Error()) + return + } + + fmt.Printf("public key: %s", hex.EncodeToString(publicKey.SerializeCompressed())) + // Output:public key: 03a25f6c10eedcd41eebac22c6bbc5278690fa1aab3afc2bbe8f2277c85e5c5def +} + +// BenchmarkGetPublicKeyFromHDKey benchmarks the method GetPublicKeyFromHDKey() +func BenchmarkGetPublicKeyFromHDKey(b *testing.B) { + hdKey, _ := GenerateHDKey(SecureSeedLength) + for i := 0; i < b.N; i++ { + _, _ = GetPublicKeyFromHDKey(hdKey) + } +} + +// TestGetAddressFromHDKey will test the method GetAddressFromHDKey() +func TestGetAddressFromHDKey(t *testing.T) { + t.Parallel() + + validHdKey, err := GenerateHDKeyFromString("xprv9s21ZrQH143K4FdJCmPQe1CFUvK3PKVrcp3b5xVr5Bs3cP5ab6ytszeHggTmHoqTXpaa8CgYPxZZzigSGCDjtyWdUDJqPogb1JGWAPkBLdF") + if err != nil { + t.Fatalf("error occurred: %s", err.Error()) + } + + // Create the list of tests + var tests = []struct { + input *hdkeychain.ExtendedKey + expectedAddress string + expectedNil bool + expectedError bool + }{ + {nil, "", true, true}, + {new(hdkeychain.ExtendedKey), "", true, true}, + {validHdKey, "13xHrMdZuqa2gpweHf37w8hu6tfv3JrnaW", false, false}, + } + + // Run tests + var address *bsvutil.LegacyAddressPubKeyHash + for _, test := range tests { + if address, err = GetAddressFromHDKey(test.input); err != nil && !test.expectedError { + t.Errorf("%s Failed: [%v] inputted and error not expected but got: %s", t.Name(), test.input, err.Error()) + } else if err == nil && test.expectedError { + t.Errorf("%s Failed: [%v] inputted and error was expected", t.Name(), test.input) + } else if address == nil && !test.expectedNil { + t.Errorf("%s Failed: [%v] inputted and was nil but not expected", t.Name(), test.input) + } else if address != nil && test.expectedNil { + t.Errorf("%s Failed: [%v] inputted and was NOT nil but expected to be nil", t.Name(), test.input) + } else if address != nil && address.String() != test.expectedAddress { + t.Errorf("%s Failed: [%v] inputted [%s] expected but got: %s", t.Name(), test.input, test.expectedAddress, address.String()) + } + } +} + +// ExampleGetAddressFromHDKey example using GetAddressFromHDKey() +func ExampleGetAddressFromHDKey() { + + hdKey, err := GenerateHDKeyFromString("xprv9s21ZrQH143K3PZSwbEeXEYq74EbnfMngzAiMCZcfjzyRpUvt2vQJnaHRTZjeuEmLXeN6BzYRoFsEckfobxE9XaRzeLGfQoxzPzTRyRb6oE") + if err != nil { + fmt.Printf("error occurred: %s", err.Error()) + return + } + + var address *bsvutil.LegacyAddressPubKeyHash + if address, err = GetAddressFromHDKey(hdKey); err != nil { + fmt.Printf("error occurred: %s", err.Error()) + return + } + + fmt.Printf("address: %s", address.String()) + // Output:address: 18G2YRH3nRKRx8pnqVFUM5nAJhTZJ3YA4W +} + +// BenchmarkGetAddressFromHDKey benchmarks the method GetAddressFromHDKey() +func BenchmarkGetAddressFromHDKey(b *testing.B) { + hdKey, _ := GenerateHDKey(SecureSeedLength) + for i := 0; i < b.N; i++ { + _, _ = GetAddressFromHDKey(hdKey) + } +}