Skip to content

Commit a9ed5cd

Browse files
Merge branch 'develop' into develop-6od9i
2 parents d76e6ee + 7876390 commit a9ed5cd

File tree

2 files changed

+43
-69
lines changed

2 files changed

+43
-69
lines changed

Sources/Web3Core/KeystoreManager/BIP32Keystore.swift

Lines changed: 34 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ 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
}
@@ -160,101 +161,74 @@ public class BIP32Keystore: AbstractKeystore {
160161
}
161162

162163
public func createNewCustomChildAccount(password: String, path: String) throws {
163-
guard let decryptedRootNode = try getPrefixNodeData(password) else {
164+
guard let decryptedRootNode = try getPrefixNodeData(password),
165+
let keystoreParams = keystoreParams else {
164166
throw AbstractKeystoreError.encryptionError("Failed to decrypt a keystore")
165167
}
166168
guard let rootNode = HDNode(decryptedRootNode) else {
167169
throw AbstractKeystoreError.encryptionError("Failed to deserialize a root node")
168170
}
171+
169172
let prefixPath = self.rootPrefix
170173
var pathAppendix: String?
174+
171175
if path.hasPrefix(prefixPath) {
172-
let upperIndex = (path.range(of: prefixPath)?.upperBound)!
173-
if upperIndex < path.endIndex {
176+
if let upperIndex = (path.range(of: prefixPath)?.upperBound), upperIndex < path.endIndex {
174177
pathAppendix = String(path[path.index(after: upperIndex)..<path.endIndex])
175178
} else {
176179
throw AbstractKeystoreError.encryptionError("out of bounds")
177180
}
178181

179-
guard pathAppendix != nil else {
182+
guard var pathAppendix = pathAppendix else {
180183
throw AbstractKeystoreError.encryptionError("Derivation depth mismatch")
181184
}
182-
if pathAppendix!.hasPrefix("/") {
183-
pathAppendix = pathAppendix?.trimmingCharacters(in: CharacterSet.init(charactersIn: "/"))
185+
if pathAppendix.hasPrefix("/") {
186+
pathAppendix = pathAppendix.trimmingCharacters(in: CharacterSet.init(charactersIn: "/"))
184187
}
185-
} else {
186-
if path.hasPrefix("/") {
187-
pathAppendix = path.trimmingCharacters(in: CharacterSet.init(charactersIn: "/"))
188-
}
189-
}
190-
guard pathAppendix != nil else {
191-
throw AbstractKeystoreError.encryptionError("Derivation depth mismatch")
188+
} else if path.hasPrefix("/") {
189+
pathAppendix = path.trimmingCharacters(in: CharacterSet.init(charactersIn: "/"))
192190
}
193-
guard rootNode.depth == prefixPath.components(separatedBy: "/").count - 1 else {
191+
192+
guard let pathAppendix = pathAppendix,
193+
rootNode.depth == prefixPath.components(separatedBy: "/").count - 1 else {
194194
throw AbstractKeystoreError.encryptionError("Derivation depth mismatch")
195195
}
196-
guard let newNode = rootNode.derive(path: pathAppendix!, derivePrivateKey: true) else {
197-
throw AbstractKeystoreError.keyDerivationError
198-
}
199-
guard let newAddress = Utilities.publicToAddress(newNode.publicKey) else {
196+
197+
guard let newNode = rootNode.derive(path: pathAppendix, derivePrivateKey: true),
198+
let newAddress = Utilities.publicToAddress(newNode.publicKey) else {
200199
throw AbstractKeystoreError.keyDerivationError
201200
}
201+
202202
var newPath: String
203203
if newNode.isHardened {
204-
newPath = prefixPath + "/" + pathAppendix!.trimmingCharacters(in: CharacterSet.init(charactersIn: "'")) + "'"
204+
newPath = prefixPath + "/" + pathAppendix.trimmingCharacters(in: CharacterSet.init(charactersIn: "'")) + "'"
205205
} else {
206-
newPath = prefixPath + "/" + pathAppendix!
206+
newPath = prefixPath + "/" + pathAppendix
207207
}
208+
208209
addressStorage.add(address: newAddress, for: newPath)
209210
guard let serializedRootNode = rootNode.serialize(serializePublic: false) else {throw AbstractKeystoreError.keyDerivationError}
210-
try encryptDataToStorage(password, data: serializedRootNode, aesMode: self.keystoreParams!.crypto.cipher)
211+
try encryptDataToStorage(password, data: serializedRootNode, aesMode: keystoreParams.crypto.cipher)
211212
}
212213

213214
/// Fast generation addresses for current account
214-
/// used for shows which address user will get when changed number of his wallet
215+
/// used to show which addresses the user can get for indices from `0` to `number-1`
215216
/// - Parameters:
216217
/// - password: password of seed storage
217-
/// - number: number of wallets addresses needed to generate from 0 to number-1
218-
/// - Returns: Array of addresses generated from 0 to number bound, or empty array in case of error
219-
public func getAddressForAccount(password: String, number: Int) -> [EthereumAddress] {
220-
guard let decryptedRootNode = try? getPrefixNodeData(password) else {
221-
return []
222-
}
223-
guard let rootNode = HDNode(decryptedRootNode) else {
224-
return []
218+
/// - number: number of wallets addresses needed to generate from `0` to `number-1`
219+
/// - Returns: Array of addresses generated from `0` to number bound
220+
public func getAddressForAccount(password: String, number: UInt) throws -> [EthereumAddress] {
221+
guard let decryptedRootNode = try? getPrefixNodeData(password),
222+
let rootNode = HDNode(decryptedRootNode) else {
223+
throw AbstractKeystoreError.encryptionError("Failed to decrypt a keystore")
225224
}
226-
let prefixPath = self.rootPrefix
227-
var pathAppendix: String?
228225

229-
return [Int](0..<number).compactMap({ number in
230-
pathAppendix = nil
231-
let path = prefixPath + "/\(number)"
232-
if path.hasPrefix(prefixPath) {
233-
let upperIndex = (path.range(of: prefixPath)?.upperBound)!
234-
if upperIndex < path.endIndex {
235-
pathAppendix = String(path[path.index(after: upperIndex)..<path.endIndex])
236-
} else {
237-
return nil
238-
}
239-
240-
guard pathAppendix != nil else {
241-
return nil
242-
}
243-
if pathAppendix!.hasPrefix("/") {
244-
pathAppendix = pathAppendix?.trimmingCharacters(in: CharacterSet.init(charactersIn: "/"))
245-
}
246-
} else {
247-
if path.hasPrefix("/") {
248-
pathAppendix = path.trimmingCharacters(in: CharacterSet.init(charactersIn: "/"))
249-
}
250-
}
251-
guard pathAppendix != nil,
252-
rootNode.depth == prefixPath.components(separatedBy: "/").count - 1,
253-
let newNode = rootNode.derive(path: pathAppendix!, derivePrivateKey: true),
254-
let newAddress = Utilities.publicToAddress(newNode.publicKey) else {
255-
return nil
226+
return try [UInt](0..<number).compactMap({ number in
227+
guard rootNode.depth == rootPrefix.components(separatedBy: "/").count - 1,
228+
let newNode = rootNode.derive(path: "\(number)", derivePrivateKey: true) else {
229+
throw AbstractKeystoreError.keyDerivationError
256230
}
257-
return newAddress
231+
return Utilities.publicToAddress(newNode.publicKey)
258232
})
259233
}
260234

Tests/web3swiftTests/localTests/BIP32KeystoreTests.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ class BIP32KeystoreTests: XCTestCase {
1616
/// Seed randomly generated for this test
1717
let mnemonic = "resource beyond merit enemy foot piece reveal eagle nothing luggage goose spot"
1818
let password = "test_password"
19-
20-
let addressesCount = 101
21-
19+
20+
let addressesCount: UInt = 101
21+
2222
guard let keystore = try BIP32Keystore(
2323
mnemonics: mnemonic,
2424
password: password,
@@ -28,12 +28,12 @@ class BIP32KeystoreTests: XCTestCase {
2828
XCTFail("Keystore has not generated")
2929
throw NSError(domain: "0", code: 0)
3030
}
31-
32-
let addresses = keystore.getAddressForAccount(password: password,
33-
number: addressesCount)
34-
XCTAssertEqual(addresses.count, addressesCount)
31+
32+
let addresses = try keystore.getAddressForAccount(password: password,
33+
number: addressesCount)
34+
XCTAssertEqual(UInt(addresses.count), addressesCount)
3535
XCTAssertNotEqual(addresses[11], addresses[1])
36-
36+
3737
guard let sameKeystore = try BIP32Keystore(
3838
mnemonics: mnemonic,
3939
password: password,
@@ -43,7 +43,7 @@ class BIP32KeystoreTests: XCTestCase {
4343
XCTFail("Keystore has not generated")
4444
throw NSError(domain: "0", code: 0)
4545
}
46-
46+
4747
let walletNumber = addressesCount - 1
4848
try sameKeystore.createNewCustomChildAccount(password: password,
4949
path: HDNode.defaultPathMetamaskPrefix + "/\(walletNumber)")

0 commit comments

Comments
 (0)