diff --git a/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.pbxproj b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.pbxproj new file mode 100644 index 0000000..52fe81b --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.pbxproj @@ -0,0 +1,748 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 28122A3C2BB28E9C00B6FA63 /* ThresholdKeyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28122A3B2BB28E9C00B6FA63 /* ThresholdKeyView.swift */; }; + 28122A3F2BB2A04A00B6FA63 /* Web3SwiftMpcProvider in Frameworks */ = {isa = PBXBuildFile; productRef = 28122A3E2BB2A04A00B6FA63 /* Web3SwiftMpcProvider */; }; + 28122A412BB4429E00B6FA63 /* EthereumClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28122A402BB4429E00B6FA63 /* EthereumClient.swift */; }; + 28122A442BB4431800B6FA63 /* web3-zksync.swift in Frameworks */ = {isa = PBXBuildFile; productRef = 28122A432BB4431800B6FA63 /* web3-zksync.swift */; }; + 28122A462BB4431800B6FA63 /* web3.swift in Frameworks */ = {isa = PBXBuildFile; productRef = 28122A452BB4431800B6FA63 /* web3.swift */; }; + 283C54472BC03B5E008CD381 /* tkey-mpc-swift in Frameworks */ = {isa = PBXBuildFile; productRef = 283C54462BC03B5E008CD381 /* tkey-mpc-swift */; }; + 283C544A2BC03B6C008CD381 /* TorusUtils in Frameworks */ = {isa = PBXBuildFile; productRef = 283C54492BC03B6C008CD381 /* TorusUtils */; }; + 283C544D2BC03B84008CD381 /* CustomAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 283C544C2BC03B84008CD381 /* CustomAuth */; }; + 2882D6632BADAE6900B3E518 /* tkey_ios_mpcApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2882D6622BADAE6900B3E518 /* tkey_ios_mpcApp.swift */; }; + 2882D6652BADAE6900B3E518 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2882D6642BADAE6900B3E518 /* ContentView.swift */; }; + 2882D6672BADAE6B00B3E518 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2882D6662BADAE6B00B3E518 /* Assets.xcassets */; }; + 2882D66A2BADAE6B00B3E518 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2882D6692BADAE6B00B3E518 /* Preview Assets.xcassets */; }; + 2882D6742BADAE6B00B3E518 /* tkey_ios_mpcTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2882D6732BADAE6B00B3E518 /* tkey_ios_mpcTests.swift */; }; + 2882D67E2BADAE6B00B3E518 /* tkey_ios_mpcUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2882D67D2BADAE6B00B3E518 /* tkey_ios_mpcUITests.swift */; }; + 2882D6802BADAE6B00B3E518 /* tkey_ios_mpcUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2882D67F2BADAE6B00B3E518 /* tkey_ios_mpcUITestsLaunchTests.swift */; }; + 2882D6942BADC5E800B3E518 /* CustomAuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2882D6932BADC5E800B3E518 /* CustomAuthViewModel.swift */; }; + 2882D6982BADCA0500B3E518 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2882D6972BADCA0500B3E518 /* LoginView.swift */; }; + 2882D69A2BADCC4300B3E518 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2882D6992BADCC4300B3E518 /* HomeView.swift */; }; + 2882D69C2BADCD2400B3E518 /* ThresholdKeyViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2882D69B2BADCD2400B3E518 /* ThresholdKeyViewModel.swift */; }; + 2882D6A22BAEC57C00B3E518 /* KeyChainInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2882D6A12BAEC57C00B3E518 /* KeyChainInterface.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 2882D6702BADAE6B00B3E518 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2882D6572BADAE6900B3E518 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2882D65E2BADAE6900B3E518; + remoteInfo = "tkey-ios-mpc"; + }; + 2882D67A2BADAE6B00B3E518 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 2882D6572BADAE6900B3E518 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2882D65E2BADAE6900B3E518; + remoteInfo = "tkey-ios-mpc"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 28122A3B2BB28E9C00B6FA63 /* ThresholdKeyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThresholdKeyView.swift; sourceTree = ""; }; + 28122A402BB4429E00B6FA63 /* EthereumClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumClient.swift; sourceTree = ""; }; + 2882D65F2BADAE6900B3E518 /* tkey-ios-mpc.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "tkey-ios-mpc.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2882D6622BADAE6900B3E518 /* tkey_ios_mpcApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = tkey_ios_mpcApp.swift; sourceTree = ""; }; + 2882D6642BADAE6900B3E518 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 2882D6662BADAE6B00B3E518 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 2882D6692BADAE6B00B3E518 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 2882D66F2BADAE6B00B3E518 /* tkey-ios-mpcTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "tkey-ios-mpcTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2882D6732BADAE6B00B3E518 /* tkey_ios_mpcTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = tkey_ios_mpcTests.swift; sourceTree = ""; }; + 2882D6792BADAE6B00B3E518 /* tkey-ios-mpcUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "tkey-ios-mpcUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2882D67D2BADAE6B00B3E518 /* tkey_ios_mpcUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = tkey_ios_mpcUITests.swift; sourceTree = ""; }; + 2882D67F2BADAE6B00B3E518 /* tkey_ios_mpcUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = tkey_ios_mpcUITestsLaunchTests.swift; sourceTree = ""; }; + 2882D6932BADC5E800B3E518 /* CustomAuthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomAuthViewModel.swift; sourceTree = ""; }; + 2882D6972BADCA0500B3E518 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = ""; }; + 2882D6992BADCC4300B3E518 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; + 2882D69B2BADCD2400B3E518 /* ThresholdKeyViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThresholdKeyViewModel.swift; sourceTree = ""; }; + 2882D6A12BAEC57C00B3E518 /* KeyChainInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyChainInterface.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 2882D65C2BADAE6900B3E518 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 28122A442BB4431800B6FA63 /* web3-zksync.swift in Frameworks */, + 283C544D2BC03B84008CD381 /* CustomAuth in Frameworks */, + 28122A3F2BB2A04A00B6FA63 /* Web3SwiftMpcProvider in Frameworks */, + 283C54472BC03B5E008CD381 /* tkey-mpc-swift in Frameworks */, + 283C544A2BC03B6C008CD381 /* TorusUtils in Frameworks */, + 28122A462BB4431800B6FA63 /* web3.swift in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2882D66C2BADAE6B00B3E518 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2882D6762BADAE6B00B3E518 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 2882D6562BADAE6900B3E518 = { + isa = PBXGroup; + children = ( + 2882D6612BADAE6900B3E518 /* tkey-ios-mpc */, + 2882D6722BADAE6B00B3E518 /* tkey-ios-mpcTests */, + 2882D67C2BADAE6B00B3E518 /* tkey-ios-mpcUITests */, + 2882D6602BADAE6900B3E518 /* Products */, + ); + sourceTree = ""; + }; + 2882D6602BADAE6900B3E518 /* Products */ = { + isa = PBXGroup; + children = ( + 2882D65F2BADAE6900B3E518 /* tkey-ios-mpc.app */, + 2882D66F2BADAE6B00B3E518 /* tkey-ios-mpcTests.xctest */, + 2882D6792BADAE6B00B3E518 /* tkey-ios-mpcUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 2882D6612BADAE6900B3E518 /* tkey-ios-mpc */ = { + isa = PBXGroup; + children = ( + 2882D6A02BAEC57000B3E518 /* Helpers */, + 2882D6962BADC9F900B3E518 /* Views */, + 2882D6922BADC5CB00B3E518 /* ViewModels */, + 2882D6622BADAE6900B3E518 /* tkey_ios_mpcApp.swift */, + 2882D6662BADAE6B00B3E518 /* Assets.xcassets */, + 2882D6682BADAE6B00B3E518 /* Preview Content */, + ); + path = "tkey-ios-mpc"; + sourceTree = ""; + }; + 2882D6682BADAE6B00B3E518 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 2882D6692BADAE6B00B3E518 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 2882D6722BADAE6B00B3E518 /* tkey-ios-mpcTests */ = { + isa = PBXGroup; + children = ( + 2882D6732BADAE6B00B3E518 /* tkey_ios_mpcTests.swift */, + ); + path = "tkey-ios-mpcTests"; + sourceTree = ""; + }; + 2882D67C2BADAE6B00B3E518 /* tkey-ios-mpcUITests */ = { + isa = PBXGroup; + children = ( + 2882D67D2BADAE6B00B3E518 /* tkey_ios_mpcUITests.swift */, + 2882D67F2BADAE6B00B3E518 /* tkey_ios_mpcUITestsLaunchTests.swift */, + ); + path = "tkey-ios-mpcUITests"; + sourceTree = ""; + }; + 2882D6922BADC5CB00B3E518 /* ViewModels */ = { + isa = PBXGroup; + children = ( + 2882D6932BADC5E800B3E518 /* CustomAuthViewModel.swift */, + 2882D69B2BADCD2400B3E518 /* ThresholdKeyViewModel.swift */, + ); + path = ViewModels; + sourceTree = ""; + }; + 2882D6962BADC9F900B3E518 /* Views */ = { + isa = PBXGroup; + children = ( + 2882D6642BADAE6900B3E518 /* ContentView.swift */, + 2882D6972BADCA0500B3E518 /* LoginView.swift */, + 2882D6992BADCC4300B3E518 /* HomeView.swift */, + 28122A3B2BB28E9C00B6FA63 /* ThresholdKeyView.swift */, + ); + path = Views; + sourceTree = ""; + }; + 2882D6A02BAEC57000B3E518 /* Helpers */ = { + isa = PBXGroup; + children = ( + 2882D6A12BAEC57C00B3E518 /* KeyChainInterface.swift */, + 28122A402BB4429E00B6FA63 /* EthereumClient.swift */, + ); + path = Helpers; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 2882D65E2BADAE6900B3E518 /* tkey-ios-mpc */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2882D6832BADAE6B00B3E518 /* Build configuration list for PBXNativeTarget "tkey-ios-mpc" */; + buildPhases = ( + 2882D65B2BADAE6900B3E518 /* Sources */, + 2882D65C2BADAE6900B3E518 /* Frameworks */, + 2882D65D2BADAE6900B3E518 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "tkey-ios-mpc"; + packageProductDependencies = ( + 28122A3E2BB2A04A00B6FA63 /* Web3SwiftMpcProvider */, + 28122A432BB4431800B6FA63 /* web3-zksync.swift */, + 28122A452BB4431800B6FA63 /* web3.swift */, + 283C54462BC03B5E008CD381 /* tkey-mpc-swift */, + 283C54492BC03B6C008CD381 /* TorusUtils */, + 283C544C2BC03B84008CD381 /* CustomAuth */, + ); + productName = "tkey-ios-mpc"; + productReference = 2882D65F2BADAE6900B3E518 /* tkey-ios-mpc.app */; + productType = "com.apple.product-type.application"; + }; + 2882D66E2BADAE6B00B3E518 /* tkey-ios-mpcTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2882D6862BADAE6B00B3E518 /* Build configuration list for PBXNativeTarget "tkey-ios-mpcTests" */; + buildPhases = ( + 2882D66B2BADAE6B00B3E518 /* Sources */, + 2882D66C2BADAE6B00B3E518 /* Frameworks */, + 2882D66D2BADAE6B00B3E518 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 2882D6712BADAE6B00B3E518 /* PBXTargetDependency */, + ); + name = "tkey-ios-mpcTests"; + productName = "tkey-ios-mpcTests"; + productReference = 2882D66F2BADAE6B00B3E518 /* tkey-ios-mpcTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 2882D6782BADAE6B00B3E518 /* tkey-ios-mpcUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2882D6892BADAE6B00B3E518 /* Build configuration list for PBXNativeTarget "tkey-ios-mpcUITests" */; + buildPhases = ( + 2882D6752BADAE6B00B3E518 /* Sources */, + 2882D6762BADAE6B00B3E518 /* Frameworks */, + 2882D6772BADAE6B00B3E518 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 2882D67B2BADAE6B00B3E518 /* PBXTargetDependency */, + ); + name = "tkey-ios-mpcUITests"; + productName = "tkey-ios-mpcUITests"; + productReference = 2882D6792BADAE6B00B3E518 /* tkey-ios-mpcUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 2882D6572BADAE6900B3E518 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1500; + LastUpgradeCheck = 1500; + TargetAttributes = { + 2882D65E2BADAE6900B3E518 = { + CreatedOnToolsVersion = 15.0.1; + }; + 2882D66E2BADAE6B00B3E518 = { + CreatedOnToolsVersion = 15.0.1; + TestTargetID = 2882D65E2BADAE6900B3E518; + }; + 2882D6782BADAE6B00B3E518 = { + CreatedOnToolsVersion = 15.0.1; + TestTargetID = 2882D65E2BADAE6900B3E518; + }; + }; + }; + buildConfigurationList = 2882D65A2BADAE6900B3E518 /* Build configuration list for PBXProject "tkey-ios-mpc" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 2882D6562BADAE6900B3E518; + packageReferences = ( + 28122A3D2BB2A04A00B6FA63 /* XCRemoteSwiftPackageReference "web3-swift-mpc-provider" */, + 28122A422BB4431800B6FA63 /* XCRemoteSwiftPackageReference "web3" */, + 283C54452BC03B5E008CD381 /* XCRemoteSwiftPackageReference "tkey-mpc-swift" */, + 283C54482BC03B6C008CD381 /* XCRemoteSwiftPackageReference "torus-utils-swift" */, + 283C544B2BC03B84008CD381 /* XCRemoteSwiftPackageReference "customauth-swift-sdk" */, + ); + productRefGroup = 2882D6602BADAE6900B3E518 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 2882D65E2BADAE6900B3E518 /* tkey-ios-mpc */, + 2882D66E2BADAE6B00B3E518 /* tkey-ios-mpcTests */, + 2882D6782BADAE6B00B3E518 /* tkey-ios-mpcUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 2882D65D2BADAE6900B3E518 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2882D66A2BADAE6B00B3E518 /* Preview Assets.xcassets in Resources */, + 2882D6672BADAE6B00B3E518 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2882D66D2BADAE6B00B3E518 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2882D6772BADAE6B00B3E518 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2882D65B2BADAE6900B3E518 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2882D6652BADAE6900B3E518 /* ContentView.swift in Sources */, + 2882D6942BADC5E800B3E518 /* CustomAuthViewModel.swift in Sources */, + 28122A3C2BB28E9C00B6FA63 /* ThresholdKeyView.swift in Sources */, + 2882D6982BADCA0500B3E518 /* LoginView.swift in Sources */, + 2882D69A2BADCC4300B3E518 /* HomeView.swift in Sources */, + 2882D69C2BADCD2400B3E518 /* ThresholdKeyViewModel.swift in Sources */, + 2882D6632BADAE6900B3E518 /* tkey_ios_mpcApp.swift in Sources */, + 2882D6A22BAEC57C00B3E518 /* KeyChainInterface.swift in Sources */, + 28122A412BB4429E00B6FA63 /* EthereumClient.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2882D66B2BADAE6B00B3E518 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2882D6742BADAE6B00B3E518 /* tkey_ios_mpcTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2882D6752BADAE6B00B3E518 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2882D6802BADAE6B00B3E518 /* tkey_ios_mpcUITestsLaunchTests.swift in Sources */, + 2882D67E2BADAE6B00B3E518 /* tkey_ios_mpcUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 2882D6712BADAE6B00B3E518 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 2882D65E2BADAE6900B3E518 /* tkey-ios-mpc */; + targetProxy = 2882D6702BADAE6B00B3E518 /* PBXContainerItemProxy */; + }; + 2882D67B2BADAE6B00B3E518 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 2882D65E2BADAE6900B3E518 /* tkey-ios-mpc */; + targetProxy = 2882D67A2BADAE6B00B3E518 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 2882D6812BADAE6B00B3E518 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 2882D6822BADAE6B00B3E518 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 2882D6842BADAE6B00B3E518 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"tkey-ios-mpc/Preview Content\""; + DEVELOPMENT_TEAM = HYCGKU63WD; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.w3a.tkey-ios-mpc"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 2882D6852BADAE6B00B3E518 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"tkey-ios-mpc/Preview Content\""; + DEVELOPMENT_TEAM = HYCGKU63WD; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.w3a.tkey-ios-mpc"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 2882D6872BADAE6B00B3E518 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = HYCGKU63WD; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.w3a.tkey-ios-mpcTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/tkey-ios-mpc.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/tkey-ios-mpc"; + }; + name = Debug; + }; + 2882D6882BADAE6B00B3E518 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = HYCGKU63WD; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.w3a.tkey-ios-mpcTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/tkey-ios-mpc.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/tkey-ios-mpc"; + }; + name = Release; + }; + 2882D68A2BADAE6B00B3E518 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = HYCGKU63WD; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.w3a.tkey-ios-mpcUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "tkey-ios-mpc"; + }; + name = Debug; + }; + 2882D68B2BADAE6B00B3E518 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = HYCGKU63WD; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.w3a.tkey-ios-mpcUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "tkey-ios-mpc"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 2882D65A2BADAE6900B3E518 /* Build configuration list for PBXProject "tkey-ios-mpc" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2882D6812BADAE6B00B3E518 /* Debug */, + 2882D6822BADAE6B00B3E518 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2882D6832BADAE6B00B3E518 /* Build configuration list for PBXNativeTarget "tkey-ios-mpc" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2882D6842BADAE6B00B3E518 /* Debug */, + 2882D6852BADAE6B00B3E518 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2882D6862BADAE6B00B3E518 /* Build configuration list for PBXNativeTarget "tkey-ios-mpcTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2882D6872BADAE6B00B3E518 /* Debug */, + 2882D6882BADAE6B00B3E518 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2882D6892BADAE6B00B3E518 /* Build configuration list for PBXNativeTarget "tkey-ios-mpcUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2882D68A2BADAE6B00B3E518 /* Debug */, + 2882D68B2BADAE6B00B3E518 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 28122A3D2BB2A04A00B6FA63 /* XCRemoteSwiftPackageReference "web3-swift-mpc-provider" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/tkey/web3-swift-mpc-provider"; + requirement = { + kind = exactVersion; + version = 1.0.0; + }; + }; + 28122A422BB4431800B6FA63 /* XCRemoteSwiftPackageReference "web3" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/argentlabs/web3.swift"; + requirement = { + kind = exactVersion; + version = 1.6.1; + }; + }; + 283C54452BC03B5E008CD381 /* XCRemoteSwiftPackageReference "tkey-mpc-swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/tkey/tkey-mpc-swift"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 2.1.0; + }; + }; + 283C54482BC03B6C008CD381 /* XCRemoteSwiftPackageReference "torus-utils-swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/torusresearch/torus-utils-swift"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 8.0.0; + }; + }; + 283C544B2BC03B84008CD381 /* XCRemoteSwiftPackageReference "customauth-swift-sdk" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/torusresearch/customauth-swift-sdk"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 9.0.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 28122A3E2BB2A04A00B6FA63 /* Web3SwiftMpcProvider */ = { + isa = XCSwiftPackageProductDependency; + package = 28122A3D2BB2A04A00B6FA63 /* XCRemoteSwiftPackageReference "web3-swift-mpc-provider" */; + productName = Web3SwiftMpcProvider; + }; + 28122A432BB4431800B6FA63 /* web3-zksync.swift */ = { + isa = XCSwiftPackageProductDependency; + package = 28122A422BB4431800B6FA63 /* XCRemoteSwiftPackageReference "web3" */; + productName = "web3-zksync.swift"; + }; + 28122A452BB4431800B6FA63 /* web3.swift */ = { + isa = XCSwiftPackageProductDependency; + package = 28122A422BB4431800B6FA63 /* XCRemoteSwiftPackageReference "web3" */; + productName = web3.swift; + }; + 283C54462BC03B5E008CD381 /* tkey-mpc-swift */ = { + isa = XCSwiftPackageProductDependency; + package = 283C54452BC03B5E008CD381 /* XCRemoteSwiftPackageReference "tkey-mpc-swift" */; + productName = "tkey-mpc-swift"; + }; + 283C54492BC03B6C008CD381 /* TorusUtils */ = { + isa = XCSwiftPackageProductDependency; + package = 283C54482BC03B6C008CD381 /* XCRemoteSwiftPackageReference "torus-utils-swift" */; + productName = TorusUtils; + }; + 283C544C2BC03B84008CD381 /* CustomAuth */ = { + isa = XCSwiftPackageProductDependency; + package = 283C544B2BC03B84008CD381 /* XCRemoteSwiftPackageReference "customauth-swift-sdk" */; + productName = CustomAuth; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 2882D6572BADAE6900B3E518 /* Project object */; +} diff --git a/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..9eda2e6 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,248 @@ +{ + "pins" : [ + { + "identity" : "anycodable", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Flight-School/AnyCodable", + "state" : { + "revision" : "862808b2070cd908cb04f9aafe7de83d35f81b05", + "version" : "0.6.7" + } + }, + { + "identity" : "bigint", + "kind" : "remoteSourceControl", + "location" : "https://github.com/attaswift/BigInt.git", + "state" : { + "revision" : "0ed110f7555c34ff468e72e1686e59721f2b0da6", + "version" : "5.3.0" + } + }, + { + "identity" : "cryptoswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/krzyzanowskim/CryptoSwift", + "state" : { + "revision" : "7892a123f7e8d0fe62f9f03728b17bbd4f94df5c", + "version" : "1.8.1" + } + }, + { + "identity" : "curvelib.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/tkey/curvelib.swift", + "state" : { + "revision" : "7dad3bf1793de263f83406c08c18c9316abf082f", + "version" : "0.1.2" + } + }, + { + "identity" : "customauth-swift-sdk", + "kind" : "remoteSourceControl", + "location" : "https://github.com/torusresearch/customauth-swift-sdk", + "state" : { + "revision" : "bb0c8249b6f0e2866e51e47bebdc801848fae45a", + "version" : "9.0.0" + } + }, + { + "identity" : "fetch-node-details-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/torusresearch/fetch-node-details-swift", + "state" : { + "revision" : "d591af500f32ce3c88d04af9bb74d746585acfea", + "version" : "5.1.0" + } + }, + { + "identity" : "generic-json-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/iwill/generic-json-swift", + "state" : { + "revision" : "0a06575f4038b504e78ac330913d920f1630f510", + "version" : "2.0.2" + } + }, + { + "identity" : "jwtdecode.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/auth0/JWTDecode.swift.git", + "state" : { + "revision" : "58af7278797871e460d79496621b3e5366b865b2", + "version" : "3.1.0" + } + }, + { + "identity" : "secp256k1.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/GigaBitcoin/secp256k1.swift.git", + "state" : { + "revision" : "1a14e189def5eaa92f839afdd2faad8e43b61a6e", + "version" : "0.12.2" + } + }, + { + "identity" : "socket.io-client-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/socketio/socket.io-client-swift", + "state" : { + "revision" : "175da8b5156f6b132436f0676cc84c2f6a766b6e", + "version" : "16.1.0" + } + }, + { + "identity" : "starscream", + "kind" : "remoteSourceControl", + "location" : "https://github.com/daltoniam/Starscream", + "state" : { + "revision" : "ac6c0fc9da221873e01bd1a0d4818498a71eef33", + "version" : "4.0.6" + } + }, + { + "identity" : "swift-atomics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-atomics.git", + "state" : { + "revision" : "cd142fd2f64be2100422d658e7411e39489da985", + "version" : "1.2.0" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections.git", + "state" : { + "revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb", + "version" : "1.1.0" + } + }, + { + "identity" : "swift-http-types", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-http-types", + "state" : { + "revision" : "12358d55a3824bd5fed310b999ea8cf83a9a1a65", + "version" : "1.0.3" + } + }, + { + "identity" : "swift-log", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-log.git", + "state" : { + "revision" : "e97a6fcb1ab07462881ac165fdbb37f067e205d5", + "version" : "1.5.4" + } + }, + { + "identity" : "swift-nio", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio.git", + "state" : { + "revision" : "fc63f0cf4e55a4597407a9fc95b16a2bc44b4982", + "version" : "2.64.0" + } + }, + { + "identity" : "swift-nio-extras", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-extras.git", + "state" : { + "revision" : "a3b640d7dc567225db7c94386a6e71aded1bfa63", + "version" : "1.22.0" + } + }, + { + "identity" : "swift-nio-http2", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-http2.git", + "state" : { + "revision" : "0904bf0feb5122b7e5c3f15db7df0eabe623dd87", + "version" : "1.30.0" + } + }, + { + "identity" : "swift-nio-ssl", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-ssl.git", + "state" : { + "revision" : "7c381eb6083542b124a6c18fae742f55001dc2b5", + "version" : "2.26.0" + } + }, + { + "identity" : "swift-nio-transport-services", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio-transport-services.git", + "state" : { + "revision" : "6cbe0ed2b394f21ab0d46b9f0c50c6be964968ce", + "version" : "1.20.1" + } + }, + { + "identity" : "swift-system", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-system.git", + "state" : { + "revision" : "025bcb1165deab2e20d4eaba79967ce73013f496", + "version" : "1.2.1" + } + }, + { + "identity" : "tkey-mpc-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/tkey/tkey-mpc-swift", + "state" : { + "revision" : "0b1020f2fe0c3790bc50aa133bb613ff1b55172f", + "version" : "2.1.0" + } + }, + { + "identity" : "torus-utils-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/torusresearch/torus-utils-swift", + "state" : { + "revision" : "04c62fd5f73f21bd01b7c07e08f6135db26c5940", + "version" : "8.0.0" + } + }, + { + "identity" : "tss-client-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/torusresearch/tss-client-swift.git", + "state" : { + "revision" : "e1262449b2810b10c7ac2b29215aebf4d8f422f7", + "version" : "1.0.15" + } + }, + { + "identity" : "web3-swift-mpc-provider", + "kind" : "remoteSourceControl", + "location" : "https://github.com/tkey/web3-swift-mpc-provider", + "state" : { + "revision" : "206ae41face7590b8642703005d768c633015d75", + "version" : "1.0.0" + } + }, + { + "identity" : "web3.swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/argentlabs/web3.swift", + "state" : { + "revision" : "1e75f98a5738c470b23bbfffa9314e9f788df76b", + "version" : "1.6.1" + } + }, + { + "identity" : "websocket-kit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/vapor/websocket-kit.git", + "state" : { + "revision" : "4232d34efa49f633ba61afde365d3896fc7f8740", + "version" : "2.15.0" + } + } + ], + "version" : 2 +} diff --git a/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/xcuserdata/ayushb.xcuserdatad/UserInterfaceState.xcuserstate b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/xcuserdata/ayushb.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..b8a7883 Binary files /dev/null and b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/project.xcworkspace/xcuserdata/ayushb.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/xcuserdata/ayushb.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/xcuserdata/ayushb.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..b8d0acf --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/xcuserdata/ayushb.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,519 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/xcuserdata/ayushb.xcuserdatad/xcschemes/xcschememanagement.plist b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/xcuserdata/ayushb.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..0353fe4 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc.xcodeproj/xcuserdata/ayushb.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,140 @@ + + + + + SchemeUserState + + AnyCodable (Playground) 1.xcscheme + + isShown + + orderHint + 7 + + AnyCodable (Playground) 2.xcscheme + + isShown + + orderHint + 8 + + AnyCodable (Playground) 3.xcscheme + + isShown + + orderHint + 18 + + AnyCodable (Playground) 4.xcscheme + + isShown + + orderHint + 19 + + AnyCodable (Playground) 5.xcscheme + + isShown + + orderHint + 20 + + AnyCodable (Playground).xcscheme + + isShown + + orderHint + 6 + + Demo (Playground) 1.xcscheme + + isShown + + orderHint + 10 + + Demo (Playground) 2.xcscheme + + isShown + + orderHint + 11 + + Demo (Playground).xcscheme + + isShown + + orderHint + 9 + + JWTDecode (Playground) 1.xcscheme + + isShown + + orderHint + 2 + + JWTDecode (Playground) 2.xcscheme + + isShown + + orderHint + 3 + + JWTDecode (Playground) 3.xcscheme + + isShown + + orderHint + 16 + + JWTDecode (Playground) 4.xcscheme + + isShown + + orderHint + 17 + + JWTDecode (Playground) 5.xcscheme + + isShown + + orderHint + 18 + + JWTDecode (Playground).xcscheme + + isShown + + orderHint + 1 + + Playground (Playground) 1.xcscheme + + isShown + + orderHint + 13 + + Playground (Playground) 2.xcscheme + + isShown + + orderHint + 14 + + Playground (Playground).xcscheme + + isShown + + orderHint + 12 + + tkey-ios-mpc.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/tkey-ios-mpc/tkey-ios-mpc/Assets.xcassets/AccentColor.colorset/Contents.json b/tkey-ios-mpc/tkey-ios-mpc/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/Assets.xcassets/AppIcon.appiconset/Contents.json b/tkey-ios-mpc/tkey-ios-mpc/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..13613e3 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/Assets.xcassets/Contents.json b/tkey-ios-mpc/tkey-ios-mpc/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/Helpers/EthereumClient.swift b/tkey-ios-mpc/tkey-ios-mpc/Helpers/EthereumClient.swift new file mode 100644 index 0000000..6280125 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/Helpers/EthereumClient.swift @@ -0,0 +1,72 @@ +// +// EthereumClient.swift +// tkey-ios-mpc +// +// Created by Ayush B on 27/03/24. +// + +import Foundation +import web3 +import BigInt +import Web3SwiftMpcProvider + +struct EthereumClient { + let web3Client: EthereumHttpClient! + var networkId: String = "11155111" + + init() { + self.web3Client = EthereumHttpClient( + url: URL(string: "https://1rpc.io/sepolia")!, + network: .fromString(networkId) + ) + } + + func getNonce(address: EthereumAddress) async throws -> Int{ + do { + let nonce = try await web3Client.eth_getTransactionCount( + address: address, block: .Latest + ) + return nonce + 1 + } catch let error { + throw error + } + } + + func getGasPrice() async throws -> BigUInt { + do { + let gasPrice = try await web3Client.eth_gasPrice() + return gasPrice + } catch let error { + throw error + } + } + + func getGasLimit(transaction: EthereumTransaction) async throws -> BigUInt { + do { + let gasLimit = try await web3Client.eth_estimateGas(transaction) + return gasLimit + } catch let error { + throw error + } + } + + func sendRawTransaction( + transaction: EthereumTransaction, + ethTssAccount: EthereumTssAccount + ) async throws -> String { + do { + let hash = try await web3Client.eth_sendRawTransaction( + transaction, + withAccount: ethTssAccount + ) + + return hash + } catch let error { + throw error + } + } + + func getChainId() -> String { + return networkId + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/Helpers/KeyChainInterface.swift b/tkey-ios-mpc/tkey-ios-mpc/Helpers/KeyChainInterface.swift new file mode 100644 index 0000000..23799f0 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/Helpers/KeyChainInterface.swift @@ -0,0 +1,78 @@ +// +// KeyChainInterface.swift +// tkey-ios-mpc +// +// Created by Ayush B on 23/03/24. +// + +import Foundation +import Security + +public class KeychainInterface { + // Note: This class is provided for example purposes only, + // it is not intended to be used in a production environment. + + public enum KeychainError: Error { + case itemNotFound + case invalidItemFormat + case unexpectedStatus(OSStatus) + } + + // TODO: add delete function + + public static func save(item: String, key: String, identifier: String = "web3auth.tkey-ios") throws { + let query: [String: AnyObject] = [ + kSecAttrService as String: identifier as AnyObject, + kSecAttrAccount as String: key as AnyObject, + kSecClass as String: kSecClassGenericPassword, + kSecValueData as String: item.data(using: .utf8)! as AnyObject + ] + + // First delete item if found + var status = SecItemDelete(query as CFDictionary) + + guard status == errSecSuccess || status == errSecItemNotFound else { + throw KeychainError.unexpectedStatus(status) + } + + // Add new item + status = SecItemAdd( + query as CFDictionary, + nil + ) + + guard status == errSecSuccess else { + throw KeychainError.unexpectedStatus(status) + } + } + + public static func fetch(key: String, identifier: String = "web3auth.tkey-ios") throws -> String { + let query: [String: AnyObject] = [ + kSecAttrService as String: identifier as AnyObject, + kSecAttrAccount as String: key as AnyObject, + kSecClass as String: kSecClassGenericPassword, + kSecMatchLimit as String: kSecMatchLimitOne, + kSecReturnData as String: kCFBooleanTrue + ] + + var itemCopy: AnyObject? + let status = SecItemCopyMatching( + query as CFDictionary, + &itemCopy + ) + + guard status != errSecItemNotFound else { + throw KeychainError.itemNotFound + } + + guard status == errSecSuccess else { + throw KeychainError.unexpectedStatus(status) + } + + guard let item = itemCopy as? Data else { + throw KeychainError.invalidItemFormat + } + + return String(decoding: item, as: UTF8.self) + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/Preview Content/Preview Assets.xcassets/Contents.json b/tkey-ios-mpc/tkey-ios-mpc/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/ViewModels/CustomAuthViewModel.swift b/tkey-ios-mpc/tkey-ios-mpc/ViewModels/CustomAuthViewModel.swift new file mode 100644 index 0000000..1d02d17 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/ViewModels/CustomAuthViewModel.swift @@ -0,0 +1,50 @@ +// +// ViewModel.swift +// tkey-ios-mpc +// +// Created by Ayush B on 22/03/24. +// + +import Foundation +import CustomAuth + +class CustomAuthViewModel: ObservableObject { + var customAuth: CustomAuth! + var torusKeyDetails: TorusKeyData! + + @Published var isLoggedIn: Bool = false + + func intialize() { + Task { + let subVerifierDetails = SubVerifierDetails( + loginType: .web, + loginProvider: .google, + clientId: "519228911939-cri01h55lsjbsia1k7ll6qpalrus75ps.apps.googleusercontent.com", + verifier: "w3a-google-demo", + redirectURL: "tdsdk://tdsdk/oauthCallback", + browserRedirectURL: "https://scripts.toruswallet.io/redirect.html" + + ) + customAuth = CustomAuth.init( + web3AuthClientId: "BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ", + aggregateVerifierType: .singleLogin, + aggregateVerifier: "w3a-google-demo", + subVerifierDetails: [subVerifierDetails], + network: .sapphire(.SAPPHIRE_MAINNET) + ) + } + } + + func login() { + Task { + do { + torusKeyDetails = try await customAuth.triggerLogin() + DispatchQueue.main.async { + self.isLoggedIn.toggle() + } + } catch let error { + print(error) + } + } + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/ViewModels/ThresholdKeyViewModel.swift b/tkey-ios-mpc/tkey-ios-mpc/ViewModels/ThresholdKeyViewModel.swift new file mode 100644 index 0000000..fc99526 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/ViewModels/ThresholdKeyViewModel.swift @@ -0,0 +1,759 @@ +// +// ThresholdKeyViewModel.swift +// tkey-ios-mpc +// +// Created by Ayush B on 22/03/24. +// + +import Foundation +import CustomAuth +import TorusUtils +import FetchNodeDetails +import CommonSources +import Web3SwiftMpcProvider +import web3 +import CryptoSwift +import UIKit +import tkey_mpc_swift + +class ThresholdKeyViewModel: ObservableObject { + + var userData: TorusKeyData + var ethereumClient: EthereumClient! + + init(userData: TorusKeyData) { + self.userData = userData + ethereumClient = EthereumClient() + } + + @Published var isAccounReady: Bool = false + @Published var showAlert: Bool = false + @Published var isTKeyInitialized: Bool = false + @Published var factorPubs: [String]! + @Published var isLoaderVisible: Bool = false + @Published var securityQuestion: String = "" + @Published var isReseted: Bool = false + + var verifier: String! + var verifierId: String! + var signatures: [[String: String]]! + var torusUtils: TorusUtils! + var nodeDetails: AllNodeDetailsModel! + var tssEndPoints: Array! + var thresholdKey: ThresholdKey! + var totalShares: Int! + var threshold: Int! + var requiredShares: Int! + var keyDetails: KeyDetails! + var address: String! + var ethereumAccount: EthereumTssAccount! + var activeFactor: String! + + var alertContent: String = "" + + func initialize() { + Task { + do { + guard let finalKeyData = userData.torusKey.finalKeyData else { + showAlert(alertContent:"Failed to get public address from userinfo") + return + } + + guard let verifierLocal = userData.userInfo["verifier"] as? String, let verifierIdLocal = userData.userInfo["verifierId"] as? String else { + showAlert(alertContent: "Failed to get verifier or verifierId from userinfo") + return + } + verifier = verifierLocal + verifierId = verifierIdLocal + + guard let postboxkey = finalKeyData.privKey else { + showAlert(alertContent:"Failed to get postboxkey") + return + } + + guard let sessionData = userData.torusKey.sessionData else { + showAlert(alertContent:"Failed to get sessionData") + return + } + + let sessionTokenData = sessionData.sessionTokenData + + signatures = sessionTokenData.map { token in + return [ "data": Data(hex: token!.token).base64EncodedString(), + "sig": token!.signature ] + } + assert(signatures.isEmpty != true) + + guard let storage_layer = try? StorageLayer( + enable_logging: true, + host_url: "https://metadata.tor.us", + server_time_offset: 2 + ) else { + showAlert(alertContent: "Failed to create storage layer") + return + } + + torusUtils = TorusUtils( + enableOneKey: true, + network: .sapphire(.SAPPHIRE_MAINNET), + clientId: "BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ" + ) + + let nodeDetailsManager = NodeDetailManager( + network: .sapphire(.SAPPHIRE_MAINNET) + ) + + nodeDetails = try await nodeDetailsManager.getNodeDetails( + verifier: verifier, verifierID: verifierId + ) + + tssEndPoints = nodeDetails!.torusNodeTSSEndpoints + + + guard let service_provider = try? ServiceProvider( + enable_logging: true, + postbox_key: postboxkey, + useTss: true, + verifier: verifier, + verifierId: verifierId, + nodeDetails: nodeDetails + ) + + else { + showAlert(alertContent: "Failed to create service provider") + return + } + + let rss_comm = try RssComm() + guard let thresholdKeyLocal = try? ThresholdKey( + storage_layer: storage_layer, + service_provider: service_provider, + enable_logging: true, + manual_sync: false, + rss_comm: rss_comm + ) else { + showAlert(alertContent: "Failed to create threshold key") + return + } + + thresholdKey = thresholdKeyLocal + + guard let keyDetailsLocal = try? await thresholdKey.initialize( + never_initialize_new_key: false, + include_local_metadata_transitions: false + ) else { + showAlert(alertContent: "Failed to get key details") + return + } + + keyDetails = keyDetailsLocal + + totalShares = Int(keyDetails.total_shares) + threshold = Int(keyDetails.threshold) + requiredShares = Int(keyDetails.required_shares) + + DispatchQueue.main.async { + self.isTKeyInitialized.toggle() + } + + + } catch let error { + throw error + } + } + } + + private func refreshFactorPubs() async throws { + do { + let tag = try TssModule.get_tss_tag(threshold_key: thresholdKey) + let factorPubsLocal = try await TssModule.get_all_factor_pub( + threshold_key: thresholdKey, tss_tag: tag + ) + + DispatchQueue.main.async { + self.factorPubs = factorPubsLocal + } + } catch let error { + throw error + } + } + + func reconstructWithSecurityQuestion(answer: String) { + Task { + do { + let isValidAnswer = try await SecurityQuestionModule.input_share( + threshold_key: thresholdKey, answer: answer + ) + + if(!isValidAnswer) { + showAlert(alertContent: "Not a valid answer") + return + } + + + guard let reconstructionDetails = try? await thresholdKey.reconstruct() + else { + showAlert( + alertContent:"Failed to reconstruct key with security question." + ) + return + } + + let factorKey = try recoverFactorFromSecurityAnswer(answer: answer) + activeFactor = factorKey.hex + + try await prepareEthTssAccout(factorKey: factorKey.hex) + try await refreshFactorPubs() + + DispatchQueue.main.async { + self.isAccounReady.toggle() + } + } catch let error { + showAlert(alertContent: error.localizedDescription) + } + } + } + + private func recoverFactorFromSecurityAnswer(answer: String) throws -> PrivateKey { + + do { + let pubKey = try thresholdKey.get_key_details().pub_key.getPublicKey( + format: .EllipticCompress + ) + + var pubKeyBytes = pubKey.bytes + pubKeyBytes.append(contentsOf: answer.bytes) + + let hash = CryptoSwift.SHA3(variant: .keccak256 + ).callAsFunction(pubKeyBytes).toHexString() + + let privateKey = PrivateKey(hex: hash) + return privateKey + } catch let error { + throw error + } + } + + func reconstructWithBackupFactor(backupFactor: String) { + Task { + do { + let hex = try ShareSerializationModule.deserialize_share( + threshold_key: thresholdKey, + share: backupFactor, + format: "mnemonic" + ) + let factorKey = PrivateKey.init(hex: hex) + try await thresholdKey.input_factor_key(factorKey: factorKey.hex) + + guard (try? await thresholdKey.reconstruct()) != nil + else { + showAlert( + alertContent:"Failed to reconstruct key with backup factor" + ) + return + } + + activeFactor = factorKey.hex + try await prepareEthTssAccout(factorKey: factorKey.hex) + try await refreshFactorPubs() + + DispatchQueue.main.async { + self.isAccounReady.toggle() + } + } catch let error { + showAlert(alertContent: error.localizedDescription) + } + } + } + + func reconstructWithDeviceShare() { + Task { + + let metadataPublicKey = try keyDetails.pub_key.getPublicKey( + format: .EllipticCompress + ) + + guard let factorPub = UserDefaults.standard.string( + forKey: metadataPublicKey + ) else { + showAlert(alertContent: "Failed to find device share.") + return + } + + var factorKey: String! + + do { + factorKey = try KeychainInterface.fetch(key: factorPub) + try await thresholdKey.input_factor_key(factorKey: factorKey) + let pk = PrivateKey(hex: factorKey) + activeFactor = factorKey + + } catch { + showAlert( + alertContent: "Failed to find device share or Incorrect device share" + ) + return + } + + guard let reconstructionDetails = try? await thresholdKey.reconstruct() else { + showAlert( + alertContent:"Failed to reconstruct key with available shares." + ) + return + } + + try await prepareEthTssAccout( + factorKey: factorKey + ) + + try await refreshFactorPubs() + + DispatchQueue.main.async { + self.isAccounReady.toggle() + } + } + } + + func addSecurityQuestion(question: String, answer: String) { + Task { + do { + + if(question.isEmpty || answer.isEmpty) { + showAlert(alertContent: "Question and Answer cannot be empty.") + return + } + + let privateKey = try recoverFactorFromSecurityAnswer(answer: answer) + + try await saveNewTSSFactor(newFactorKey: privateKey) + + + _ = try await SecurityQuestionModule.generate_new_share( + threshold_key: thresholdKey, + questions: question, + answer: answer + ) + + DispatchQueue.main.async { + self.securityQuestion = question + } + + } catch let error { + print(error.localizedDescription) + showAlert(alertContent: error.localizedDescription) + } + } + } + + private func toggleIsLoaderVisible() { + DispatchQueue.main.async { + self.isLoaderVisible.toggle() + } + } + + func resetAccount() { + Task { + do { + guard let finalKeyData = userData.torusKey.finalKeyData else { + showAlert(alertContent:"Failed to get public address from userinfo") + return + } + + guard let postboxkey = finalKeyData.privKey else { + showAlert(alertContent: "Failed to get public address from userinfo") + return + } + + let temp_storage_layer = try StorageLayer( + enable_logging: true, + host_url: "https://metadata.tor.us", + server_time_offset: 2 + ) + + let temp_service_provider = try ServiceProvider( + enable_logging: true, + postbox_key: postboxkey + ) + + let temp_threshold_key = try ThresholdKey( + storage_layer: temp_storage_layer, + service_provider: temp_service_provider, + enable_logging: true, + manual_sync: false + ) + + try await temp_threshold_key.storage_layer_set_metadata( + private_key: postboxkey, + json: "{ \"message\": \"KEY_NOT_FOUND\" }" + ) + + + showAlert(alertContent: "Account reset successful") + DispatchQueue.main.async { + self.isReseted = true + } + + } catch { + showAlert(alertContent: "Reset failed") + } + } + } + + func sendTransaction(onSend: @escaping (String?, String?) -> ()) { + Task { + do { + let address = self.ethereumAccount.address + let transaction = EthereumTransaction.init( + to: address, + data: Data.init(hex: "0x") + ) + + let gasLimit = try await self.ethereumClient.getGasLimit( + transaction: transaction + ) + let gasPrice = try await self.ethereumClient.getGasPrice() + let nonce = try await self.ethereumClient.getNonce(address: address) + + let finalTransaction = EthereumTransaction( + from: address, + to: address, + value: TorusWeb3Utils.toWei(ether: 0.001), + data: transaction.data, + nonce: nonce, + gasPrice: gasPrice, + gasLimit: gasLimit, + chainId: Int(self.ethereumClient.getChainId()) + ) + + let hash = try await self.ethereumClient.sendRawTransaction( + transaction: finalTransaction, + ethTssAccount: ethereumAccount + ) + + onSend(hash, nil) + + + } catch let error { + print(error.localizedDescription) + onSend(nil, error.localizedDescription) + } + } + } + + func deleteFactor(deleteFactorPub: String) { + Task { + var deleteFactorKey: String! + var tag: String! + do { + tag = try TssModule.get_tss_tag(threshold_key: thresholdKey) + deleteFactorKey = try KeychainInterface.fetch(key: deleteFactorPub) + } catch { + showAlert(alertContent: "There is no extra factor key to be deleted") + return + } + + + do { + let deleteFactorPrivateKey = PrivateKey(hex: deleteFactorKey) + + let factorKey = activeFactor + let sigs: [String] = try signatures.map { String( + decoding: try JSONSerialization.data(withJSONObject: $0), as: UTF8.self + )} + + try await TssModule.delete_factor_pub( + threshold_key: thresholdKey, + tss_tag: tag, + factor_key: factorKey!, + auth_signatures: sigs, + delete_factor_pub: deleteFactorPrivateKey.toPublic(), + nodeDetails: nodeDetails!, + torusUtils: torusUtils! + ) + + try KeychainInterface.save(item: "", key: deleteFactorKey) + try await refreshFactorPubs() + + showAlert(alertContent: "Deleted Factor Key :" + deleteFactorPub) + + } catch let error { + showAlert(alertContent: error.localizedDescription) + } + } + } + + func reconstructWithNewDeviceFactor() { + Task { + do { + let factorKey = try PrivateKey.generate() + try await _createDeviceFactor(factorKey: factorKey) + guard (try? await thresholdKey.reconstruct()) != nil else { + showAlert( + alertContent: "Failed to reconstruct key. \(keyDetails.required_shares) more share(s) required." + ) + + return + } + + activeFactor = factorKey.hex + + try await prepareEthTssAccout(factorKey: factorKey.hex) + + try await refreshFactorPubs() + + DispatchQueue.main.async { + self.isAccounReady.toggle() + } + + } catch let error { + showAlert(alertContent: error.localizedDescription) + } + } + } + + private func _createDeviceFactor(factorKey: PrivateKey) async throws { + do { + let factorPub = try factorKey.toPublic() + + let tssIndex = Int32(2) + let defaultTag = "default" + + try await TssModule.create_tagged_tss_share( + threshold_key: thresholdKey, + tss_tag: defaultTag, + deviceTssShare: nil, + factorPub: factorPub, + deviceTssIndex: tssIndex, + nodeDetails: self.nodeDetails!, + torusUtils: self.torusUtils! + ) + + + _ = try await TssModule.get_tss_pub_key( + threshold_key: thresholdKey, tss_tag: defaultTag + ) + + var shareIndexes = try thresholdKey.get_shares_indexes() + shareIndexes.removeAll(where: {$0 == "1"}) + + try TssModule.backup_share_with_factor_key( + threshold_key: thresholdKey, + shareIndex: shareIndexes[0], + factorKey: factorKey.hex + ) + + let description = [ + "module": "Device Factor key", + "tssTag": defaultTag, + "tssShareIndex": tssIndex, + "dateAdded": Date().timeIntervalSince1970 + ] as [String: Codable] + + let jsonStr = try factorDescription(dataObj: description) + + try await thresholdKey.add_share_description( + key: factorPub, + description: jsonStr + ) + + let metadataPublicKey = try keyDetails.pub_key.getPublicKey( + format: .EllipticCompress + ) + + + UserDefaults.standard.set(factorPub, forKey: metadataPublicKey) + + guard let _ = try? KeychainInterface.save( + item: factorKey.hex, + key: factorPub + ) else { + showAlert(alertContent: "Failed to save factor key") + + return + } + } catch let error { + throw error + } + } + + func createNewTSSFactor() { + Task { + do { + let newFactorKey = try PrivateKey.generate() + try await saveNewTSSFactor(newFactorKey: newFactorKey) + + } catch { + showAlert(alertContent: "Invalid Factor Key") + } + } + } + + private func saveNewTSSFactor(newFactorKey: PrivateKey) async throws { + do { + let newFactorPub = try newFactorKey.toPublic() + + // Use exising device factor to generate tss share with + // index 3 with new factor + let factorKey = activeFactor! + + let shareIndex = try await TssModule.find_device_share_index( + threshold_key: thresholdKey, + factor_key: factorKey + ) + + try TssModule.backup_share_with_factor_key( + threshold_key: thresholdKey, + shareIndex: shareIndex, + factorKey: newFactorKey.hex + ) + + // For now only tss index 2 and index 3 are supported. + // + // Index 2 is used device factor, and index 3 is used for + // recovery factor. + let tssShareIndex = Int32(3) + let sigs: [String] = try signatures.map {String( + decoding: + try JSONSerialization.data(withJSONObject: $0), as: UTF8.self + )} + + let tag = try TssModule.get_tss_tag(threshold_key: thresholdKey) + + try await TssModule.add_factor_pub( + threshold_key: thresholdKey, + tss_tag: tag, + factor_key: factorKey, + auth_signatures: sigs, + new_factor_pub: newFactorPub, + new_tss_index: tssShareIndex, + nodeDetails: nodeDetails!, + torusUtils: torusUtils! + ) + + let saveNewFactorId = newFactorPub + try KeychainInterface.save(item: newFactorKey.hex, key: saveNewFactorId) + + let description = [ + "module": "Manual Backup", + "tssTag": tag, + "tssShareIndex": tssShareIndex, + "dateAdded": Date().timeIntervalSince1970 + ] as [String: Codable] + + let jsonStr = try factorDescription(dataObj: description) + + try await thresholdKey.add_share_description( + key: newFactorPub, + description: jsonStr + ) + + let mnemonic = try ShareSerializationModule.serialize_share( + threshold_key: thresholdKey, + share: newFactorKey.hex, + format: "mnemonic" + ) + + UIPasteboard.general.string = mnemonic + + try await refreshFactorPubs() + } catch let error { + throw error + } + } + + func signMessage(onSigned: @escaping (_ signedMessage: String?, _ error: String?) -> ()){ + Task { + do { + toggleIsLoaderVisible() + let signature = try ethereumAccount.sign(message: "Welcome to Web3Auth") + toggleIsLoaderVisible() + onSigned(signature.toHexString(), nil) + } catch let error { + toggleIsLoaderVisible() + showAlert(alertContent: error.localizedDescription) + onSigned(nil, error.localizedDescription) + } + } + } + + + func factorDescription ( dataObj: [String: Codable] ) throws -> String { + let json = try JSONSerialization.data(withJSONObject: dataObj) + guard let jsonStr = String(data: json, encoding: .utf8) else { + throw "Invalid data structure" + } + return jsonStr + } + + private func showAlert(alertContent: String) { + DispatchQueue.main.async { + self.alertContent = alertContent + self.showAlert.toggle() + } + } + + private func prepareEthTssAccout( + factorKey: String + ) async throws { + let tag = try TssModule.get_tss_tag(threshold_key: thresholdKey) + let tssPublicKey = try await TssModule.get_tss_pub_key( + threshold_key: thresholdKey, tss_tag: tag + ) + + let keyPoint = try KeyPoint(address: tssPublicKey) + + address = try keyPoint.getPublicKey( + format: .FullAddress + ) + + let nonce = try TssModule.get_tss_nonce( + threshold_key: thresholdKey, tss_tag: tag + ) + + print(nonce.description) + + let (tssIndex, tssShare) = try await TssModule.get_tss_share( + threshold_key: thresholdKey, + tss_tag: tag, + factorKey: factorKey + ) + + let tssPublicAddressInfo = try await TssModule.get_dkg_pub_key( + threshold_key: thresholdKey, + tssTag: tag, + nonce: nonce.description, + nodeDetails: nodeDetails!, + torusUtils: torusUtils! + ) + + + let sigs: [String] = try signatures.map { String( + decoding: try JSONSerialization.data( + withJSONObject: $0 + ), as: UTF8.self) + } + + let fullAddress = try keyPoint.getPublicKey(format: .FullAddress) + + let ethTssAccountParams = EthTssAccountParams( + publicKey: fullAddress, + factorKey: factorKey, + tssNonce: nonce, + tssShare: tssShare, + tssIndex: tssIndex, + selectedTag: tag, + verifier: verifier, + verifierID: verifierId, + nodeIndexes: tssPublicAddressInfo.nodeIndexes.sorted(), + tssEndpoints: tssEndPoints, + authSigs: sigs + ) + + ethereumAccount = EthereumTssAccount( + params: ethTssAccountParams + ) + + address = ethereumAccount.address.asString() + print("Public Address: \(String(describing: address))") + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/Views/ContentView.swift b/tkey-ios-mpc/tkey-ios-mpc/Views/ContentView.swift new file mode 100644 index 0000000..ebb8deb --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/Views/ContentView.swift @@ -0,0 +1,29 @@ +// +// ContentView.swift +// tkey-ios-mpc +// +// Created by Ayush B on 22/03/24. +// + +import SwiftUI + +struct ContentView: View { + @StateObject var customAuthViewModel: CustomAuthViewModel + + var body: some View { + NavigationView { + if customAuthViewModel.isLoggedIn { + ThresholdKeyView(thresholdKeyViewModel: ThresholdKeyViewModel( + userData: customAuthViewModel.torusKeyDetails + )) + + } else { + LoginView(customAuthViewModel: customAuthViewModel) + } + } + } +} + +#Preview { + ContentView(customAuthViewModel: CustomAuthViewModel()) +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/Views/HomeView.swift b/tkey-ios-mpc/tkey-ios-mpc/Views/HomeView.swift new file mode 100644 index 0000000..00e1903 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/Views/HomeView.swift @@ -0,0 +1,136 @@ +// +// HomeView.swift +// tkey-ios-mpc +// +// Created by Ayush B on 22/03/24. +// + +import SwiftUI + +struct HomeView: View { + @StateObject var thresholdKeyViewModel: ThresholdKeyViewModel + @State var signedMessage: String? + @State var hash: String? + + @State private var answer: String = "" + @State private var question: String = "" + + var body: some View { + List { + Section( + header: Text("Public Address"), + content: { + Text( + thresholdKeyViewModel.address + ) + } + ) + Section( + header: Text("Chain interactions"), + content: { + Button( + action: { + thresholdKeyViewModel.signMessage{ + signedMessage,error in + self.signedMessage = signedMessage + } + }, + label: { + Text("Sign Message") + } + ) + + if(signedMessage != nil) { + Text(signedMessage!) + } + + Button( + action: { + thresholdKeyViewModel.sendTransaction { + hash, error in + self.hash = hash + } + }, + label: { + Text("Send 0.001 ETH") + } + ) + + if(hash != nil) { + Text(hash!) + } + } + ) + + Section( + header: Text("Other TSS Factors"), + content: { + let areOtherFactorsPresent = thresholdKeyViewModel.factorPubs.count > 0 + if(areOtherFactorsPresent) { + ForEach(Array(thresholdKeyViewModel.factorPubs), id: \.self) { factorPub in + HStack( + alignment: .top, + spacing: 24, + content: { + Text(factorPub) + Button(action: { + withAnimation { + thresholdKeyViewModel.deleteFactor( + deleteFactorPub: factorPub + ) + } + }) { + Label("",systemImage: "trash") + } + }) + } + } else { + Text("Only device factor found. Please create other TSS factor.") + } + } + ) + + Section( + header: Text("TSS Operations"), + content: { + Button( + action: { + thresholdKeyViewModel.createNewTSSFactor() + }, + label: { + Text("Create new TSS Factor") + } + ) + + Text("Security Question") + + TextField( + "Your security question", + text: $question + ) + + Text("Security Answer") + + TextField( + "Your security Answer", + text: $answer + ) + + Button( + action: { + thresholdKeyViewModel.addSecurityQuestion( + question: question, + answer: answer + ) + }, + label: { + Text("Add security question") + } + ) + } + ) + }.alert(isPresented: $thresholdKeyViewModel.showAlert, content: { + Alert(title: Text(thresholdKeyViewModel.alertContent)) + }) + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/Views/LoginView.swift b/tkey-ios-mpc/tkey-ios-mpc/Views/LoginView.swift new file mode 100644 index 0000000..a0c5715 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/Views/LoginView.swift @@ -0,0 +1,34 @@ +// +// LoginView.swift +// tkey-ios-mpc +// +// Created by Ayush B on 22/03/24. +// + +import Foundation + +import SwiftUI + +struct LoginView: View { + @StateObject var customAuthViewModel: CustomAuthViewModel + + var body: some View { + VStack(spacing: 16) { + Spacer() + Text("tKey iOS MPC Demo").font(.title).multilineTextAlignment(.center) + Button(action: { + customAuthViewModel.login() + }, label: { + Text("Sign in with Google") + }).buttonStyle(.bordered) + Spacer() + }.onAppear { + customAuthViewModel.intialize() + } + + } +} + +#Preview { + LoginView(customAuthViewModel: CustomAuthViewModel()) +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/Views/ThresholdKeyView.swift b/tkey-ios-mpc/tkey-ios-mpc/Views/ThresholdKeyView.swift new file mode 100644 index 0000000..f21f816 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/Views/ThresholdKeyView.swift @@ -0,0 +1,121 @@ +// +// ThresholdKeyView.swift +// tkey-ios-mpc +// +// Created by Ayush B on 26/03/24. +// + +import Foundation +import SwiftUI + +struct ThresholdKeyView: View { + @StateObject var thresholdKeyViewModel: ThresholdKeyViewModel + + var body: some View { + NavigationView { + if(!thresholdKeyViewModel.isAccounReady) { + if(!thresholdKeyViewModel.isTKeyInitialized) { + ProgressView() + } else { + ReconstructTKeyOptions( + thresholdKeyViewModel: thresholdKeyViewModel + ) + } + } else { + HomeView(thresholdKeyViewModel: thresholdKeyViewModel) + } + }.onAppear { + thresholdKeyViewModel.initialize() + } + } +} + +struct ReconstructTKeyOptions: View { + @StateObject var thresholdKeyViewModel: ThresholdKeyViewModel + @State private var backupFactor: String = "" + @State private var answer: String = "" + + var body: some View { + let isNewUser: Bool = thresholdKeyViewModel.requiredShares < 1 + List { + Section( + header: Text("Threshold Details"), + content: { + Text("Threshold: \(thresholdKeyViewModel.threshold)") + Text("Total Shares: \(thresholdKeyViewModel.totalShares)") + Text("Required Shares: \(thresholdKeyViewModel.requiredShares)") + Text("New user: \(isNewUser.description)") + + } + ) + + if(!isNewUser) { + Section( + header: Text("Reconstruct Options"), + content: { + Button(action: { + thresholdKeyViewModel.reconstructWithDeviceShare() + }, label: { + Text("Recover with Device share") + }) + } + ) + + Section( + header: Text("Recovery Options"), + content: { + TextField( + "Backup Factor in Mnemonic", + text: $backupFactor + ) + Button( + action: { + thresholdKeyViewModel.reconstructWithBackupFactor( + backupFactor: backupFactor + ) + }, + label: { + Text("Recover with backup") + } + ) + + TextField( + "Answer", + text: $answer + ) + + Button( + action: { + thresholdKeyViewModel.reconstructWithSecurityQuestion( + answer: answer + ) + }, + label: { + Text("Recover with Security Question") + } + ) + } + ) + + Section( + header: Text("Reset"), + content: { + Button(action: { + thresholdKeyViewModel.resetAccount() + }, label: { + Text("Reset Account") + }) + } + ) + } else { + Button(action: { + thresholdKeyViewModel.reconstructWithNewDeviceFactor() + }, label: { + Text("Create Device share") + }) + } + }.alert(isPresented: $thresholdKeyViewModel.showAlert, content: { + Alert(title: Text(thresholdKeyViewModel.alertContent)) + }) + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpc/tkey_ios_mpcApp.swift b/tkey-ios-mpc/tkey-ios-mpc/tkey_ios_mpcApp.swift new file mode 100644 index 0000000..97f7393 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpc/tkey_ios_mpcApp.swift @@ -0,0 +1,17 @@ +// +// tkey_ios_mpcApp.swift +// tkey-ios-mpc +// +// Created by Ayush B on 22/03/24. +// + +import SwiftUI + +@main +struct tkey_ios_mpcApp: App { + var body: some Scene { + WindowGroup { + ContentView(customAuthViewModel: CustomAuthViewModel()) + } + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpcTests/tkey_ios_mpcTests.swift b/tkey-ios-mpc/tkey-ios-mpcTests/tkey_ios_mpcTests.swift new file mode 100644 index 0000000..02e47b0 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpcTests/tkey_ios_mpcTests.swift @@ -0,0 +1,36 @@ +// +// tkey_ios_mpcTests.swift +// tkey-ios-mpcTests +// +// Created by Ayush B on 22/03/24. +// + +import XCTest +@testable import tkey_ios_mpc + +final class tkey_ios_mpcTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + // Any test you write for XCTest can be annotated as throws and async. + // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. + // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/tkey-ios-mpc/tkey-ios-mpcUITests/tkey_ios_mpcUITests.swift b/tkey-ios-mpc/tkey-ios-mpcUITests/tkey_ios_mpcUITests.swift new file mode 100644 index 0000000..077af8e --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpcUITests/tkey_ios_mpcUITests.swift @@ -0,0 +1,41 @@ +// +// tkey_ios_mpcUITests.swift +// tkey-ios-mpcUITests +// +// Created by Ayush B on 22/03/24. +// + +import XCTest + +final class tkey_ios_mpcUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testLaunchPerformance() throws { + if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } + } +} diff --git a/tkey-ios-mpc/tkey-ios-mpcUITests/tkey_ios_mpcUITestsLaunchTests.swift b/tkey-ios-mpc/tkey-ios-mpcUITests/tkey_ios_mpcUITestsLaunchTests.swift new file mode 100644 index 0000000..1d24028 --- /dev/null +++ b/tkey-ios-mpc/tkey-ios-mpcUITests/tkey_ios_mpcUITestsLaunchTests.swift @@ -0,0 +1,32 @@ +// +// tkey_ios_mpcUITestsLaunchTests.swift +// tkey-ios-mpcUITests +// +// Created by Ayush B on 22/03/24. +// + +import XCTest + +final class tkey_ios_mpcUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +}