MnemonicInteractor
This commit is contained in:
parent
e3fdc24ad5
commit
fd26827372
|
@ -7,13 +7,11 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0DDAF3A42408728600EA9427 /* PKC5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DDAF3A32408728600EA9427 /* PKC5.swift */; };
|
||||
0DDAF3A52408728600EA9427 /* PKC5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DDAF3A32408728600EA9427 /* PKC5.swift */; };
|
||||
122777029525BA9CC4F9A958 /* Mnemonic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12B9024EB02AB18E1F44789A /* Mnemonic.swift */; };
|
||||
2A51344C2F30A6CE1A391BCF /* MnemonicSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A5EC633D7524CD344B44513 /* MnemonicSwiftTests.swift */; };
|
||||
2E1D0790276CCA0800AD43AB /* MnemonicInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E1D078F276CCA0800AD43AB /* MnemonicInteractor.swift */; };
|
||||
2E8756142768CFA5000BBABD /* Crypto in Frameworks */ = {isa = PBXBuildFile; productRef = 2E8756132768CFA5000BBABD /* Crypto */; };
|
||||
2E8756182768D6DF000BBABD /* Crypto in Frameworks */ = {isa = PBXBuildFile; productRef = 2E8756172768D6DF000BBABD /* Crypto */; };
|
||||
2E87561A2768D702000BBABD /* Crypto in Frameworks */ = {isa = PBXBuildFile; productRef = 2E8756192768D702000BBABD /* Crypto */; };
|
||||
422A84796316566997821D77 /* vectors.json in Resources */ = {isa = PBXBuildFile; fileRef = C3E5287598681E0527694214 /* vectors.json */; };
|
||||
81D18E658D26212E4D7647D8 /* String+MnemonicData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 256E6CB62D82160ACBA1512E /* String+MnemonicData.swift */; };
|
||||
8DC3D3DA23DBEAD93257DE4F /* MnemonicSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC7EE929BD11BA8AB38F9C19 /* MnemonicSwift.framework */; };
|
||||
|
@ -84,6 +82,7 @@
|
|||
1D6F81AB601CF04F3F1E52E3 /* English.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = English.swift; sourceTree = "<group>"; };
|
||||
23F75813C686C37B78DE459E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
256E6CB62D82160ACBA1512E /* String+MnemonicData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+MnemonicData.swift"; sourceTree = "<group>"; };
|
||||
2E1D078F276CCA0800AD43AB /* MnemonicInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MnemonicInteractor.swift; sourceTree = "<group>"; };
|
||||
7DCB97C4881969FDB72C61DB /* MnemonicSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MnemonicSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C3E5287598681E0527694214 /* vectors.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = vectors.json; sourceTree = "<group>"; };
|
||||
D2D9394FFD7755F40E53D60E /* Data+BitArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+BitArray.swift"; sourceTree = "<group>"; };
|
||||
|
@ -150,6 +149,7 @@
|
|||
0DAE92E7248EDE9700067A0B /* Info.plist */,
|
||||
D2D9394FFD7755F40E53D60E /* Data+BitArray.swift */,
|
||||
12B9024EB02AB18E1F44789A /* Mnemonic.swift */,
|
||||
2E1D078F276CCA0800AD43AB /* MnemonicInteractor.swift */,
|
||||
256E6CB62D82160ACBA1512E /* String+MnemonicData.swift */,
|
||||
07836B522CFA5AB2F61C4F9F /* Language */,
|
||||
0DDAF3A32408728600EA9427 /* PKC5.swift */,
|
||||
|
@ -369,6 +369,7 @@
|
|||
D04ECC70FD2144C467D7E779 /* Chinese.swift in Sources */,
|
||||
EFBEB3B343A9FDDD7B67FF88 /* Data+BitArray.swift in Sources */,
|
||||
D4460C3982D7B9A90D99C790 /* English.swift in Sources */,
|
||||
2E1D0791276CCA0800AD43AB /* MnemonicInteractor.swift in Sources */,
|
||||
C3A836752BC9FC7C89A398C5 /* Mnemonic.swift in Sources */,
|
||||
0DDAF3A52408728600EA9427 /* PKC5.swift in Sources */,
|
||||
9374718ABBF77ACE41A92B18 /* String+MnemonicData.swift in Sources */,
|
||||
|
@ -382,6 +383,7 @@
|
|||
996B7163A0786EC88C945C9F /* Chinese.swift in Sources */,
|
||||
8EAFFDA8F2A30674EA9EBBBC /* Data+BitArray.swift in Sources */,
|
||||
934F1409AF864AAA0AB52FDA /* English.swift in Sources */,
|
||||
2E1D0790276CCA0800AD43AB /* MnemonicInteractor.swift in Sources */,
|
||||
122777029525BA9CC4F9A958 /* Mnemonic.swift in Sources */,
|
||||
0DDAF3A42408728600EA9427 /* PKC5.swift in Sources */,
|
||||
81D18E658D26212E4D7647D8 /* String+MnemonicData.swift in Sources */,
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
//
|
||||
// MnemonicInteractor.swift
|
||||
// MnemonicSwift
|
||||
//
|
||||
// Created by Adam Stener on 12/17/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// The `MnemonicInteractor` is a wrapper around the Mnemonic type that allows for easy testing.
|
||||
/// The `Mnemonic` Type is comprised of static functions that take and produce data. In order
|
||||
/// to easily produce test data, all of these static functions have been wrapped in function
|
||||
/// properties that live on the `MnemonicInteractor` type. Because of this, you can instantiate
|
||||
/// the `MnemonicInteractor` with your own implementation of these functions for testing purposes,
|
||||
/// or you can use one of the built in static versions of the `MnemonicInteractor`.
|
||||
///
|
||||
/// `MnemonicInteractor.live` will return an interactor that simply forwards the interactor
|
||||
/// function calls directly to the Mnemonic type, i.e. nothing is mocked or stubbed, it is a
|
||||
/// `live` version.
|
||||
///
|
||||
/// `MnemonicInteractor.throwing` will return an interactor that has stubbed implementations of
|
||||
/// the entire API surface, where every method `throws` and `Error`. This can be useful when you
|
||||
/// want to test your apps behavior in the case that `Mnemonic` `throws`.
|
||||
///
|
||||
/// By writing an extension on `MnemonicInteractor`, you can provide your own static property that
|
||||
/// can produce a `MnemonicInteractor` that returns the data or state that you need for testing.
|
||||
/// If you don't intend to test your code with different behaviors of `MnemonicInteractor`, you
|
||||
/// can either use the `MnemonicInteractor.live` version, or you can use the `Mnemonic` static
|
||||
/// functions directly without instantiating anything.
|
||||
///
|
||||
public struct MnemonicInteractor {
|
||||
|
||||
/// Generate a mnemonic from the given hex string in the given language.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - hexString: The hex string to generate a mnemonic from.
|
||||
/// - Returns: the mnemonic string or nil if input is invalid
|
||||
/// - Throws:
|
||||
/// - `MnemonicError.InvalidHexString`: when an invalid string is given
|
||||
/// - `MnemonicError.invalidBitString` when the resulting bitstring generates an invalid word index
|
||||
let mnemonicEnglishString: (String) throws -> String
|
||||
|
||||
/// Generate a mnemonic from the given hex string in the given language.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - hexString: The hex string to generate a mnemonic from.
|
||||
/// - language: The language to use. Default is english.
|
||||
/// - Returns: the mnemonic string or nil if input is invalid
|
||||
/// - Throws:
|
||||
/// - `MnemonicError.InvalidHexString`: when an invalid string is given
|
||||
/// - `MnemonicError.invalidBitString` when the resulting bitstring generates an invalid word index
|
||||
let mnemonicString: (String, MnemonicLanguageType) throws -> String
|
||||
|
||||
/// Generate a deterministic seed string from a Mnemonic String.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - mnemonic: The mnemonic to use.
|
||||
/// - iterations: The iterations to perform in the PBKDF2 algorithm. Default is 2048.
|
||||
/// - passphrase: An optional passphrase. Default is the empty string.
|
||||
/// - language: The language to use. Default is english.
|
||||
/// - Returns: hexString representing the deterministic seed bytes
|
||||
/// - Throws: `MnemonicError.checksumError` if checksum fails, `MnemonicError.invalidInput` if received input is invalid
|
||||
let deterministicSeedString: (String, Int, String, MnemonicLanguageType) throws -> String
|
||||
|
||||
/// Generate a deterministic seed bytes from a Mnemonic String.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - mnemonic: The mnemonic to use.
|
||||
/// - iterations: The iterations to perform in the PBKDF2 algorithm. Default is 2048.
|
||||
/// - passphrase: An optional passphrase. Default is the empty string.
|
||||
/// - language: The language to use. Default is english.
|
||||
/// - Returns: a byte array representing the deterministic seed bytes
|
||||
/// - Throws: `MnemonicError.checksumError` if checksum fails, `MnemonicError.invalidInput` if received input is invalid
|
||||
let deterministicSeedBytes: (String, Int, String, MnemonicLanguageType) throws -> [UInt8]
|
||||
|
||||
/// Generate a mnemonic of the given strength and given language.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - strength: The strength to use. This must be a multiple of 32.
|
||||
/// - language: The language to use.
|
||||
/// - Returns: the random mnemonic phrase of the given strenght and language or `nil` if the strength is invalid or an error occurs
|
||||
/// - Throws:
|
||||
/// - `MnemonicError.InvalidInput` if stregth is invalid in the terms of BIP-39
|
||||
/// - `MnemonicError.entropyCreationFailed` if random bytes created for entropy fails
|
||||
/// - `MnemonicError.InvalidHexString` when an invalid string is given
|
||||
/// - `MnemonicError.invalidBitString` when the resulting bitstring generates an invalid word index
|
||||
let generateMnemonic: (Int, MnemonicLanguageType) throws -> String
|
||||
|
||||
/// Generate a mnemonic of the given strength and given language.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - strength: The strength to use. This must be a multiple of 32.
|
||||
/// - Returns: the random mnemonic phrase of the given strenght and language or `nil` if the strength is invalid or an error occurs
|
||||
/// - Throws:
|
||||
/// - `MnemonicError.InvalidInput` if stregth is invalid in the terms of BIP-39
|
||||
/// - `MnemonicError.entropyCreationFailed` if random bytes created for entropy fails
|
||||
/// - `MnemonicError.InvalidHexString` when an invalid string is given
|
||||
/// - `MnemonicError.invalidBitString` when the resulting bitstring generates an invalid word index
|
||||
let generateEnglishMnemonic: (Int) throws -> String
|
||||
|
||||
/// Validate that the given string is a valid mnemonic phrase according to BIP-39
|
||||
/// - Parameters:
|
||||
/// - mnemonic: a mnemonic phrase string
|
||||
/// - Throws:
|
||||
/// - `MnemonicError.wrongWordCount` if the word count is invalid
|
||||
/// - `MnemonicError.invalidWord(word: word)` this phase as a word that's not represented in this library's vocabulary for the detected language.
|
||||
/// - `MnemonicError.unsupportedLanguage` if the given phrase language isn't supported or couldn't be infered
|
||||
/// - `throw MnemonicError.checksumError` if the given phrase has an invalid checksum
|
||||
let validate: (String) throws -> Void
|
||||
|
||||
let determineLanguage: ([String]) throws -> MnemonicLanguageType
|
||||
|
||||
/// Change a string into data.
|
||||
/// - Parameter string: the string to convert
|
||||
/// - Returns: the utf8 encoded data
|
||||
/// - Throws: `MnemonicError.invalidInput` if the given String cannot be converted to Data
|
||||
let normalizedString: (String) throws -> Data
|
||||
|
||||
init(
|
||||
mnemonicEnglishString: @escaping (String) throws -> String = { hexString in
|
||||
try Mnemonic.mnemonicString(from: hexString)
|
||||
},
|
||||
mnemonicString: @escaping (
|
||||
String,
|
||||
MnemonicLanguageType
|
||||
) throws -> String = { hexString, languageType in
|
||||
try Mnemonic.mnemonicString(from: hexString, language: languageType)
|
||||
},
|
||||
deterministicSeedString: @escaping (
|
||||
String,
|
||||
Int,
|
||||
String,
|
||||
MnemonicLanguageType
|
||||
) throws -> String = { mnemonic, iterations, passphrase, language in
|
||||
try Mnemonic.deterministicSeedString(
|
||||
from: mnemonic,
|
||||
iterations: iterations,
|
||||
passphrase: passphrase,
|
||||
language: language
|
||||
)
|
||||
},
|
||||
deterministicSeedBytes: @escaping (
|
||||
String,
|
||||
Int,
|
||||
String,
|
||||
MnemonicLanguageType
|
||||
) throws -> [UInt8] = { mnemonic, iterations, passphrase, language in
|
||||
try Mnemonic.deterministicSeedBytes(
|
||||
from: mnemonic,
|
||||
iterations: iterations,
|
||||
passphrase: passphrase,
|
||||
language: language
|
||||
)
|
||||
},
|
||||
generateMnemonic: @escaping (
|
||||
Int,
|
||||
MnemonicLanguageType
|
||||
) throws -> String = { strength, language in
|
||||
try Mnemonic.generateMnemonic(strength: strength, language: language)
|
||||
},
|
||||
generateEnglishMnemonic: @escaping (Int) throws -> String = { strength in
|
||||
try Mnemonic.generateMnemonic(strength: strength)
|
||||
},
|
||||
validate: @escaping (String) throws -> Void = { mnemonic in
|
||||
try Mnemonic.validate(mnemonic: mnemonic)
|
||||
},
|
||||
determineLanguage: @escaping ([String]) throws -> MnemonicLanguageType = { mnemonicWords in
|
||||
try Mnemonic.determineLanguage(from: mnemonicWords)
|
||||
},
|
||||
normalizedString: @escaping (String) throws -> Data = { string in
|
||||
try Mnemonic.normalizedString(string)
|
||||
}
|
||||
) {
|
||||
self.mnemonicEnglishString = mnemonicEnglishString
|
||||
self.mnemonicString = mnemonicString
|
||||
self.deterministicSeedString = deterministicSeedString
|
||||
self.deterministicSeedBytes = deterministicSeedBytes
|
||||
self.generateMnemonic = generateMnemonic
|
||||
self.generateEnglishMnemonic = generateEnglishMnemonic
|
||||
self.validate = validate
|
||||
self.determineLanguage = determineLanguage
|
||||
self.normalizedString = normalizedString
|
||||
}
|
||||
}
|
||||
|
||||
extension MnemonicInteractor {
|
||||
static let live = MnemonicInteractor()
|
||||
|
||||
static let throwing = MnemonicInteractor(
|
||||
mnemonicEnglishString: { _ in
|
||||
throw MnemonicError.invalidHexstring
|
||||
},
|
||||
mnemonicString: { _, _ in
|
||||
throw MnemonicError.invalidHexstring
|
||||
},
|
||||
deterministicSeedString: { _, _, _, _ in
|
||||
throw MnemonicError.invalidInput
|
||||
},
|
||||
deterministicSeedBytes: { _, _, _, _ in
|
||||
throw MnemonicError.invalidInput
|
||||
},
|
||||
generateMnemonic: { _, _ in
|
||||
throw MnemonicError.invalidHexstring
|
||||
},
|
||||
generateEnglishMnemonic: { _ in
|
||||
throw MnemonicError.invalidHexstring
|
||||
},
|
||||
validate: { _ in
|
||||
throw MnemonicError.checksumError
|
||||
},
|
||||
determineLanguage: { _ in
|
||||
throw MnemonicError.invalidWord(word: "word")
|
||||
},
|
||||
normalizedString: { _ in
|
||||
throw MnemonicError.invalidInput
|
||||
}
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue