MnemonicSwift added to the project

MnemonicSwift SPM added + implementation of the MnemonicSeedPhraseHandling protocol

TCA syntax for the MnemonicSeedPhaseProvider

swiftlint disable not needed anymore

double space fixed
This commit is contained in:
Lukas Korba 2022-03-10 13:28:25 +01:00
parent d9977ef3a0
commit 4660b41b7b
6 changed files with 124 additions and 83 deletions

View File

@ -17,7 +17,6 @@
0D2ACE8026C2C67100D62E3C /* Zboto.otf in Resources */ = {isa = PBXBuildFile; fileRef = 0D2ACE7F26C2C67100D62E3C /* Zboto.otf */; };
0D354A0926D5A9D000315F45 /* Services.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D354A0626D5A9D000315F45 /* Services.swift */; };
0D354A0A26D5A9D000315F45 /* KeyStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D354A0726D5A9D000315F45 /* KeyStoring.swift */; };
0D354A0B26D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D354A0826D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift */; };
0D35CC46277A36E00074316A /* ScrollableWhenScaled.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D35CC45277A36E00074316A /* ScrollableWhenScaled.swift */; };
0D3D04082728B3440032ABC1 /* RecoveryPhraseDisplayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D3D04072728B3440032ABC1 /* RecoveryPhraseDisplayView.swift */; };
0D3D040A2728B3A10032ABC1 /* RecoveryPhraseDisplayStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D3D04092728B3A10032ABC1 /* RecoveryPhraseDisplayStore.swift */; };
@ -81,6 +80,8 @@
66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */; };
66D50668271D9B6100E51F0D /* NavigationButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */; };
66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */; };
9E2AC0FF27D8EC120042AA47 /* MnemonicSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9E2AC0FE27D8EC120042AA47 /* MnemonicSwift */; };
9E2AC10127D8EF0B0042AA47 /* MnemonicSeedPhraseProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2AC10027D8EF0B0042AA47 /* MnemonicSeedPhraseProvider.swift */; };
9E2DF99C27CF704D00649636 /* ImportWalletStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99827CF704D00649636 /* ImportWalletStore.swift */; };
9E2DF99D27CF704D00649636 /* ImportSeedEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */; };
9E2DF99E27CF704D00649636 /* ImportWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E2DF99B27CF704D00649636 /* ImportWalletView.swift */; };
@ -145,7 +146,6 @@
0D2ACE7F26C2C67100D62E3C /* Zboto.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Zboto.otf; sourceTree = "<group>"; };
0D354A0626D5A9D000315F45 /* Services.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Services.swift; sourceTree = "<group>"; };
0D354A0726D5A9D000315F45 /* KeyStoring.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyStoring.swift; sourceTree = "<group>"; };
0D354A0826D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MnemonicSeedPhraseHandling.swift; sourceTree = "<group>"; };
0D35CC45277A36E00074316A /* ScrollableWhenScaled.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollableWhenScaled.swift; sourceTree = "<group>"; };
0D3D04072728B3440032ABC1 /* RecoveryPhraseDisplayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseDisplayView.swift; sourceTree = "<group>"; };
0D3D04092728B3A10032ABC1 /* RecoveryPhraseDisplayStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecoveryPhraseDisplayStore.swift; sourceTree = "<group>"; };
@ -214,6 +214,7 @@
66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingProgressIndicator.swift; sourceTree = "<group>"; };
66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationButtonStyle.swift; sourceTree = "<group>"; };
66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardButtonStyle.swift; sourceTree = "<group>"; };
9E2AC10027D8EF0B0042AA47 /* MnemonicSeedPhraseProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MnemonicSeedPhraseProvider.swift; sourceTree = "<group>"; };
9E2DF99827CF704D00649636 /* ImportWalletStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletStore.swift; sourceTree = "<group>"; };
9E2DF99A27CF704D00649636 /* ImportSeedEditor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportSeedEditor.swift; sourceTree = "<group>"; };
9E2DF99B27CF704D00649636 /* ImportWalletView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportWalletView.swift; sourceTree = "<group>"; };
@ -255,6 +256,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9E2AC0FF27D8EC120042AA47 /* MnemonicSwift in Frameworks */,
6654C73A2715A38000901167 /* ComposableArchitecture in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -296,7 +298,6 @@
isa = PBXGroup;
children = (
0D354A0726D5A9D000315F45 /* KeyStoring.swift */,
0D354A0826D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift */,
0D354A0626D5A9D000315F45 /* Services.swift */,
);
path = MockedDependencies;
@ -499,6 +500,7 @@
F9EEB8152742C2210032EEB8 /* WithStateBinding.swift */,
F93673D52742CB840099C6AF /* Previews.swift */,
0D35CC45277A36E00074316A /* ScrollableWhenScaled.swift */,
9E2AC10027D8EF0B0042AA47 /* MnemonicSeedPhraseProvider.swift */,
);
path = Util;
sourceTree = "<group>";
@ -855,6 +857,7 @@
name = "secant-testnet";
packageProductDependencies = (
6654C7392715A38000901167 /* ComposableArchitecture */,
9E2AC0FE27D8EC120042AA47 /* MnemonicSwift */,
);
productName = secant;
productReference = 0D4E7A0526B364170058B01E /* secant-testnet.app */;
@ -929,6 +932,7 @@
mainGroup = 0D4E79FC26B364170058B01E;
packageReferences = (
6654C7382715A38000901167 /* XCRemoteSwiftPackageReference "swift-composable-architecture" */,
9E2AC0FD27D8EC120042AA47 /* XCRemoteSwiftPackageReference "MnemonicSwift" */,
);
productRefGroup = 0D4E7A0626B364170058B01E /* Products */;
projectDirPath = "";
@ -1047,7 +1051,6 @@
0DACFA7F27208CE00039EEA5 /* Clamped.swift in Sources */,
0DFE93E3272CA1AA000FCCA5 /* RecoveryPhraseValidation.swift in Sources */,
9E2DF99E27CF704D00649636 /* ImportWalletView.swift in Sources */,
0D354A0B26D5A9D000315F45 /* MnemonicSeedPhraseHandling.swift in Sources */,
0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */,
6654C73E2715A41300901167 /* OnboardingStore.swift in Sources */,
9EBEF87A27CE369800B4F343 /* RecoveryPhraseTestPreambleView.swift in Sources */,
@ -1078,6 +1081,7 @@
66D50668271D9B6100E51F0D /* NavigationButtonStyle.swift in Sources */,
0D1922F826BDEB3500052649 /* MockServices.swift in Sources */,
0D3D040A2728B3A10032ABC1 /* RecoveryPhraseDisplayStore.swift in Sources */,
9E2AC10127D8EF0B0042AA47 /* MnemonicSeedPhraseProvider.swift in Sources */,
0D4E7A0B26B364170058B01E /* ContentView.swift in Sources */,
0D354A0926D5A9D000315F45 /* Services.swift in Sources */,
660558F7270C862F009D6954 /* Fonts+Generated.swift in Sources */,
@ -1448,6 +1452,14 @@
version = 0.28.1;
};
};
9E2AC0FD27D8EC120042AA47 /* XCRemoteSwiftPackageReference "MnemonicSwift" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/zcash-hackworks/MnemonicSwift";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
@ -1456,6 +1468,11 @@
package = 6654C7382715A38000901167 /* XCRemoteSwiftPackageReference "swift-composable-architecture" */;
productName = ComposableArchitecture;
};
9E2AC0FE27D8EC120042AA47 /* MnemonicSwift */ = {
isa = XCSwiftPackageProductDependency;
package = 9E2AC0FD27D8EC120042AA47 /* XCRemoteSwiftPackageReference "MnemonicSwift" */;
productName = MnemonicSwift;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 0D4E79FD26B364170058B01E /* Project object */;

View File

@ -10,6 +10,15 @@
"version": "0.5.3"
}
},
{
"package": "MnemonicSwift",
"repositoryURL": "https://github.com/zcash-hackworks/MnemonicSwift",
"state": {
"branch": null,
"revision": "27711179a75a1172d6f04ceb5d86419cf0cba401",
"version": "2.1.0"
}
},
{
"package": "swift-case-paths",
"repositoryURL": "https://github.com/pointfreeco/swift-case-paths",
@ -37,6 +46,15 @@
"version": "0.28.1"
}
},
{
"package": "swift-crypto",
"repositoryURL": "https://github.com/apple/swift-crypto.git",
"state": {
"branch": null,
"revision": "a8911e0fadc25aef1071d582355bd1037a176060",
"version": "2.0.4"
}
},
{
"package": "swift-custom-dump",
"repositoryURL": "https://github.com/pointfreeco/swift-custom-dump",

View File

@ -1,41 +0,0 @@
//
// MnemonicSeedPhraseHandling.swift
// wallet
//
// Created by Francisco Gindre on 2/28/20.
// Copyright © 2020 Francisco Gindre. All rights reserved.
//
import Foundation
enum MnemonicError: Error {
case invalidSeed
case checksumFailed
}
protocol MnemonicSeedPhraseHandling {
/**
Random 24 words mnemonic phrase
*/
func randomMnemonic() throws -> String
/**
Random 24 words mnemonic phrase as array of words
*/
func randomMnemonicWords() throws -> [String]
/**
Generate deterministic seed from mnemonic phrase
*/
func toSeed(mnemonic: String) throws -> [UInt8]
/**
Get this mnemonic
*/
func asWords(mnemonic: String) throws -> [String]
/**
Validates whether the given mnemonic is correct
*/
func isValid(mnemonic: String) throws
}

View File

@ -9,7 +9,7 @@ import Foundation
protocol Services {
var networkProvider: ZcashNetworkProvider { get }
var seedHandler: MnemonicSeedPhraseHandling { get }
var seedHandler: MnemonicSeedPhraseProvider { get }
var keyStorage: KeyStoring { get }
}

View File

@ -7,11 +7,10 @@
// TODO: Move this to different Target when real functionality is developed.
import Foundation
// swiftlint:disable line_length
class MockServices: Services {
var networkProvider: ZcashNetworkProvider = MockNetworkProvider()
var seedHandler: MnemonicSeedPhraseHandling = MockMnemonicPhraseHandling()
var seedHandler: MnemonicSeedPhraseProvider = .mock
var keyStorage: KeyStoring = MockKeyStoring()
}
@ -22,41 +21,6 @@ class MockNetworkProvider: ZcashNetworkProvider {
}
}
class MockMnemonicPhraseHandling: MnemonicSeedPhraseHandling {
class TestSeed {
/**
Test account: "still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
*/
let seedString = Data(
base64Encoded: "9VDVOZZZOWWHpZtq1Ebridp3Qeux5C+HwiRR0g7Oi7HgnMs8Gfln83+/Q1NnvClcaSwM4ADFL1uZHxypEWlWXg=="
)!// swiftlint:disable:this force_unwrapping
func seed() -> [UInt8] {
[UInt8](seedString)
}
}
func randomMnemonic() throws -> String {
"still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
}
func randomMnemonicWords() throws -> [String] {
"still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
.components(separatedBy: " ")
}
func toSeed(mnemonic: String) throws -> [UInt8] {
TestSeed().seed()
}
func asWords(mnemonic: String) throws -> [String] {
"still champion voice habit trend flight survey between bitter process artefact blind carbon truly provide dizzy crush flush breeze blouse charge solid fish spread"
.components(separatedBy: " ")
}
func isValid(mnemonic: String) throws {}
}
class KeysPresentStub: KeyStoring {
init(returnBlock: @escaping () throws -> Bool) {
self.returnBlock = returnBlock

View File

@ -0,0 +1,83 @@
//
// MnemonicSeedPhraseProvider.swift
// secant-testnet
//
// Created by Lukáš Korba on 03/09/2022.
//
import Foundation
import MnemonicSwift
struct MnemonicSeedPhraseProvider {
/// Random 24 words mnemonic phrase
var randomMnemonic: () throws -> String
/// Random 24 words mnemonic phrase as array of words
var randomMnemonicWords: () throws -> [String]
/// Generate deterministic seed from mnemonic phrase
var toSeed: (String) throws -> [UInt8]
/// Get this mnemonic phrase as array of words
var asWords: (String) throws -> [String]
/// Validates whether the given mnemonic is correct
var isValid: (String) throws -> Void
}
extension MnemonicSeedPhraseProvider {
static let live = MnemonicSeedPhraseProvider(
randomMnemonic: {
try Mnemonic.generateMnemonic(strength: 256)
},
randomMnemonicWords: {
try Mnemonic.generateMnemonic(strength: 256).components(separatedBy: " ")
},
toSeed: { mnemonic in
let data = try Mnemonic.deterministicSeedBytes(from: mnemonic)
return [UInt8](data)
},
asWords: { mnemonic in
mnemonic.components(separatedBy: " ")
},
isValid: { mnemonic in
try Mnemonic.validate(mnemonic: mnemonic)
}
)
static let mock = MnemonicSeedPhraseProvider(
randomMnemonic: {
"""
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
"""
},
randomMnemonicWords: {
let mnemonic = """
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
"""
return mnemonic.components(separatedBy: " ")
},
toSeed: { _ in
let seedString = Data(
base64Encoded: "9VDVOZZZOWWHpZtq1Ebridp3Qeux5C+HwiRR0g7Oi7HgnMs8Gfln83+/Q1NnvClcaSwM4ADFL1uZHxypEWlWXg=="
)!// swiftlint:disable:this force_unwrapping
return [UInt8](seedString)
},
asWords: { mnemonic in
let mnemonic = """
still champion voice habit trend flight \
survey between bitter process artefact blind \
carbon truly provide dizzy crush flush \
breeze blouse charge solid fish spread
"""
return mnemonic.components(separatedBy: " ")
},
isValid: { _ in }
)
}