Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serialize derivedKeys as object #279

Merged
merged 1 commit into from
May 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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