@@ -8,85 +8,129 @@ import {
8
8
} from '@scure/bip39'
9
9
import { bech32 } from 'bech32'
10
10
import { wordlist } from '@scure/bip39/wordlists/english'
11
- import { DERIVATION_PATH , PUBLIC_KEY_PREFIX , SECRET_KEY_PREFIX } from './constants'
11
+ import {
12
+ DERIVATION_PATH ,
13
+ PUBLIC_KEY_PREFIX ,
14
+ SECRET_KEY_PREFIX
15
+ } from './constants'
12
16
13
- export function privateKeyFromSeedWords (
14
- {
15
- mnemonic,
16
- passphrase
17
- } : { mnemonic : string , passphrase ?: string }
18
- ) : { privateKey : string } {
17
+ import {
18
+ ExtendedKeys ,
19
+ Key ,
20
+ Account ,
21
+ } from './types'
22
+
23
+ export function accountFromSeedWords ( {
24
+ mnemonic,
25
+ passphrase,
26
+ accountIndex = 0
27
+ } : {
28
+ mnemonic : string ,
29
+ passphrase ?: string ,
30
+ accountIndex ?: number
31
+ } ) : Account {
19
32
const root = HDKey . fromMasterSeed ( mnemonicToSeedSync ( mnemonic , passphrase ) )
20
- const { privateKey } = root . derive ( `${ DERIVATION_PATH } /0'/0/0` )
21
- if ( ! privateKey ) {
22
- throw new Error ( 'could not derive private key' )
33
+ const seed = root . derive ( `${ DERIVATION_PATH } /${ accountIndex } '/0/0` )
34
+ const privateKeyHex = bytesToHex ( seed . privateKey ! )
35
+ const publicKeyHex = bytesToHex ( seed . publicKey ! . slice ( 1 ) )
36
+ if ( ! privateKeyHex && ! publicKeyHex ) {
37
+ throw new Error ( 'could not derive key pair' )
23
38
}
39
+ const { bech32PrivateKey } = getBech32PrivateKey ( { privateKey : privateKeyHex } )
40
+ const { bech32PublicKey } = getBech32PublicKey ( { publicKey : publicKeyHex } )
24
41
return {
25
- privateKey : bytesToHex ( privateKey )
42
+ privateKey : { hex : privateKeyHex , bech32 : bech32PrivateKey } ,
43
+ publicKey : { hex : publicKeyHex , bech32 : bech32PublicKey }
26
44
}
27
45
}
28
46
29
- export function generatePrivateKey ( ) : { privateKey : string } {
30
- return {
31
- privateKey : bytesToHex ( secp256k1 . utils . randomPrivateKey ( ) )
47
+ export function accountFromRandomKey ( ) : Account {
48
+ const privateKeyHex = bytesToHex ( secp256k1 . utils . randomPrivateKey ( ) )
49
+ const publicKeyHex = bytesToHex ( schnorr . getPublicKey ( privateKeyHex ) )
50
+ if ( ! privateKeyHex && ! publicKeyHex ) {
51
+ throw new Error ( 'could not derive key pair' )
32
52
}
33
- }
34
-
35
- export function getPublicKey ( { privateKey } : { privateKey : string } ) : { publicKey : string } {
53
+ const { bech32PrivateKey } = getBech32PrivateKey ( { privateKey : privateKeyHex } )
54
+ const { bech32PublicKey } = getBech32PublicKey ( { publicKey : publicKeyHex } )
36
55
return {
37
- publicKey : bytesToHex ( schnorr . getPublicKey ( privateKey ) )
56
+ privateKey : { hex : privateKeyHex , bech32 : bech32PrivateKey } ,
57
+ publicKey : { hex : publicKeyHex , bech32 : bech32PublicKey }
38
58
}
39
59
}
40
60
41
- function hexToBech32 ( key : string , prefix : string ) {
42
- const words = bech32 . toWords ( hexToBytes ( key ) )
43
- return bech32 . encode ( prefix , words )
44
- }
45
-
46
- export function getBech32PrivateKey ( { privateKey } : { privateKey : string } ) : { bech32PrivateKey : string } {
47
- return {
48
- bech32PrivateKey : hexToBech32 ( privateKey , SECRET_KEY_PREFIX )
61
+ export function getPublicKey ( { privateKey } : { privateKey : string } ) : {
62
+ publicKey : Key
63
+ } {
64
+ const publicKeyHex = bytesToHex ( schnorr . getPublicKey ( privateKey ) )
65
+ if ( ! publicKeyHex ) {
66
+ throw new Error ( 'could not generate public key' )
49
67
}
50
- }
51
-
52
- export function getBech32PublicKey ( { publicKey } : { publicKey : string } ) : { bech32PublicKey : string } {
68
+ const { bech32PublicKey } = getBech32PublicKey ( { publicKey : publicKeyHex } )
53
69
return {
54
- bech32PublicKey : hexToBech32 ( publicKey , PUBLIC_KEY_PREFIX )
70
+ publicKey : { hex : publicKeyHex , bech32 : bech32PublicKey }
55
71
}
56
72
}
57
73
58
- export function extendedPairFromSeedWords ( mnemonic : string , passphrase ?: string , extendedAccountIndex = 0 ) : {
59
- privateExtendedKey : string ,
60
- publicExtendedKey : string
61
- } {
74
+ export function extendedKeysFromSeedWords ( {
75
+ mnemonic,
76
+ passphrase,
77
+ extendedAccountIndex = 0
78
+ } : {
79
+ mnemonic : string ,
80
+ passphrase ?: string ,
81
+ extendedAccountIndex ?: number
82
+ } ) : ExtendedKeys {
62
83
let root = HDKey . fromMasterSeed ( mnemonicToSeedSync ( mnemonic , passphrase ) )
63
84
let seed = root . derive ( `${ DERIVATION_PATH } /${ extendedAccountIndex } '` )
64
85
let privateExtendedKey = seed . privateExtendedKey
65
86
let publicExtendedKey = seed . publicExtendedKey
66
- if ( ! privateExtendedKey ) throw new Error ( 'could not derive private extended key' )
87
+ if ( ! privateExtendedKey && ! publicExtendedKey ) throw new Error ( 'could not derive extended key pair ' )
67
88
return { privateExtendedKey, publicExtendedKey }
68
89
}
69
90
70
- export function accountFromExtendedKey ( base58key : string , accountIndex = 0 ) : {
71
- privateKey ?: { hex : string , bech32 : string } ,
72
- publicKey : { hex : string , bech32 : string }
91
+ export function accountFromExtendedKey ( {
92
+ extendedKey,
93
+ accountIndex = 0
94
+ } : {
95
+ extendedKey : string ,
96
+ accountIndex ?: number
97
+ } ) : {
98
+ privateKey ?: Key ,
99
+ publicKey : Key
73
100
} {
74
- let extendedKey = HDKey . fromExtendedKey ( base58key )
75
- let version = base58key . slice ( 0 , 4 )
76
- let child = extendedKey . deriveChild ( 0 ) . deriveChild ( accountIndex )
101
+ let seed = HDKey . fromExtendedKey ( extendedKey )
102
+ let version = extendedKey . slice ( 0 , 4 )
103
+ let child = seed . deriveChild ( 0 ) . deriveChild ( accountIndex )
77
104
let publicKeyHex = bytesToHex ( child . publicKey ! . slice ( 1 ) )
78
105
if ( ! publicKeyHex ) throw new Error ( 'could not derive public key' )
79
- let publicKeyBech32 = hexToBech32 ( publicKeyHex , 'npub' )
106
+ const { bech32PublicKey } = getBech32PublicKey ( { publicKey : publicKeyHex } )
80
107
if ( version === 'xprv' ) {
81
108
let privateKeyHex = bytesToHex ( child . privateKey ! )
82
109
if ( ! privateKeyHex ) throw new Error ( 'could not derive private key' )
83
- let privateKeyBech32 = hexToBech32 ( privateKeyHex , 'nsec' )
110
+ const { bech32PrivateKey } = getBech32PrivateKey ( { privateKey : privateKeyHex } )
84
111
return {
85
- privateKey : { hex : privateKeyHex , bech32 : privateKeyBech32 } ,
86
- publicKey : { hex : publicKeyHex , bech32 : publicKeyBech32 }
112
+ privateKey : { hex : privateKeyHex , bech32 : bech32PrivateKey } ,
113
+ publicKey : { hex : publicKeyHex , bech32 : bech32PublicKey }
87
114
}
88
115
}
89
- return { publicKey : { hex : publicKeyHex , bech32 : publicKeyBech32 } }
116
+ return { publicKey : { hex : publicKeyHex , bech32 : bech32PublicKey } }
117
+ }
118
+
119
+ function hexToBech32 ( key : string , prefix : string ) {
120
+ const words = bech32 . toWords ( hexToBytes ( key ) )
121
+ return bech32 . encode ( prefix , words )
122
+ }
123
+
124
+ export function getBech32PrivateKey ( { privateKey } : { privateKey : string } ) : { bech32PrivateKey : string } {
125
+ return {
126
+ bech32PrivateKey : hexToBech32 ( privateKey , SECRET_KEY_PREFIX )
127
+ }
128
+ }
129
+
130
+ export function getBech32PublicKey ( { publicKey } : { publicKey : string } ) : { bech32PublicKey : string } {
131
+ return {
132
+ bech32PublicKey : hexToBech32 ( publicKey , PUBLIC_KEY_PREFIX )
133
+ }
90
134
}
91
135
92
136
export function generateSeedWords ( ) : { mnemonic : string } {
0 commit comments