Skip to content

Commit

Permalink
Merge pull request #279 from tangem/IOS-3574_derivedkeys_serialization
Browse files Browse the repository at this point in the history
Serialize derivedKeys as object
  • Loading branch information
tureck1y authored May 10, 2023
2 parents c2b460c + 2a2d69d commit 7c0c3ef
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 19 deletions.
4 changes: 4 additions & 0 deletions TangemSdk/TangemSdk.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@
DC59CB0A29AF6F9C00EC14E1 /* EntropyLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC59CB0929AF6F9C00EC14E1 /* EntropyLength.swift */; };
DC59CB0C29AF706100EC14E1 /* MnemonicError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC59CB0B29AF706100EC14E1 /* MnemonicError.swift */; };
DC59CB0E29AF70C700EC14E1 /* Mnemonic.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC59CB0D29AF70C700EC14E1 /* Mnemonic.swift */; };
DC7254902A03E20A0003FE1B /* DerivedKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC72548F2A03E20A0003FE1B /* DerivedKeys.swift */; };
DC8B0E3F286F221D009D64F7 /* BiometricsUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC8B0E3E286F221D009D64F7 /* BiometricsUtil.swift */; };
DCA9706628E35EAD0046E62E /* GenerateOTPCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA9706528E35EAD0046E62E /* GenerateOTPCommand.swift */; };
DCC0A21129D3146100C45B13 /* SetUserSettingsCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCC0A21029D3146100C45B13 /* SetUserSettingsCommand.swift */; };
Expand Down Expand Up @@ -661,6 +662,7 @@
DC59CB0929AF6F9C00EC14E1 /* EntropyLength.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntropyLength.swift; sourceTree = "<group>"; };
DC59CB0B29AF706100EC14E1 /* MnemonicError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MnemonicError.swift; sourceTree = "<group>"; };
DC59CB0D29AF70C700EC14E1 /* Mnemonic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mnemonic.swift; sourceTree = "<group>"; };
DC72548F2A03E20A0003FE1B /* DerivedKeys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DerivedKeys.swift; sourceTree = "<group>"; };
DC8B0E3E286F221D009D64F7 /* BiometricsUtil.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BiometricsUtil.swift; sourceTree = "<group>"; };
DCA9706528E35EAD0046E62E /* GenerateOTPCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenerateOTPCommand.swift; sourceTree = "<group>"; };
DCC0A21029D3146100C45B13 /* SetUserSettingsCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetUserSettingsCommand.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1427,6 +1429,7 @@
5D379C26268FA47600C7F473 /* EncryptionMode.swift */,
5D270F2426A0199100D2EDC1 /* WalletData.swift */,
DCC0A21529D3216100C45B13 /* UserSettings.swift */,
DC72548F2A03E20A0003FE1B /* DerivedKeys.swift */,
);
path = Card;
sourceTree = "<group>";
Expand Down Expand Up @@ -1838,6 +1841,7 @@
5D2F3EE526CBDAA100779CAC /* KeyboardAdaptive.swift in Sources */,
5D7D5FB223449D4000058D69 /* SessionEnvironment.swift in Sources */,
5D2FE06324DD82750086B5E8 /* AttestCardKeyCommand.swift in Sources */,
DC7254902A03E20A0003FE1B /* DerivedKeys.swift in Sources */,
DC1244E229BB7B390037BC05 /* WIF.swift in Sources */,
5D539ECB276CDD8600AB8B53 /* DeriveMultipleWalletPublicKeysTask.swift in Sources */,
DA6C752A292682650070EEFD /* LAContext+.swift in Sources */,
Expand Down
64 changes: 64 additions & 0 deletions TangemSdk/TangemSdk/Common/Card/DerivedKeys.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// DerivedKeys.swift
// TangemSdk
//
// Created by Alexander Osokin on 04.05.2023.
// Copyright © 2023 Tangem AG. All rights reserved.
//

import Foundation

