This repository has been archived by the owner on Apr 2, 2024. It is now read-only.
generated from mrz1836/go-template
-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
keys.go
147 lines (119 loc) · 3.65 KB
/
keys.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package utils
import (
"github.com/bitcoinschema/go-bitcoin/v2"
"github.com/libsv/go-bk/bec"
"github.com/libsv/go-bk/bip32"
"github.com/libsv/go-bt/v2/bscript"
)
// DeriveChildKeyFromHex derive the child extended key from the hex string
func DeriveChildKeyFromHex(hdKey *bip32.ExtendedKey, hexHash string) (*bip32.ExtendedKey, error) {
var childKey *bip32.ExtendedKey
childKey = hdKey
childNums, err := GetChildNumsFromHex(hexHash)
if err != nil {
return nil, err
}
for _, num := range childNums {
if childKey, err = childKey.Child(num); err != nil {
return nil, err
}
}
return childKey, nil
}
// DerivePublicKey will derive the internal and external address from a key
func DerivePublicKey(hdKey *bip32.ExtendedKey, chain uint32, num uint32) (*bec.PublicKey, error) {
if hdKey == nil {
return nil, ErrHDKeyNil
}
pubKeys, err := bitcoin.GetPublicKeysForPath(hdKey, num)
if err != nil {
return nil, err
}
return pubKeys[chain], nil
}
// ValidateXPub will check the xPub key for length & validation
func ValidateXPub(rawKey string) (*bip32.ExtendedKey, error) {
// Validate the xpub (length)
if len(rawKey) != XpubKeyLength {
return nil, ErrXpubInvalidLength
}
// Parse the xPub into an HD key
hdKey, err := bitcoin.GetHDKeyFromExtendedPublicKey(rawKey)
if err != nil {
return nil, err
} else if hdKey.String() != rawKey { // Sanity check (might not be needed)
return nil, ErrXpubNoMatch
}
return hdKey, nil
}
// DeriveAddress will derive the given address from a key
func DeriveAddress(hdKey *bip32.ExtendedKey, chain uint32, num uint32) (address string, err error) {
// Don't panic
if hdKey == nil {
return "", ErrHDKeyNil
}
var child *bip32.ExtendedKey
if child, err = bitcoin.GetHDKeyByPath(hdKey, chain, num); err != nil {
return "", err
}
var pubKey *bec.PublicKey
if pubKey, err = child.ECPubKey(); err != nil {
// Should never error since the previous method ensures a valid hdKey
return "", err
}
var addressScript *bscript.Address
if addressScript, err = bitcoin.GetAddressFromPubKey(pubKey, true); err != nil {
// Should never error if the pubKeys are valid keys
return "", err
}
return addressScript.AddressString, nil
}
// DeriveAddresses will derive the internal and external address from a key
func DeriveAddresses(hdKey *bip32.ExtendedKey, num uint32) (external, internal string, err error) {
// Don't panic
if hdKey == nil {
return "", "", ErrHDKeyNil
}
// Derive the address
var addresses []string
if addresses, err = bitcoin.GetAddressesForPath(
hdKey, num,
); err != nil {
return
} else if len(addresses) != 2 { // Sanity check might not be needed
return "", "", ErrDeriveFailed
}
external = addresses[0]
internal = addresses[1]
return
}
// DerivePrivateKeyFromHex will derive the private key from the extended key using the hex as the derivation paths
func DerivePrivateKeyFromHex(hdKey *bip32.ExtendedKey, hexString string) (*bec.PrivateKey, error) {
if hdKey == nil {
return nil, ErrHDKeyNil
}
childKey, err := DeriveChildKeyFromHex(hdKey, hexString)
if err != nil {
return nil, err
}
var privKey *bec.PrivateKey
if privKey, err = childKey.ECPrivKey(); err != nil {
return nil, err
}
return privKey, nil
}
// DerivePublicKeyFromHex will derive the public key from the extended key using the hex as the derivation paths
func DerivePublicKeyFromHex(hdKey *bip32.ExtendedKey, hexString string) (*bec.PublicKey, error) {
if hdKey == nil {
return nil, ErrHDKeyNil
}
childKey, err := DeriveChildKeyFromHex(hdKey, hexString)
if err != nil {
return nil, err
}
var pubKey *bec.PublicKey
if pubKey, err = childKey.ECPubKey(); err != nil {
return nil, err
}
return pubKey, nil
}