@@ -14,21 +14,18 @@ public class BIP32Keystore: AbstractKeystore {
14
14
15
15
public var addresses : [ EthereumAddress ] ? {
16
16
get {
17
- if self . paths. count == 0 {
17
+ let addresses = self . addressStorage. addresses
18
+ if addresses. count == 0 {
18
19
return nil
19
20
}
20
- var allAccounts = [ EthereumAddress] ( )
21
- for (_, address) in paths {
22
- allAccounts. append ( address)
23
- }
24
- return allAccounts
21
+ return addresses
25
22
}
26
23
}
27
24
28
25
public var isHDKeystore : Bool = true
29
26
30
27
public func UNSAFE_getPrivateKeyData( password: String , account: EthereumAddress ) throws -> Data {
31
- if let key = self . paths . keyForValue ( value : account) {
28
+ if let key = addressStorage . path ( by : account) {
32
29
guard let decryptedRootNode = try ? self . getPrefixNodeData ( password) else { throw AbstractKeystoreError . encryptionError ( " Failed to decrypt a keystore " ) }
33
30
guard let rootNode = HDNode ( decryptedRootNode) else { throw AbstractKeystoreError . encryptionError ( " Failed to deserialize a root node " ) }
34
31
guard rootNode. depth == ( self . rootPrefix. components ( separatedBy: " / " ) . count - 1 ) else { throw AbstractKeystoreError . encryptionError ( " Derivation depth mismatch " ) }
@@ -44,8 +41,10 @@ public class BIP32Keystore: AbstractKeystore {
44
41
// --------------
45
42
46
43
public var keystoreParams : KeystoreParamsBIP32 ?
47
- public var paths : [ String : EthereumAddress ] = [ String: EthereumAddress] ( )
48
44
public var rootPrefix : String
45
+
46
+ private ( set) var addressStorage : PathAddressStorage
47
+
49
48
public convenience init ? ( _ jsonString: String ) {
50
49
let lowercaseJSON = jsonString. lowercased ( )
51
50
guard let jsonData = lowercaseJSON. data ( using: . utf8) else { return nil }
@@ -57,9 +56,7 @@ public class BIP32Keystore: AbstractKeystore {
57
56
if ( keystorePars. version != 3 ) { return nil }
58
57
if ( keystorePars. crypto. version != nil && keystorePars. crypto. version != " 1 " ) { return nil }
59
58
if ( !keystorePars. isHDWallet) { return nil }
60
- for (p, ad) in keystorePars. pathToAddress {
61
- paths [ p] = EthereumAddress ( ad)
62
- }
59
+ addressStorage = PathAddressStorage ( pathAddressPairs: keystorePars. pathAddressPairs)
63
60
if keystorePars. rootPath == nil {
64
61
keystorePars. rootPath = HDNode . defaultPathPrefix
65
62
}
@@ -74,6 +71,7 @@ public class BIP32Keystore: AbstractKeystore {
74
71
}
75
72
76
73
public init ? ( seed: Data , password: String = " web3swift " , prefixPath: String = HDNode . defaultPathMetamaskPrefix, aesMode: String = " aes-128-cbc " ) throws {
74
+ addressStorage = PathAddressStorage ( )
77
75
guard let rootNode = HDNode ( seed: seed) ? . derive ( path: prefixPath, derivePrivateKey: true ) else { return nil }
78
76
self . rootPrefix = prefixPath
79
77
try createNewAccount ( parentNode: rootNode, password: password)
@@ -93,7 +91,7 @@ public class BIP32Keystore: AbstractKeystore {
93
91
94
92
func createNewAccount( parentNode: HDNode , password: String = " web3swift " ) throws {
95
93
var newIndex = UInt32 ( 0 )
96
- for (p , _ ) in paths {
94
+ for p in addressStorage . paths {
97
95
guard let idx = UInt32 ( p. components ( separatedBy: " / " ) . last!) else { continue }
98
96
if idx >= newIndex {
99
97
newIndex = idx + 1
@@ -108,7 +106,7 @@ public class BIP32Keystore: AbstractKeystore {
108
106
} else {
109
107
newPath = prefixPath + " / " + String( newNode. index)
110
108
}
111
- paths [ newPath ] = newAddress
109
+ addressStorage . add ( address : newAddress, for : newPath )
112
110
}
113
111
114
112
public func createNewCustomChildAccount( password: String = " web3swift " , path: String ) throws {
@@ -143,7 +141,7 @@ public class BIP32Keystore: AbstractKeystore {
143
141
} else {
144
142
newPath = prefixPath + " / " + pathAppendix!
145
143
}
146
- paths [ newPath ] = newAddress
144
+ addressStorage . add ( address : newAddress, for : newPath )
147
145
guard let serializedRootNode = rootNode. serialize ( serializePublic: false ) else { throw AbstractKeystoreError . keyDerivationError}
148
146
try encryptDataToStorage ( password, data: serializedRootNode, aesMode: self . keystoreParams!. crypto. cipher)
149
147
}
@@ -183,12 +181,8 @@ public class BIP32Keystore: AbstractKeystore {
183
181
let kdfparams = KdfParamsV3 ( salt: saltData. toHexString ( ) , dklen: dkLen, n: N, p: P, r: R, c: nil , prf: nil )
184
182
let cipherparams = CipherParamsV3 ( iv: IV . toHexString ( ) )
185
183
let crypto = CryptoParamsV3 ( ciphertext: encryptedKeyData. toHexString ( ) , cipher: aesMode, cipherparams: cipherparams, kdf: " scrypt " , kdfparams: kdfparams, mac: mac. toHexString ( ) , version: nil )
186
- var pathToAddress = [ String: String] ( )
187
- for (path, address) in paths {
188
- pathToAddress [ path] = address. address
189
- }
190
184
var keystorePars = KeystoreParamsBIP32 ( crypto: crypto, id: UUID ( ) . uuidString. lowercased ( ) , version: 3 )
191
- keystorePars. pathToAddress = pathToAddress
185
+ keystorePars. pathAddressPairs = addressStorage . toPathAddressPairs ( )
192
186
keystorePars. rootPath = self . rootPrefix
193
187
keystoreParams = keystorePars
194
188
}
0 commit comments