@@ -17,34 +17,27 @@ public class BIP32Keystore: AbstractKeystore {
17
17
public var isHDKeystore : Bool = true
18
18
19
19
public var keystoreParams : KeystoreParamsBIP32 ?
20
+
21
+ @available ( * , deprecated, message: " Please use addressStorage instead " )
20
22
public var paths : [ String : EthereumAddress ] = [ String: EthereumAddress] ( )
21
23
22
24
public var rootPrefix : String
23
25
24
26
public var addresses : [ EthereumAddress ] ? {
25
27
get {
26
- if self . paths. count == 0 {
28
+ let addresses = self . addressStorage. addresses
29
+ if addresses. count == 0 {
27
30
return nil
28
31
}
29
- var allAccounts = [ EthereumAddress] ( )
30
- for (_, address) in paths {
31
- allAccounts. append ( address)
32
- }
33
- return allAccounts
32
+ return addresses
34
33
}
35
34
}
36
35
37
36
public func UNSAFE_getPrivateKeyData( password: String , account: EthereumAddress ) throws -> Data {
38
- if let key = self . paths. keyForValue ( value: account) {
39
- guard let decryptedRootNode = try ? self . getPrefixNodeData ( password) else {
40
- throw AbstractKeystoreError . encryptionError ( " Failed to decrypt a keystore " )
41
- }
42
- guard let rootNode = HDNode ( decryptedRootNode) else {
43
- throw AbstractKeystoreError . encryptionError ( " Failed to deserialize a root node " )
44
- }
45
- guard rootNode. depth == ( self . rootPrefix. components ( separatedBy: " / " ) . count - 1 ) else {
46
- throw AbstractKeystoreError . encryptionError ( " Derivation depth mismatch " )
47
- }
37
+ if let key = addressStorage. path ( by: account) {
38
+ guard let decryptedRootNode = try ? self . getPrefixNodeData ( password) else { throw AbstractKeystoreError . encryptionError ( " Failed to decrypt a keystore " ) }
39
+ guard let rootNode = HDNode ( decryptedRootNode) else { throw AbstractKeystoreError . encryptionError ( " Failed to deserialize a root node " ) }
40
+ guard rootNode. depth == ( self . rootPrefix. components ( separatedBy: " / " ) . count - 1 ) else { throw AbstractKeystoreError . encryptionError ( " Derivation depth mismatch " ) }
48
41
// guard rootNode.depth == HDNode.defaultPathPrefix.components(separatedBy: "/").count - 1 else {throw AbstractKeystoreError.encryptionError("Derivation depth mismatch")}
49
42
guard let index = UInt32 ( key. components ( separatedBy: " / " ) . last!) else {
50
43
throw AbstractKeystoreError . encryptionError ( " Derivation depth mismatch " )
@@ -61,8 +54,11 @@ public class BIP32Keystore: AbstractKeystore {
61
54
}
62
55
63
56
// --------------
64
-
65
-
57
+
58
+ private static let KeystoreParamsBIP32Version = 4
59
+
60
+ private ( set) var addressStorage : PathAddressStorage
61
+
66
62
public convenience init ? ( _ jsonString: String ) {
67
63
let lowercaseJSON = jsonString. lowercased ( )
68
64
guard let jsonData = lowercaseJSON. data ( using: . utf8) else {
@@ -72,21 +68,16 @@ public class BIP32Keystore: AbstractKeystore {
72
68
}
73
69
74
70
public init ? ( _ jsonData: Data ) {
75
- guard var keystorePars = try ? JSONDecoder ( ) . decode ( KeystoreParamsBIP32 . self, from: jsonData) else {
76
- return nil
77
- }
78
- if ( keystorePars. version != 3 ) {
79
- return nil
80
- }
81
- if ( keystorePars. crypto. version != nil && keystorePars. crypto. version != " 1 " ) {
82
- return nil
83
- }
84
- if ( !keystorePars. isHDWallet) {
85
- return nil
86
- }
71
+ guard var keystorePars = try ? JSONDecoder ( ) . decode ( KeystoreParamsBIP32 . self, from: jsonData) else { return nil }
72
+ if ( keystorePars. version != Self . KeystoreParamsBIP32Version) { return nil }
73
+ if ( keystorePars. crypto. version != nil && keystorePars. crypto. version != " 1 " ) { return nil }
74
+ if ( !keystorePars. isHDWallet) { return nil }
75
+
87
76
for (p, ad) in keystorePars. pathToAddress {
88
77
paths [ p] = EthereumAddress ( ad)
89
78
}
79
+ addressStorage = PathAddressStorage ( pathAddressPairs: keystorePars. pathAddressPairs)
80
+
90
81
if keystorePars. rootPath == nil {
91
82
keystorePars. rootPath = HDNode . defaultPathPrefix
92
83
}
@@ -103,11 +94,10 @@ public class BIP32Keystore: AbstractKeystore {
103
94
}
104
95
try self . init ( seed: seed, password: password, prefixPath: prefixPath, aesMode: aesMode)
105
96
}
106
-
107
- public init ? ( seed: Data , password: String = " web3swift " , prefixPath: String = HDNode . defaultPathMetamaskPrefix, aesMode: String = " aes-128-cbc " ) throws {
108
- guard let rootNode = HDNode ( seed: seed) ? . derive ( path: prefixPath, derivePrivateKey: true ) else {
109
- return nil
110
- }
97
+
98
+ public init ? ( seed: Data , password: String = " web3swift " , prefixPath: String = HDNode . defaultPathMetamaskPrefix, aesMode: String = " aes-128-cbc " ) throws {
99
+ addressStorage = PathAddressStorage ( )
100
+ guard let rootNode = HDNode ( seed: seed) ? . derive ( path: prefixPath, derivePrivateKey: true ) else { return nil }
111
101
self . rootPrefix = prefixPath
112
102
try createNewAccount ( parentNode: rootNode, password: password)
113
103
guard let serializedRootNode = rootNode. serialize ( serializePublic: false ) else {
@@ -136,10 +126,8 @@ public class BIP32Keystore: AbstractKeystore {
136
126
137
127
func createNewAccount( parentNode: HDNode , password: String = " web3swift " ) throws {
138
128
var newIndex = UInt32 ( 0 )
139
- for (p, _) in paths {
140
- guard let idx = UInt32 ( p. components ( separatedBy: " / " ) . last!) else {
141
- continue
142
- }
129
+ for p in addressStorage. paths {
130
+ guard let idx = UInt32 ( p. components ( separatedBy: " / " ) . last!) else { continue }
143
131
if idx >= newIndex {
144
132
newIndex = idx + 1
145
133
}
@@ -157,7 +145,7 @@ public class BIP32Keystore: AbstractKeystore {
157
145
} else {
158
146
newPath = prefixPath + " / " + String( newNode. index)
159
147
}
160
- paths [ newPath ] = newAddress
148
+ addressStorage . add ( address : newAddress, for : newPath )
161
149
}
162
150
163
151
public func createNewCustomChildAccount( password: String = " web3swift " , path: String ) throws { guard let decryptedRootNode = try ? self . getPrefixNodeData ( password) else {
@@ -208,9 +196,8 @@ public class BIP32Keystore: AbstractKeystore {
208
196
newPath = prefixPath + " / " + pathAppendix!
209
197
}
210
198
paths [ newPath] = newAddress
211
- guard let serializedRootNode = rootNode. serialize ( serializePublic: false ) else {
212
- throw AbstractKeystoreError . keyDerivationError
213
- }
199
+ addressStorage. add ( address: newAddress, for: newPath)
200
+ guard let serializedRootNode = rootNode. serialize ( serializePublic: false ) else { throw AbstractKeystoreError . keyDerivationError}
214
201
try encryptDataToStorage ( password, data: serializedRootNode, aesMode: self . keystoreParams!. crypto. cipher)
215
202
}
216
203
@@ -261,8 +248,8 @@ public class BIP32Keystore: AbstractKeystore {
261
248
for (path, address) in paths {
262
249
pathToAddress [ path] = address. address
263
250
}
264
- var keystorePars = KeystoreParamsBIP32 ( crypto: crypto, id: UUID ( ) . uuidString. lowercased ( ) , version: 3 )
265
- keystorePars. pathToAddress = pathToAddress
251
+ var keystorePars = KeystoreParamsBIP32 ( crypto: crypto, id: UUID ( ) . uuidString. lowercased ( ) , version: Self . KeystoreParamsBIP32Version )
252
+ keystorePars. pathAddressPairs = addressStorage . toPathAddressPairs ( )
266
253
keystorePars. rootPath = self . rootPrefix
267
254
keystoreParams = keystorePars
268
255
}
0 commit comments