@@ -149,14 +149,17 @@ public class BIP32Keystore: AbstractKeystore {
149149 } else {
150150 newIndex = UInt32 . zero
151151 }
152+
152153 guard let newNode = parentNode. derive ( index: newIndex, derivePrivateKey: true , hardened: false ) else {
153154 throw AbstractKeystoreError . keyDerivationError
154155 }
155156 guard let newAddress = Utilities . publicToAddress ( newNode. publicKey) else {
156157 throw AbstractKeystoreError . keyDerivationError
157158 }
159+
158160 let prefixPath = self . rootPrefix
159161 var newPath : String
162+
160163 if newNode. isHardened {
161164 newPath = prefixPath + " / " + String( newNode. index % HDNode. hardenedIndexPrefix) + " ' "
162165 } else {
@@ -166,101 +169,75 @@ public class BIP32Keystore: AbstractKeystore {
166169 }
167170
168171 public func createNewCustomChildAccount( password: String , path: String ) throws {
169- guard let decryptedRootNode = try getPrefixNodeData ( password) else {
172+ guard let decryptedRootNode = try getPrefixNodeData ( password) ,
173+ let keystoreParams = keystoreParams else {
170174 throw AbstractKeystoreError . encryptionError ( " Failed to decrypt a keystore " )
171175 }
172176 guard let rootNode = HDNode ( decryptedRootNode) else {
173177 throw AbstractKeystoreError . encryptionError ( " Failed to deserialize a root node " )
174178 }
179+
175180 let prefixPath = self . rootPrefix
176181 var pathAppendix : String ?
182+
177183 if path. hasPrefix ( prefixPath) {
178- let upperIndex = ( path. range ( of: prefixPath) ? . upperBound) !
179- if upperIndex < path. endIndex {
184+ if let upperIndex = ( path. range ( of: prefixPath) ? . upperBound) , upperIndex < path. endIndex {
180185 pathAppendix = String ( path [ path. index ( after: upperIndex) ..< path. endIndex] )
181186 } else {
182187 throw AbstractKeystoreError . encryptionError ( " out of bounds " )
183188 }
184189
185- guard pathAppendix != nil else {
190+ guard var pathAppendix = pathAppendix else {
186191 throw AbstractKeystoreError . encryptionError ( " Derivation depth mismatch " )
187192 }
188- if pathAppendix!. hasPrefix ( " / " ) {
189- pathAppendix = pathAppendix? . trimmingCharacters ( in: CharacterSet . init ( charactersIn: " / " ) )
190- }
191- } else {
192- if path. hasPrefix ( " / " ) {
193- pathAppendix = path. trimmingCharacters ( in: CharacterSet . init ( charactersIn: " / " ) )
193+ if pathAppendix. hasPrefix ( " / " ) {
194+ pathAppendix = pathAppendix. trimmingCharacters ( in: CharacterSet . init ( charactersIn: " / " ) )
194195 }
196+ } else if path. hasPrefix ( " / " ) {
197+ pathAppendix = path. trimmingCharacters ( in: CharacterSet . init ( charactersIn: " / " ) )
195198 }
196- guard pathAppendix != nil else {
197- throw AbstractKeystoreError . encryptionError ( " Derivation depth mismatch " )
198- }
199- guard rootNode. depth == prefixPath. components ( separatedBy: " / " ) . count - 1 else {
199+
200+ guard let pathAppendix = pathAppendix,
201+ rootNode. depth == prefixPath. components ( separatedBy: " / " ) . count - 1 else {
200202 throw AbstractKeystoreError . encryptionError ( " Derivation depth mismatch " )
201203 }
202- guard let newNode = rootNode. derive ( path: pathAppendix!, derivePrivateKey: true ) else {
203- throw AbstractKeystoreError . keyDerivationError
204- }
205- guard let newAddress = Utilities . publicToAddress ( newNode. publicKey) else {
204+
205+ guard let newNode = rootNode. derive ( path: pathAppendix, derivePrivateKey: true ) ,
206+ let newAddress = Utilities . publicToAddress ( newNode. publicKey) else {
206207 throw AbstractKeystoreError . keyDerivationError
207208 }
209+
208210 var newPath : String
209211 if newNode. isHardened {
210- newPath = prefixPath + " / " + pathAppendix! . trimmingCharacters ( in: CharacterSet . init ( charactersIn: " ' " ) ) + " ' "
212+ newPath = prefixPath + " / " + pathAppendix. trimmingCharacters ( in: CharacterSet . init ( charactersIn: " ' " ) ) + " ' "
211213 } else {
212- newPath = prefixPath + " / " + pathAppendix!
214+ newPath = prefixPath + " / " + pathAppendix
213215 }
216+
214217 addressStorage. add ( address: newAddress, for: newPath)
215218 guard let serializedRootNode = rootNode. serialize ( serializePublic: false ) else { throw AbstractKeystoreError . keyDerivationError}
216- try encryptDataToStorage ( password, data: serializedRootNode, aesMode: self . keystoreParams! . crypto. cipher)
219+ try encryptDataToStorage ( password, data: serializedRootNode, aesMode: keystoreParams. crypto. cipher)
217220 }
218221
219222 /// Fast generation addresses for current account
220- /// used for shows which address user will get when changed number of his wallet
223+ /// used to show which addresses the user can get for indices from `0` to `number-1`
221224 /// - Parameters:
222225 /// - password: password of seed storage
223- /// - number: number of wallets addresses needed to generate from 0 to number-1
224- /// - Returns: Array of addresses generated from 0 to number bound, or empty array in case of error
225- public func getAddressForAccount( password: String , number: Int ) -> [ EthereumAddress ] {
226- guard let decryptedRootNode = try ? getPrefixNodeData ( password) else {
227- return [ ]
228- }
229- guard let rootNode = HDNode ( decryptedRootNode) else {
230- return [ ]
226+ /// - number: number of wallets addresses needed to generate from `0` to `number-1`
227+ /// - Returns: Array of addresses generated from `0` to number bound
228+ public func getAddressForAccount( password: String , number: UInt ) throws -> [ EthereumAddress ] {
229+ guard let decryptedRootNode = try ? getPrefixNodeData ( password) ,
230+ let rootNode = HDNode ( decryptedRootNode) else {
231+ throw AbstractKeystoreError . encryptionError ( " Failed to decrypt a keystore " )
231232 }
232- let prefixPath = self . rootPrefix
233233
234- return [ Int] ( 0 ..< number) . compactMap { number in
235- var pathAppendix : String ?
236- let path = prefixPath + " / \( number) "
237- if path. hasPrefix ( prefixPath) {
238- let upperIndex = ( path. range ( of: prefixPath) ? . upperBound) !
239- if upperIndex < path. endIndex {
240- pathAppendix = String ( path [ path. index ( after: upperIndex) ..< path. endIndex] )
241- } else {
242- return nil
243- }
244-
245- guard pathAppendix != nil else {
246- return nil
247- }
248- if pathAppendix!. hasPrefix ( " / " ) {
249- pathAppendix = pathAppendix? . trimmingCharacters ( in: CharacterSet . init ( charactersIn: " / " ) )
250- }
251- } else {
252- if path. hasPrefix ( " / " ) {
253- pathAppendix = path. trimmingCharacters ( in: CharacterSet . init ( charactersIn: " / " ) )
254- }
234+ return try [ UInt] ( 0 ..< number) . compactMap ( { number in
235+ guard rootNode. depth == rootPrefix. components ( separatedBy: " / " ) . count - 1 ,
236+ let newNode = rootNode. derive ( path: " \( number) " , derivePrivateKey: true ) else {
237+ throw AbstractKeystoreError . keyDerivationError
255238 }
256- guard pathAppendix != nil ,
257- rootNode. depth == prefixPath. components ( separatedBy: " / " ) . count - 1 ,
258- let newNode = rootNode. derive ( path: pathAppendix!, derivePrivateKey: true ) ,
259- let newAddress = Utilities . publicToAddress ( newNode. publicKey) else {
260- return nil
261- }
262- return newAddress
263- }
239+ return Utilities . publicToAddress ( newNode. publicKey)
240+ } )
264241 }
265242
266243 fileprivate func encryptDataToStorage( _ password: String , data: Data , dkLen: Int = 32 , N: Int = 4096 , R: Int = 6 , P: Int = 1 , aesMode: String = " aes-128-cbc " ) throws {
0 commit comments