// We can't use CodingKeyRepresentable because of iOS 15 version
@available(iOS 13.0, *)
public struct DerivedKeys: JSONStringConvertible {
public private(set) var keys: [DerivationPath:ExtendedPublicKey]

public init(keys: [DerivationPath : ExtendedPublicKey]) {
self.keys = keys
}

public subscript(_ path: DerivationPath) -> ExtendedPublicKey? {
get {
return keys[path]
}
set(newValue) {
keys[path] = newValue
}
}
}

@available(iOS 13.0, *)
extension DerivedKeys: Codable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let stringDictionary = try container.decode([String: ExtendedPublicKey].self)

let keysDictionary: [DerivationPath: ExtendedPublicKey] = try stringDictionary.reduce(into: [:]) { partialResult, item in
let path = try DerivationPath(rawPath: item.key)
partialResult[path] = item.value
}

self.init(keys: keysDictionary)
}

public func encode(to encoder: Encoder) throws {
let stringDictionary = keys.reduce(into: [:]) { partialResult, item in
partialResult[item.key.rawPath] = item.value
}

var container = encoder.singleValueContainer()
try container.encode(stringDictionary)
}
}


@available(iOS 13.0, *)
extension DerivedKeys: ExpressibleByDictionaryLiteral {
public init(dictionaryLiteral elements: (DerivationPath, ExtendedPublicKey)...) {
let dictionary = elements.reduce(into: [:]) { partialResult, item in
partialResult[item.0] = item.1
}

self.init(keys: dictionary)
}
}
2 changes: 1 addition & 1 deletion TangemSdk/TangemSdk/Common/Card/Wallet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public extension Card {
/// Does this wallet has a backup
public var hasBackup: Bool
/// Derived keys according to `Config.defaultDerivationPaths`
public var derivedKeys: [DerivationPath:ExtendedPublicKey] = [:]
public var derivedKeys: DerivedKeys = [:]
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation

@available(iOS 13.0, *)
public class DeriveMultipleWalletPublicKeysTask: CardSessionRunnable {
public typealias Response = [Data: [DerivationPath:ExtendedPublicKey]]
public typealias Response = [Data: DerivedKeys]

private let derivations: Array<(Data,[DerivationPath])>
private var response: Response = .init()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import Foundation

@available(iOS 13.0, *)
public class DeriveWalletPublicKeysTask: CardSessionRunnable {
public typealias Response = [DerivationPath:ExtendedPublicKey]
private let walletPublicKey: Data
private let derivationPaths: [DerivationPath]

Expand All @@ -28,11 +27,11 @@ public class DeriveWalletPublicKeysTask: CardSessionRunnable {
Log.debug("DeriveWalletPublicKeysTask deinit")
}

public func run(in session: CardSession, completion: @escaping CompletionResult<Response>) {
public func run(in session: CardSession, completion: @escaping CompletionResult<DerivedKeys>) {
runDerivation(at: 0, keys: [:], in: session, completion: completion)
}

private func runDerivation(at index: Int, keys: [DerivationPath:ExtendedPublicKey], in session: CardSession, completion: @escaping CompletionResult<Response>) {
private func runDerivation(at index: Int, keys: DerivedKeys, in session: CardSession, completion: @escaping CompletionResult<DerivedKeys>) {
guard index < derivationPaths.count else {
completion(.success(keys))
return
Expand All @@ -51,6 +50,3 @@ public class DeriveWalletPublicKeysTask: CardSessionRunnable {
}
}
}

@available(iOS 13.0, *)
extension DeriveWalletPublicKeysTask.Response: JSONStringConvertible {}
4 changes: 2 additions & 2 deletions TangemSdk/TangemSdk/TangemSdk.swift
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,12 @@ public extension TangemSdk {
/// - walletPublicKey: Seed public key.
/// - derivationPaths: Derivation paths. Repeated items will be ignored.
/// - initialMessage: A custom description that shows at the beginning of the NFC session. If nil, default message will be used
/// - completion: Returns `Swift.Result<[ExtendedPublicKey],TangemSdkError>`. All derived keys are unique and will be returned in arbitrary order.
/// - completion: Returns `Swift.Result<DerivedKeys,TangemSdkError>`. All derived keys are unique and will be returned in arbitrary order.
func deriveWalletPublicKeys(cardId: String,
walletPublicKey: Data,
derivationPaths: [DerivationPath],
initialMessage: Message? = nil,
completion: @escaping CompletionResult<[DerivationPath:ExtendedPublicKey]>) {
completion: @escaping CompletionResult<DerivedKeys>) {
let command = DeriveWalletPublicKeysTask(walletPublicKey: walletPublicKey, derivationPaths: derivationPaths)
startSession(with: command, cardId: cardId, initialMessage: initialMessage, completion: completion)
}
Expand Down
6 changes: 3 additions & 3 deletions TangemSdk/TangemSdkTests/JSONRPCTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,11 @@ class JSONRPCTests: XCTestCase {
}

func testDerivePublicKeys() {
let result = ["m/44'/0'" : ExtendedPublicKey(publicKey: Data(hexString: "0200300397571D99D41BB2A577E2CBE495C04AC5B9A97B7A4ECF999F23CE45E962"),
let keys = [try! DerivationPath(rawPath: "m/44'/0'") : ExtendedPublicKey(publicKey: Data(hexString: "0200300397571D99D41BB2A577E2CBE495C04AC5B9A97B7A4ECF999F23CE45E962"),
chainCode: Data(hexString: "537F7361175B150732E17508066982B42D9FB1F8239C4D7BFC490088C83A8BBB")),
"m/44'/1'" : ExtendedPublicKey(publicKey: Data(hexString: "0200300397571D99D41BB2A577E2CBE495C04AC5B9A97B7A4ECF999F23CE45E962"),
try! DerivationPath(rawPath: "m/44'/1'") : ExtendedPublicKey(publicKey: Data(hexString: "0200300397571D99D41BB2A577E2CBE495C04AC5B9A97B7A4ECF999F23CE45E962"),
chainCode: Data(hexString: "537F7361175B150732E17508066982B42D9FB1F8239C4D7BFC490088C83A8BBB"))]

let result = DerivedKeys(keys: keys)
testMethod(name: "DeriveWalletPublicKeys", result: result)
}

Expand Down
6 changes: 3 additions & 3 deletions TangemSdk/TangemSdkTests/Jsons/Card.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"index" : 0,
"hasBackup" : false,
"isImported": false,
"derivedKeys" : []
"derivedKeys" : {}
},
{
"publicKey" : "0440C533E007D029C1F345CA70A9F6016EC7A95C775B6320AE84248F20B647FBBD90FF56A2D9C3A1984279ED2367274A49079789E130444541C2F15907D5570B49",
Expand All @@ -77,7 +77,7 @@
"index" : 1,
"hasBackup" : false,
"isImported": false,
"derivedKeys" : []
"derivedKeys" : {}
},
{
"publicKey" : "04DDFACEF55A95EAB2CDCC8E86CE779342D2E2A53CF8F0F20BF2B248336AE3EEA6DD62D1F4C5420A71D6212073B136034CDC878DAD3AE3FDFA3360E6FE6184F470",
Expand All @@ -89,7 +89,7 @@
"index" : 2,
"hasBackup" : false,
"isImported": false,
"derivedKeys" : []
"derivedKeys" : {}
}
],
"isPasscodeSet" : true,
Expand Down
2 changes: 1 addition & 1 deletion TangemSdk/TangemSdkTests/Jsons/CreateWallet.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"index": 1,
"hasBackup" : false,
"isImported": false,
"derivedKeys" : []
"derivedKeys" : {}
}
},
"id" : 1
Expand Down
2 changes: 1 addition & 1 deletion TangemSdk/TangemSdkTests/Jsons/ImportWalletMnemonic.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"index": 1,
"hasBackup" : false,
"isImported": false,
"derivedKeys" : []
"derivedKeys" : {}
}
},
"id" : 1
Expand Down
2 changes: 1 addition & 1 deletion TangemSdk/TangemSdkTests/Jsons/ImportWalletSeed.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"index": 1,
"hasBackup" : false,
"isImported": false,
"derivedKeys" : []
"derivedKeys" : {}
}
},
"id" : 1
Expand Down

0 comments on commit 7c0c3ef

Please sign in to comment.