diff --git a/Bitcoin Private.xcodeproj/project.pbxproj b/Bitcoin Private.xcodeproj/project.pbxproj new file mode 100644 index 0000000..390dcad --- /dev/null +++ b/Bitcoin Private.xcodeproj/project.pbxproj @@ -0,0 +1,735 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 48; + objects = { + +/* Begin PBXBuildFile section */ + EC367BAF205ABC37008FF479 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BAE205ABC37008FF479 /* AppDelegate.swift */; }; + EC367BB6205ABC37008FF479 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EC367BB5205ABC37008FF479 /* Assets.xcassets */; }; + EC367BB9205ABC37008FF479 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EC367BB7205ABC37008FF479 /* LaunchScreen.storyboard */; }; + EC367BC4205ABC37008FF479 /* Bitcoin_PrivateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BC3205ABC37008FF479 /* Bitcoin_PrivateTests.swift */; }; + EC367BCF205ABC37008FF479 /* Bitcoin_PrivateUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BCE205ABC37008FF479 /* Bitcoin_PrivateUITests.swift */; }; + EC367BF2205ABD7F008FF479 /* WalletViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367BDD205ABD7F008FF479 /* WalletViewController.xib */; }; + EC367BF3205ABD7F008FF479 /* VerificationViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367BDF205ABD7F008FF479 /* VerificationViewController.xib */; }; + EC367BF4205ABD7F008FF479 /* WalletTitleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BE0205ABD7F008FF479 /* WalletTitleViewController.swift */; }; + EC367BF5205ABD7F008FF479 /* MnemonicViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367BE1205ABD7F008FF479 /* MnemonicViewController.xib */; }; + EC367BF6205ABD7F008FF479 /* MnemonicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BE2205ABD7F008FF479 /* MnemonicViewController.swift */; }; + EC367BF7205ABD7F008FF479 /* VerificationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BE3205ABD7F008FF479 /* VerificationViewController.swift */; }; + EC367BF8205ABD7F008FF479 /* WalletTitleViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367BE4205ABD7F008FF479 /* WalletTitleViewController.xib */; }; + EC367BF9205ABD7F008FF479 /* PinViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BE5205ABD7F008FF479 /* PinViewController.swift */; }; + EC367BFA205ABD7F008FF479 /* PinViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367BE6205ABD7F008FF479 /* PinViewController.xib */; }; + EC367BFB205ABD7F008FF479 /* SendViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367BE7205ABD7F008FF479 /* SendViewController.xib */; }; + EC367BFC205ABD7F008FF479 /* ReceiveViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BE8205ABD7F008FF479 /* ReceiveViewController.swift */; }; + EC367BFD205ABD7F008FF479 /* ScanViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367BE9205ABD7F008FF479 /* ScanViewController.xib */; }; + EC367BFE205ABD7F008FF479 /* WalletViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BEA205ABD7F008FF479 /* WalletViewController.swift */; }; + EC367BFF205ABD7F008FF479 /* LaunchViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367BEB205ABD7F008FF479 /* LaunchViewController.xib */; }; + EC367C00205ABD7F008FF479 /* SendViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BEC205ABD7F008FF479 /* SendViewController.swift */; }; + EC367C01205ABD7F008FF479 /* SendAmountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BED205ABD7F008FF479 /* SendAmountViewController.swift */; }; + EC367C02205ABD7F008FF479 /* SendAmountViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367BEE205ABD7F008FF479 /* SendAmountViewController.xib */; }; + EC367C03205ABD7F008FF479 /* ScanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BEF205ABD7F008FF479 /* ScanViewController.swift */; }; + EC367C04205ABD7F008FF479 /* ReceiveViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367BF0205ABD7F008FF479 /* ReceiveViewController.xib */; }; + EC367C05205ABD7F008FF479 /* LaunchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367BF1205ABD7F008FF479 /* LaunchViewController.swift */; }; + EC367C0B205ABF48008FF479 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367C07205ABF48008FF479 /* Constants.swift */; }; + EC367C0D205ABF48008FF479 /* AppNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367C09205ABF48008FF479 /* AppNavigationController.swift */; }; + EC367C0E205ABF48008FF479 /* NibLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367C0A205ABF48008FF479 /* NibLoader.swift */; }; + EC367C1B205ABF52008FF479 /* WordSuggestionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367C11205ABF52008FF479 /* WordSuggestionCell.swift */; }; + EC367C1C205ABF52008FF479 /* WordSuggestionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367C12205ABF52008FF479 /* WordSuggestionCell.xib */; }; + EC367C1D205ABF52008FF479 /* TransactionHistoryCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367C13205ABF52008FF479 /* TransactionHistoryCell.xib */; }; + EC367C1E205ABF52008FF479 /* TransactionHistoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367C14205ABF52008FF479 /* TransactionHistoryCell.swift */; }; + EC367C1F205ABF52008FF479 /* WalletCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367C15205ABF52008FF479 /* WalletCell.xib */; }; + EC367C20205ABF52008FF479 /* WalletCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367C16205ABF52008FF479 /* WalletCell.swift */; }; + EC367C21205ABF52008FF479 /* PillView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367C17205ABF52008FF479 /* PillView.swift */; }; + EC367C22205ABF52008FF479 /* AppButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367C18205ABF52008FF479 /* AppButton.swift */; }; + EC367C23205ABF52008FF479 /* PinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367C19205ABF52008FF479 /* PinView.swift */; }; + EC367C24205ABF52008FF479 /* PinView.xib in Resources */ = {isa = PBXBuildFile; fileRef = EC367C1A205ABF52008FF479 /* PinView.xib */; }; + EC367C28205ABFD4008FF479 /* UIColor+Gradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367C26205ABFD4008FF479 /* UIColor+Gradient.swift */; }; + EC367C29205ABFD4008FF479 /* UIView+Shake.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC367C27205ABFD4008FF479 /* UIView+Shake.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + EC367BC0205ABC37008FF479 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = EC367BA3205ABC37008FF479 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EC367BAA205ABC37008FF479; + remoteInfo = "Bitcoin Private"; + }; + EC367BCB205ABC37008FF479 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = EC367BA3205ABC37008FF479 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EC367BAA205ABC37008FF479; + remoteInfo = "Bitcoin Private"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + EC367BAB205ABC37008FF479 /* Bitcoin Private.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Bitcoin Private.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + EC367BAE205ABC37008FF479 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + EC367BB5205ABC37008FF479 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + EC367BB8205ABC37008FF479 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + EC367BBA205ABC37008FF479 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EC367BBF205ABC37008FF479 /* Bitcoin PrivateTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Bitcoin PrivateTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + EC367BC3205ABC37008FF479 /* Bitcoin_PrivateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bitcoin_PrivateTests.swift; sourceTree = ""; }; + EC367BC5205ABC37008FF479 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EC367BCA205ABC37008FF479 /* Bitcoin PrivateUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Bitcoin PrivateUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + EC367BCE205ABC37008FF479 /* Bitcoin_PrivateUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bitcoin_PrivateUITests.swift; sourceTree = ""; }; + EC367BD0205ABC37008FF479 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EC367BDD205ABD7F008FF479 /* WalletViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WalletViewController.xib; sourceTree = ""; }; + EC367BDF205ABD7F008FF479 /* VerificationViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VerificationViewController.xib; sourceTree = ""; }; + EC367BE0205ABD7F008FF479 /* WalletTitleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletTitleViewController.swift; sourceTree = ""; }; + EC367BE1205ABD7F008FF479 /* MnemonicViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MnemonicViewController.xib; sourceTree = ""; }; + EC367BE2205ABD7F008FF479 /* MnemonicViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MnemonicViewController.swift; sourceTree = ""; }; + EC367BE3205ABD7F008FF479 /* VerificationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VerificationViewController.swift; sourceTree = ""; }; + EC367BE4205ABD7F008FF479 /* WalletTitleViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WalletTitleViewController.xib; sourceTree = ""; }; + EC367BE5205ABD7F008FF479 /* PinViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PinViewController.swift; sourceTree = ""; }; + EC367BE6205ABD7F008FF479 /* PinViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PinViewController.xib; sourceTree = ""; }; + EC367BE7205ABD7F008FF479 /* SendViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SendViewController.xib; sourceTree = ""; }; + EC367BE8205ABD7F008FF479 /* ReceiveViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReceiveViewController.swift; sourceTree = ""; }; + EC367BE9205ABD7F008FF479 /* ScanViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ScanViewController.xib; sourceTree = ""; }; + EC367BEA205ABD7F008FF479 /* WalletViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletViewController.swift; sourceTree = ""; }; + EC367BEB205ABD7F008FF479 /* LaunchViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchViewController.xib; sourceTree = ""; }; + EC367BEC205ABD7F008FF479 /* SendViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendViewController.swift; sourceTree = ""; }; + EC367BED205ABD7F008FF479 /* SendAmountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendAmountViewController.swift; sourceTree = ""; }; + EC367BEE205ABD7F008FF479 /* SendAmountViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SendAmountViewController.xib; sourceTree = ""; }; + EC367BEF205ABD7F008FF479 /* ScanViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScanViewController.swift; sourceTree = ""; }; + EC367BF0205ABD7F008FF479 /* ReceiveViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ReceiveViewController.xib; sourceTree = ""; }; + EC367BF1205ABD7F008FF479 /* LaunchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LaunchViewController.swift; sourceTree = ""; }; + EC367C07205ABF48008FF479 /* Constants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; + EC367C09205ABF48008FF479 /* AppNavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppNavigationController.swift; sourceTree = ""; }; + EC367C0A205ABF48008FF479 /* NibLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NibLoader.swift; sourceTree = ""; }; + EC367C11205ABF52008FF479 /* WordSuggestionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WordSuggestionCell.swift; sourceTree = ""; }; + EC367C12205ABF52008FF479 /* WordSuggestionCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WordSuggestionCell.xib; sourceTree = ""; }; + EC367C13205ABF52008FF479 /* TransactionHistoryCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TransactionHistoryCell.xib; sourceTree = ""; }; + EC367C14205ABF52008FF479 /* TransactionHistoryCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionHistoryCell.swift; sourceTree = ""; }; + EC367C15205ABF52008FF479 /* WalletCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WalletCell.xib; sourceTree = ""; }; + EC367C16205ABF52008FF479 /* WalletCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletCell.swift; sourceTree = ""; }; + EC367C17205ABF52008FF479 /* PillView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PillView.swift; sourceTree = ""; }; + EC367C18205ABF52008FF479 /* AppButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppButton.swift; sourceTree = ""; }; + EC367C19205ABF52008FF479 /* PinView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PinView.swift; sourceTree = ""; }; + EC367C1A205ABF52008FF479 /* PinView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = PinView.xib; sourceTree = ""; }; + EC367C26205ABFD4008FF479 /* UIColor+Gradient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Gradient.swift"; sourceTree = ""; }; + EC367C27205ABFD4008FF479 /* UIView+Shake.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Shake.swift"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + EC367BA8205ABC37008FF479 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EC367BBC205ABC37008FF479 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EC367BC7205ABC37008FF479 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + EC367BA2205ABC37008FF479 = { + isa = PBXGroup; + children = ( + EC367BAD205ABC37008FF479 /* Bitcoin Private */, + EC367BC2205ABC37008FF479 /* Bitcoin PrivateTests */, + EC367BCD205ABC37008FF479 /* Bitcoin PrivateUITests */, + EC367BAC205ABC37008FF479 /* Products */, + ); + sourceTree = ""; + }; + EC367BAC205ABC37008FF479 /* Products */ = { + isa = PBXGroup; + children = ( + EC367BAB205ABC37008FF479 /* Bitcoin Private.app */, + EC367BBF205ABC37008FF479 /* Bitcoin PrivateTests.xctest */, + EC367BCA205ABC37008FF479 /* Bitcoin PrivateUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + EC367BAD205ABC37008FF479 /* Bitcoin Private */ = { + isa = PBXGroup; + children = ( + EC367BAE205ABC37008FF479 /* AppDelegate.swift */, + EC367C25205ABFD4008FF479 /* Extensions */, + EC367C0F205ABF52008FF479 /* Views */, + EC367C06205ABF48008FF479 /* Utils */, + EC367BDC205ABD7F008FF479 /* View Controllers */, + EC367BB5205ABC37008FF479 /* Assets.xcassets */, + EC367BB7205ABC37008FF479 /* LaunchScreen.storyboard */, + EC367BBA205ABC37008FF479 /* Info.plist */, + ); + path = "Bitcoin Private"; + sourceTree = ""; + }; + EC367BC2205ABC37008FF479 /* Bitcoin PrivateTests */ = { + isa = PBXGroup; + children = ( + EC367BC3205ABC37008FF479 /* Bitcoin_PrivateTests.swift */, + EC367BC5205ABC37008FF479 /* Info.plist */, + ); + path = "Bitcoin PrivateTests"; + sourceTree = ""; + }; + EC367BCD205ABC37008FF479 /* Bitcoin PrivateUITests */ = { + isa = PBXGroup; + children = ( + EC367BCE205ABC37008FF479 /* Bitcoin_PrivateUITests.swift */, + EC367BD0205ABC37008FF479 /* Info.plist */, + ); + path = "Bitcoin PrivateUITests"; + sourceTree = ""; + }; + EC367BDC205ABD7F008FF479 /* View Controllers */ = { + isa = PBXGroup; + children = ( + EC367BDE205ABD7F008FF479 /* Wallet Creation and Restoration */, + EC367BF1205ABD7F008FF479 /* LaunchViewController.swift */, + EC367BEB205ABD7F008FF479 /* LaunchViewController.xib */, + EC367BEF205ABD7F008FF479 /* ScanViewController.swift */, + EC367BE9205ABD7F008FF479 /* ScanViewController.xib */, + EC367BEC205ABD7F008FF479 /* SendViewController.swift */, + EC367BE7205ABD7F008FF479 /* SendViewController.xib */, + EC367BED205ABD7F008FF479 /* SendAmountViewController.swift */, + EC367BEE205ABD7F008FF479 /* SendAmountViewController.xib */, + EC367BE8205ABD7F008FF479 /* ReceiveViewController.swift */, + EC367BF0205ABD7F008FF479 /* ReceiveViewController.xib */, + EC367BEA205ABD7F008FF479 /* WalletViewController.swift */, + EC367BDD205ABD7F008FF479 /* WalletViewController.xib */, + ); + path = "View Controllers"; + sourceTree = ""; + }; + EC367BDE205ABD7F008FF479 /* Wallet Creation and Restoration */ = { + isa = PBXGroup; + children = ( + EC367BE2205ABD7F008FF479 /* MnemonicViewController.swift */, + EC367BE1205ABD7F008FF479 /* MnemonicViewController.xib */, + EC367BE5205ABD7F008FF479 /* PinViewController.swift */, + EC367BE6205ABD7F008FF479 /* PinViewController.xib */, + EC367BE3205ABD7F008FF479 /* VerificationViewController.swift */, + EC367BDF205ABD7F008FF479 /* VerificationViewController.xib */, + EC367BE0205ABD7F008FF479 /* WalletTitleViewController.swift */, + EC367BE4205ABD7F008FF479 /* WalletTitleViewController.xib */, + ); + path = "Wallet Creation and Restoration"; + sourceTree = ""; + }; + EC367C06205ABF48008FF479 /* Utils */ = { + isa = PBXGroup; + children = ( + EC367C07205ABF48008FF479 /* Constants.swift */, + EC367C09205ABF48008FF479 /* AppNavigationController.swift */, + EC367C0A205ABF48008FF479 /* NibLoader.swift */, + ); + path = Utils; + sourceTree = ""; + }; + EC367C0F205ABF52008FF479 /* Views */ = { + isa = PBXGroup; + children = ( + EC367C10205ABF52008FF479 /* Cells */, + EC367C17205ABF52008FF479 /* PillView.swift */, + EC367C18205ABF52008FF479 /* AppButton.swift */, + EC367C19205ABF52008FF479 /* PinView.swift */, + EC367C1A205ABF52008FF479 /* PinView.xib */, + ); + path = Views; + sourceTree = ""; + }; + EC367C10205ABF52008FF479 /* Cells */ = { + isa = PBXGroup; + children = ( + EC367C11205ABF52008FF479 /* WordSuggestionCell.swift */, + EC367C12205ABF52008FF479 /* WordSuggestionCell.xib */, + EC367C14205ABF52008FF479 /* TransactionHistoryCell.swift */, + EC367C13205ABF52008FF479 /* TransactionHistoryCell.xib */, + EC367C16205ABF52008FF479 /* WalletCell.swift */, + EC367C15205ABF52008FF479 /* WalletCell.xib */, + ); + path = Cells; + sourceTree = ""; + }; + EC367C25205ABFD4008FF479 /* Extensions */ = { + isa = PBXGroup; + children = ( + EC367C26205ABFD4008FF479 /* UIColor+Gradient.swift */, + EC367C27205ABFD4008FF479 /* UIView+Shake.swift */, + ); + path = Extensions; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + EC367BAA205ABC37008FF479 /* Bitcoin Private */ = { + isa = PBXNativeTarget; + buildConfigurationList = EC367BD3205ABC38008FF479 /* Build configuration list for PBXNativeTarget "Bitcoin Private" */; + buildPhases = ( + EC367BA7205ABC37008FF479 /* Sources */, + EC367BA8205ABC37008FF479 /* Frameworks */, + EC367BA9205ABC37008FF479 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Bitcoin Private"; + productName = "Bitcoin Private"; + productReference = EC367BAB205ABC37008FF479 /* Bitcoin Private.app */; + productType = "com.apple.product-type.application"; + }; + EC367BBE205ABC37008FF479 /* Bitcoin PrivateTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = EC367BD6205ABC38008FF479 /* Build configuration list for PBXNativeTarget "Bitcoin PrivateTests" */; + buildPhases = ( + EC367BBB205ABC37008FF479 /* Sources */, + EC367BBC205ABC37008FF479 /* Frameworks */, + EC367BBD205ABC37008FF479 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + EC367BC1205ABC37008FF479 /* PBXTargetDependency */, + ); + name = "Bitcoin PrivateTests"; + productName = "Bitcoin PrivateTests"; + productReference = EC367BBF205ABC37008FF479 /* Bitcoin PrivateTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + EC367BC9205ABC37008FF479 /* Bitcoin PrivateUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = EC367BD9205ABC38008FF479 /* Build configuration list for PBXNativeTarget "Bitcoin PrivateUITests" */; + buildPhases = ( + EC367BC6205ABC37008FF479 /* Sources */, + EC367BC7205ABC37008FF479 /* Frameworks */, + EC367BC8205ABC37008FF479 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + EC367BCC205ABC37008FF479 /* PBXTargetDependency */, + ); + name = "Bitcoin PrivateUITests"; + productName = "Bitcoin PrivateUITests"; + productReference = EC367BCA205ABC37008FF479 /* Bitcoin PrivateUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + EC367BA3205ABC37008FF479 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 0920; + ORGANIZATIONNAME = "Satraj Bambra"; + TargetAttributes = { + EC367BAA205ABC37008FF479 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + }; + EC367BBE205ABC37008FF479 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + TestTargetID = EC367BAA205ABC37008FF479; + }; + EC367BC9205ABC37008FF479 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Automatic; + TestTargetID = EC367BAA205ABC37008FF479; + }; + }; + }; + buildConfigurationList = EC367BA6205ABC37008FF479 /* Build configuration list for PBXProject "Bitcoin Private" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = EC367BA2205ABC37008FF479; + productRefGroup = EC367BAC205ABC37008FF479 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + EC367BAA205ABC37008FF479 /* Bitcoin Private */, + EC367BBE205ABC37008FF479 /* Bitcoin PrivateTests */, + EC367BC9205ABC37008FF479 /* Bitcoin PrivateUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + EC367BA9205ABC37008FF479 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EC367C04205ABD7F008FF479 /* ReceiveViewController.xib in Resources */, + EC367BFD205ABD7F008FF479 /* ScanViewController.xib in Resources */, + EC367BFB205ABD7F008FF479 /* SendViewController.xib in Resources */, + EC367BF5205ABD7F008FF479 /* MnemonicViewController.xib in Resources */, + EC367BB9205ABC37008FF479 /* LaunchScreen.storyboard in Resources */, + EC367BF3205ABD7F008FF479 /* VerificationViewController.xib in Resources */, + EC367C1C205ABF52008FF479 /* WordSuggestionCell.xib in Resources */, + EC367BB6205ABC37008FF479 /* Assets.xcassets in Resources */, + EC367BF8205ABD7F008FF479 /* WalletTitleViewController.xib in Resources */, + EC367C1D205ABF52008FF479 /* TransactionHistoryCell.xib in Resources */, + EC367BFF205ABD7F008FF479 /* LaunchViewController.xib in Resources */, + EC367C02205ABD7F008FF479 /* SendAmountViewController.xib in Resources */, + EC367BF2205ABD7F008FF479 /* WalletViewController.xib in Resources */, + EC367C1F205ABF52008FF479 /* WalletCell.xib in Resources */, + EC367C24205ABF52008FF479 /* PinView.xib in Resources */, + EC367BFA205ABD7F008FF479 /* PinViewController.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EC367BBD205ABC37008FF479 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EC367BC8205ABC37008FF479 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + EC367BA7205ABC37008FF479 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EC367BF6205ABD7F008FF479 /* MnemonicViewController.swift in Sources */, + EC367C21205ABF52008FF479 /* PillView.swift in Sources */, + EC367BF4205ABD7F008FF479 /* WalletTitleViewController.swift in Sources */, + EC367C00205ABD7F008FF479 /* SendViewController.swift in Sources */, + EC367C03205ABD7F008FF479 /* ScanViewController.swift in Sources */, + EC367BF9205ABD7F008FF479 /* PinViewController.swift in Sources */, + EC367C1E205ABF52008FF479 /* TransactionHistoryCell.swift in Sources */, + EC367C29205ABFD4008FF479 /* UIView+Shake.swift in Sources */, + EC367C20205ABF52008FF479 /* WalletCell.swift in Sources */, + EC367C23205ABF52008FF479 /* PinView.swift in Sources */, + EC367BF7205ABD7F008FF479 /* VerificationViewController.swift in Sources */, + EC367BFC205ABD7F008FF479 /* ReceiveViewController.swift in Sources */, + EC367C0B205ABF48008FF479 /* Constants.swift in Sources */, + EC367C05205ABD7F008FF479 /* LaunchViewController.swift in Sources */, + EC367C22205ABF52008FF479 /* AppButton.swift in Sources */, + EC367C0D205ABF48008FF479 /* AppNavigationController.swift in Sources */, + EC367C1B205ABF52008FF479 /* WordSuggestionCell.swift in Sources */, + EC367C0E205ABF48008FF479 /* NibLoader.swift in Sources */, + EC367C28205ABFD4008FF479 /* UIColor+Gradient.swift in Sources */, + EC367C01205ABD7F008FF479 /* SendAmountViewController.swift in Sources */, + EC367BFE205ABD7F008FF479 /* WalletViewController.swift in Sources */, + EC367BAF205ABC37008FF479 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EC367BBB205ABC37008FF479 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EC367BC4205ABC37008FF479 /* Bitcoin_PrivateTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EC367BC6205ABC37008FF479 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EC367BCF205ABC37008FF479 /* Bitcoin_PrivateUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + EC367BC1205ABC37008FF479 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EC367BAA205ABC37008FF479 /* Bitcoin Private */; + targetProxy = EC367BC0205ABC37008FF479 /* PBXContainerItemProxy */; + }; + EC367BCC205ABC37008FF479 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EC367BAA205ABC37008FF479 /* Bitcoin Private */; + targetProxy = EC367BCB205ABC37008FF479 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + EC367BB7205ABC37008FF479 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + EC367BB8205ABC37008FF479 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + EC367BD1205ABC38008FF479 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = 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_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + 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; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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 = 11.2; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + EC367BD2205ABC38008FF479 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = 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_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + 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; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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 = 11.2; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + EC367BD4205ABC38008FF479 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 2C24FP5V5L; + INFOPLIST_FILE = "Bitcoin Private/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.btcp.Bitcoin-Private"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + EC367BD5205ABC38008FF479 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 2C24FP5V5L; + INFOPLIST_FILE = "Bitcoin Private/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.btcp.Bitcoin-Private"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Release; + }; + EC367BD7205ABC38008FF479 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 2C24FP5V5L; + INFOPLIST_FILE = "Bitcoin PrivateTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.btcp.Bitcoin-PrivateTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Bitcoin Private.app/Bitcoin Private"; + }; + name = Debug; + }; + EC367BD8205ABC38008FF479 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 2C24FP5V5L; + INFOPLIST_FILE = "Bitcoin PrivateTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.btcp.Bitcoin-PrivateTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Bitcoin Private.app/Bitcoin Private"; + }; + name = Release; + }; + EC367BDA205ABC38008FF479 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 2C24FP5V5L; + INFOPLIST_FILE = "Bitcoin PrivateUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.btcp.Bitcoin-PrivateUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "Bitcoin Private"; + }; + name = Debug; + }; + EC367BDB205ABC38008FF479 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 2C24FP5V5L; + INFOPLIST_FILE = "Bitcoin PrivateUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "com.btcp.Bitcoin-PrivateUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "Bitcoin Private"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + EC367BA6205ABC37008FF479 /* Build configuration list for PBXProject "Bitcoin Private" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EC367BD1205ABC38008FF479 /* Debug */, + EC367BD2205ABC38008FF479 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EC367BD3205ABC38008FF479 /* Build configuration list for PBXNativeTarget "Bitcoin Private" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EC367BD4205ABC38008FF479 /* Debug */, + EC367BD5205ABC38008FF479 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EC367BD6205ABC38008FF479 /* Build configuration list for PBXNativeTarget "Bitcoin PrivateTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EC367BD7205ABC38008FF479 /* Debug */, + EC367BD8205ABC38008FF479 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EC367BD9205ABC38008FF479 /* Build configuration list for PBXNativeTarget "Bitcoin PrivateUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EC367BDA205ABC38008FF479 /* Debug */, + EC367BDB205ABC38008FF479 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = EC367BA3205ABC37008FF479 /* Project object */; +} diff --git a/Bitcoin Private.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Bitcoin Private.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..49cf5ea --- /dev/null +++ b/Bitcoin Private.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Bitcoin Private.xcodeproj/project.xcworkspace/xcuserdata/satrajbambra.xcuserdatad/UserInterfaceState.xcuserstate b/Bitcoin Private.xcodeproj/project.xcworkspace/xcuserdata/satrajbambra.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..aa267f3 Binary files /dev/null and b/Bitcoin Private.xcodeproj/project.xcworkspace/xcuserdata/satrajbambra.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Bitcoin Private.xcodeproj/xcuserdata/satrajbambra.xcuserdatad/xcschemes/xcschememanagement.plist b/Bitcoin Private.xcodeproj/xcuserdata/satrajbambra.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..e3cde14 --- /dev/null +++ b/Bitcoin Private.xcodeproj/xcuserdata/satrajbambra.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + Bitcoin Private.xcscheme + + orderHint + 0 + + + + diff --git a/Bitcoin Private/AppDelegate.swift b/Bitcoin Private/AppDelegate.swift new file mode 100644 index 0000000..d711e1a --- /dev/null +++ b/Bitcoin Private/AppDelegate.swift @@ -0,0 +1,51 @@ +// +// AppDelegate.swift +// Bitcoin Private +// +// Created by Satraj Bambra on 2018-03-15. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + let launchViewController = LaunchViewController() + let launchNavController = AppNavigationController.init(rootViewController: launchViewController) + + window = window ?? UIWindow(frame: CGRect(origin: CGPoint.zero, size: UIScreen.main.bounds.size)) + window?.rootViewController = launchNavController + window?.makeKeyAndVisible() + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Bitcoin Private/Assets.xcassets/AppIcon.appiconset/Contents.json b/Bitcoin Private/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/Bitcoin Private/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Bitcoin Private/Assets.xcassets/Contents.json b/Bitcoin Private/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Bitcoin Private/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Bitcoin Private/Assets.xcassets/backspace.imageset/Contents.json b/Bitcoin Private/Assets.xcassets/backspace.imageset/Contents.json new file mode 100644 index 0000000..81f3e0a --- /dev/null +++ b/Bitcoin Private/Assets.xcassets/backspace.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon--backspace.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icon--backspace@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icon--backspace@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Bitcoin Private/Assets.xcassets/backspace.imageset/icon--backspace.png b/Bitcoin Private/Assets.xcassets/backspace.imageset/icon--backspace.png new file mode 100644 index 0000000..b543841 Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/backspace.imageset/icon--backspace.png differ diff --git a/Bitcoin Private/Assets.xcassets/backspace.imageset/icon--backspace@2x.png b/Bitcoin Private/Assets.xcassets/backspace.imageset/icon--backspace@2x.png new file mode 100644 index 0000000..d40a2c6 Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/backspace.imageset/icon--backspace@2x.png differ diff --git a/Bitcoin Private/Assets.xcassets/backspace.imageset/icon--backspace@3x.png b/Bitcoin Private/Assets.xcassets/backspace.imageset/icon--backspace@3x.png new file mode 100644 index 0000000..9feac3e Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/backspace.imageset/icon--backspace@3x.png differ diff --git a/Bitcoin Private/Assets.xcassets/camera.imageset/Contents.json b/Bitcoin Private/Assets.xcassets/camera.imageset/Contents.json new file mode 100644 index 0000000..a85fa25 --- /dev/null +++ b/Bitcoin Private/Assets.xcassets/camera.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "group4.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "group4@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "group4@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Bitcoin Private/Assets.xcassets/camera.imageset/group4.png b/Bitcoin Private/Assets.xcassets/camera.imageset/group4.png new file mode 100644 index 0000000..54ade20 Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/camera.imageset/group4.png differ diff --git a/Bitcoin Private/Assets.xcassets/camera.imageset/group4@2x.png b/Bitcoin Private/Assets.xcassets/camera.imageset/group4@2x.png new file mode 100644 index 0000000..06f212c Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/camera.imageset/group4@2x.png differ diff --git a/Bitcoin Private/Assets.xcassets/camera.imageset/group4@3x.png b/Bitcoin Private/Assets.xcassets/camera.imageset/group4@3x.png new file mode 100644 index 0000000..d4ba510 Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/camera.imageset/group4@3x.png differ diff --git a/Bitcoin Private/Assets.xcassets/close.imageset/Contents.json b/Bitcoin Private/Assets.xcassets/close.imageset/Contents.json new file mode 100644 index 0000000..ce0bef5 --- /dev/null +++ b/Bitcoin Private/Assets.xcassets/close.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "close.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "close@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "close@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Bitcoin Private/Assets.xcassets/close.imageset/close.png b/Bitcoin Private/Assets.xcassets/close.imageset/close.png new file mode 100644 index 0000000..1f164e4 Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/close.imageset/close.png differ diff --git a/Bitcoin Private/Assets.xcassets/close.imageset/close@2x.png b/Bitcoin Private/Assets.xcassets/close.imageset/close@2x.png new file mode 100644 index 0000000..a1d016f Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/close.imageset/close@2x.png differ diff --git a/Bitcoin Private/Assets.xcassets/close.imageset/close@3x.png b/Bitcoin Private/Assets.xcassets/close.imageset/close@3x.png new file mode 100644 index 0000000..1c9e2a1 Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/close.imageset/close@3x.png differ diff --git a/Bitcoin Private/Assets.xcassets/copy.imageset/Contents.json b/Bitcoin Private/Assets.xcassets/copy.imageset/Contents.json new file mode 100644 index 0000000..bc2a0a5 --- /dev/null +++ b/Bitcoin Private/Assets.xcassets/copy.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "fill2.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "fill2@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "fill2@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Bitcoin Private/Assets.xcassets/copy.imageset/fill2.png b/Bitcoin Private/Assets.xcassets/copy.imageset/fill2.png new file mode 100644 index 0000000..bda3cc4 Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/copy.imageset/fill2.png differ diff --git a/Bitcoin Private/Assets.xcassets/copy.imageset/fill2@2x.png b/Bitcoin Private/Assets.xcassets/copy.imageset/fill2@2x.png new file mode 100644 index 0000000..43b107a Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/copy.imageset/fill2@2x.png differ diff --git a/Bitcoin Private/Assets.xcassets/copy.imageset/fill2@3x.png b/Bitcoin Private/Assets.xcassets/copy.imageset/fill2@3x.png new file mode 100644 index 0000000..4557c61 Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/copy.imageset/fill2@3x.png differ diff --git a/Bitcoin Private/Assets.xcassets/icon.imageset/Contents.json b/Bitcoin Private/Assets.xcassets/icon.imageset/Contents.json new file mode 100644 index 0000000..7e664dd --- /dev/null +++ b/Bitcoin Private/Assets.xcassets/icon.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icon@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Bitcoin Private/Assets.xcassets/icon.imageset/icon@2x.png b/Bitcoin Private/Assets.xcassets/icon.imageset/icon@2x.png new file mode 100644 index 0000000..206d973 Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/icon.imageset/icon@2x.png differ diff --git a/Bitcoin Private/Assets.xcassets/icon.imageset/icon@3x.png b/Bitcoin Private/Assets.xcassets/icon.imageset/icon@3x.png new file mode 100644 index 0000000..75a282d Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/icon.imageset/icon@3x.png differ diff --git a/Bitcoin Private/Assets.xcassets/icon_small.imageset/Contents.json b/Bitcoin Private/Assets.xcassets/icon_small.imageset/Contents.json new file mode 100644 index 0000000..71bdffb --- /dev/null +++ b/Bitcoin Private/Assets.xcassets/icon_small.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icon_small@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Bitcoin Private/Assets.xcassets/icon_small.imageset/icon_small@2x.png b/Bitcoin Private/Assets.xcassets/icon_small.imageset/icon_small@2x.png new file mode 100644 index 0000000..e8fb34c Binary files /dev/null and b/Bitcoin Private/Assets.xcassets/icon_small.imageset/icon_small@2x.png differ diff --git a/Bitcoin Private/Base.lproj/LaunchScreen.storyboard b/Bitcoin Private/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..e99a55e --- /dev/null +++ b/Bitcoin Private/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/Extensions/UIColor+Gradient.swift b/Bitcoin Private/Extensions/UIColor+Gradient.swift new file mode 100644 index 0000000..4fb99c2 --- /dev/null +++ b/Bitcoin Private/Extensions/UIColor+Gradient.swift @@ -0,0 +1,82 @@ +// +// UIColor+Gradient.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-09. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// +import UIKit + +extension UIColor { + convenience init(_ hex: UInt) { + self.init( + red: CGFloat((hex & 0xFF0000) >> 16) / 255.0, + green: CGFloat((hex & 0x00FF00) >> 8) / 255.0, + blue: CGFloat(hex & 0x0000FF) / 255.0, + alpha: CGFloat(1.0) + ) + } +} + +typealias GradientType = (x: CGPoint, y: CGPoint) + +enum GradientPoint { + case leftRight + case rightLeft + case topBottom + case bottomTop + case topLeftBottomRight + case bottomRightTopLeft + case topRightBottomLeft + case bottomLeftTopRight + + func draw() -> GradientType { + switch self { + case .leftRight: + return (x: CGPoint(x: 0, y: 0.5), y: CGPoint(x: 1, y: 0.5)) + case .rightLeft: + return (x: CGPoint(x: 1, y: 0.5), y: CGPoint(x: 0, y: 0.5)) + case .topBottom: + return (x: CGPoint(x: 0.5, y: 0), y: CGPoint(x: 0.5, y: 1)) + case .bottomTop: + return (x: CGPoint(x: 0.5, y: 1), y: CGPoint(x: 0.5, y: 0)) + case .topLeftBottomRight: + return (x: CGPoint(x: 0, y: 0), y: CGPoint(x: 1, y: 1)) + case .bottomRightTopLeft: + return (x: CGPoint(x: 1, y: 1), y: CGPoint(x: 0, y: 0)) + case .topRightBottomLeft: + return (x: CGPoint(x: 1, y: 0), y: CGPoint(x: 0, y: 1)) + case .bottomLeftTopRight: + return (x: CGPoint(x: 0, y: 1), y: CGPoint(x: 1, y: 0)) + } + } +} + +class GradientLayer : CAGradientLayer { + var gradient: GradientType? { + didSet { + startPoint = gradient?.x ?? CGPoint.zero + endPoint = gradient?.y ?? CGPoint.zero + } + } +} + +class GradientView: UIView { + override public class var layerClass: Swift.AnyClass { + get { + return GradientLayer.self + } + } +} + +protocol GradientViewProvider { + associatedtype GradientViewType +} + +extension GradientViewProvider where Self: UIView { + var gradientLayer: GradientViewType { return layer as! GradientViewType } +} + +extension UIView: GradientViewProvider { + typealias GradientViewType = GradientLayer +} diff --git a/Bitcoin Private/Extensions/UIView+Shake.swift b/Bitcoin Private/Extensions/UIView+Shake.swift new file mode 100644 index 0000000..24432b2 --- /dev/null +++ b/Bitcoin Private/Extensions/UIView+Shake.swift @@ -0,0 +1,21 @@ +// +// UIView+Shake.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-13. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +public extension UIView { + func shake(count : Float = 4.0,for duration : TimeInterval = 0.3,withTranslation translation : Float = 10) { + let animation : CABasicAnimation = CABasicAnimation(keyPath: "transform.translation.x") + animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + animation.repeatCount = count + animation.duration = duration/TimeInterval(animation.repeatCount) + animation.autoreverses = true + animation.byValue = translation + layer.add(animation, forKey: "shake") + } +} diff --git a/Bitcoin Private/Info.plist b/Bitcoin Private/Info.plist new file mode 100644 index 0000000..5201a97 --- /dev/null +++ b/Bitcoin Private/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + NSCameraUsageDescription + Scanning QR codes + + diff --git a/Bitcoin Private/Utils/AppNavigationController.swift b/Bitcoin Private/Utils/AppNavigationController.swift new file mode 100644 index 0000000..1b702f3 --- /dev/null +++ b/Bitcoin Private/Utils/AppNavigationController.swift @@ -0,0 +1,43 @@ +// +// AppNavigationController.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-10. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +protocol AccountCreationDelegate: class { + func createAccount(mnemonic: String) +} + +class AppNavigationController: UINavigationController { + weak var accountCreationDelegate: AccountCreationDelegate? + + override func viewDidLoad() { + super.viewDidLoad() + + setupView() + } + + func setupView() { + navigationBar.isTranslucent = false + navigationBar.tintColor = Colors.primaryDark + navigationBar.barTintColor = Colors.white + navigationBar.titleTextAttributes = [ + NSAttributedStringKey.foregroundColor : Colors.primaryDark + ] + + navigationBar.backgroundColor = Colors.white + + } + + func image(fromLayer layer: CALayer) -> UIImage { + UIGraphicsBeginImageContext(layer.frame.size) + layer.render(in: UIGraphicsGetCurrentContext()!) + let outputImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return outputImage! + } +} diff --git a/Bitcoin Private/Utils/Constants.swift b/Bitcoin Private/Utils/Constants.swift new file mode 100644 index 0000000..a735773 --- /dev/null +++ b/Bitcoin Private/Utils/Constants.swift @@ -0,0 +1,32 @@ +// +// Constants.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-09. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +struct Colors { + static let primaryDark = UIColor(red: 41.0/255.0, green: 45.0/255.0, blue: 95.0/255.0, alpha: Alphas.opaque) + static let primaryDarkTransparent = UIColor(red: 41.0/255.0, green: 45.0/255.0, blue: 95.0/255.0, alpha: Alphas.transparent) + static let secondaryDark = UIColor(red: 126.0/255.0, green: 158.0/255.0, blue: 209.0/255.0, alpha: Alphas.opaque) + static let secondaryDarkTransparent = UIColor(red: 126.0/255.0, green: 158.0/255.0, blue: 209.0/255.0, alpha: Alphas.transparent) + static let lightBackground = UIColor(red: 252.0/255.0, green: 252.0/255.0, blue: 252.0/255.0, alpha: Alphas.opaque) + static let darkGray = UIColor(red: 74.0/255.0, green: 74.0/255.0, blue: 74.0/255.0, alpha: Alphas.opaque) + static let darkGrayTransparent = UIColor(red: 74.0/255.0, green: 74.0/255.0, blue: 74.0/255.0, alpha: Alphas.opaqueTransparent) + static let lightGray = UIColor(red: 216.0/255.0, green: 216.0/255.0, blue: 216.0/255.0, alpha: Alphas.opaque) + static let shadowGray = UIColor.lightGray + static let black = UIColor.black + static let blackTransparent = UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: Alphas.semiTransparent) + static let white = UIColor.white + static let whiteTransparent = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: Alphas.transparent) +} + +public struct Alphas { + static let opaque = CGFloat(1) + static let opaqueTransparent = CGFloat(0.7) + static let semiTransparent = CGFloat(0.5) + static let transparent = CGFloat(0.2) +} diff --git a/Bitcoin Private/Utils/NibLoader.swift b/Bitcoin Private/Utils/NibLoader.swift new file mode 100644 index 0000000..538204a --- /dev/null +++ b/Bitcoin Private/Utils/NibLoader.swift @@ -0,0 +1,28 @@ +// +// NibLoader.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-09. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import Foundation + +struct NibLoader { + let nibName: String + + func loadView() -> T { + return loadView(owner: nil) + } + + func loadView(owner: AnyObject?) -> T { + let bundle = Bundle.main + let views = bundle.loadNibNamed(nibName, owner: owner, options: nil) + + guard let view = views?.first! as? T else { + fatalError("Incorrect view type provided") + } + + return view + } +} diff --git a/Bitcoin Private/View Controllers/LaunchViewController.swift b/Bitcoin Private/View Controllers/LaunchViewController.swift new file mode 100644 index 0000000..c7917c2 --- /dev/null +++ b/Bitcoin Private/View Controllers/LaunchViewController.swift @@ -0,0 +1,96 @@ +// +// LaunchViewController.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-09. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class LaunchViewController: UIViewController { + + @IBOutlet var activityIndicator: UIActivityIndicatorView! + @IBOutlet var createWalletButton: UIButton! + @IBOutlet var importWalletButton: UIButton! + @IBOutlet var logoImageView: UIImageView! + + @IBAction func createNewWallet() { + let mnemonicViewController = MnemonicViewController() + let navigationController = AppNavigationController(rootViewController: mnemonicViewController) + navigationController.accountCreationDelegate = self + + present(navigationController, animated: true, completion: nil) + } + + @IBAction func importWallet() { + let verificationViewController = VerificationViewController(type: .recovery, mnemonic: "") + let navigationController = AppNavigationController(rootViewController: verificationViewController) + navigationController.accountCreationDelegate = self + + present(navigationController, animated: true, completion: nil) + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + init() { + super.init(nibName: String(describing: LaunchViewController.self), bundle: nil) + } + + override func viewDidLoad() { + super.viewDidLoad() + + setupView() + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + showButtons() + } + + func setupView() { + UIApplication.shared.statusBarStyle = .default + + navigationController?.isNavigationBarHidden = true + + logoImageView.image = UIImage(named: "icon") + + createWalletButton.backgroundColor = Colors.primaryDark + createWalletButton.setTitleColor(Colors.white, for: .normal) + importWalletButton.backgroundColor = Colors.secondaryDark + importWalletButton.setTitleColor(Colors.white, for: .normal) + view.backgroundColor = Colors.lightBackground + //view.gradientLayer.colors = [Colors.primaryDark.cgColor, Colors.secondaryDark.cgColor] + //view.gradientLayer.gradient = GradientPoint.topBottom.draw() + } + + func hideButtons() { + activityIndicator.startAnimating() + createWalletButton.isHidden = true + importWalletButton.isHidden = true + } + + func showButtons() { + activityIndicator.stopAnimating() + createWalletButton.isHidden = false + importWalletButton.isHidden = false + } + + func displayWallet() { + let walletViewController = WalletViewController() + + navigationController?.pushViewController(walletViewController, animated: true) + } +} + +extension LaunchViewController: AccountCreationDelegate { + func createAccount(mnemonic: String) { + hideButtons() + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + self.displayWallet() + } + } +} diff --git a/Bitcoin Private/View Controllers/LaunchViewController.xib b/Bitcoin Private/View Controllers/LaunchViewController.xib new file mode 100644 index 0000000..7b0af39 --- /dev/null +++ b/Bitcoin Private/View Controllers/LaunchViewController.xib @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/View Controllers/ReceiveViewController.swift b/Bitcoin Private/View Controllers/ReceiveViewController.swift new file mode 100644 index 0000000..6f97785 --- /dev/null +++ b/Bitcoin Private/View Controllers/ReceiveViewController.swift @@ -0,0 +1,100 @@ +// +// ReceiveViewController.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-10. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class ReceiveViewController: UIViewController { + + @IBOutlet var activityIndicator: UIActivityIndicatorView! + @IBOutlet var addressLabel: UILabel! + @IBOutlet var addressTitleLabel: UILabel! + @IBOutlet var addressHolderView: UIView! + @IBOutlet var imageViewHolder: UIView! + @IBOutlet var imageView: UIImageView! + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + var address: String = "" + + @IBAction func copyAddress() { + if let addressText = addressLabel.text, !addressText.isEmpty { + UIPasteboard.general.string = addressLabel.text + + let alert = UIAlertController(title: "Your wallet address has been successfully copied.", message: nil, preferredStyle: UIAlertControllerStyle.alert) + alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil)) + self.present(alert, animated: true, completion: nil) + } + + } + + init(address: String) { + super.init(nibName: String(describing: ReceiveViewController.self), bundle: nil) + + self.address = address + } + + override func viewDidLoad() { + super.viewDidLoad() + + setupView() + } + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + displayGeneratedAddress(value: address) + } + + func setupView() { + navigationItem.title = "My Wallet" + + let image = UIImage(named:"close") + let leftBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(self.dismissView)) + navigationItem.leftBarButtonItem = leftBarButtonItem + + imageViewHolder.layer.shadowColor = Colors.shadowGray.cgColor + imageViewHolder.layer.shadowOpacity = Float(Alphas.transparent) + imageViewHolder.layer.shadowOffset = CGSize(width: 0.0, height: 3.0) + imageViewHolder.layer.shadowRadius = 4.0 + + addressLabel.textColor = Colors.darkGray + addressTitleLabel.textColor = Colors.darkGrayTransparent + addressHolderView.backgroundColor = Colors.lightBackground + view.backgroundColor = Colors.lightBackground + + addressLabel.text = address + } + + @objc func dismissView() { + dismiss(animated: true, completion: nil) + } + + func displayGeneratedAddress(value: String) { + let data = value.data(using: String.Encoding.isoLatin1, allowLossyConversion: false) + + let filter = CIFilter(name: "CIQRCodeGenerator") + filter?.setValue(data, forKey: "inputMessage") + filter?.setValue("H", forKey: "inputCorrectionLevel") + + let colorFilter = CIFilter(name: "CIFalseColor") + colorFilter?.setValue(filter?.outputImage, forKey: "inputImage") + colorFilter?.setValue(CIColor.init(cgColor: Colors.white.cgColor), forKey: "inputColor1") + colorFilter?.setValue(CIColor.init(cgColor: Colors.primaryDark.cgColor), forKey: "inputColor0") + + let qrcodeImage = colorFilter?.outputImage + let scaleX = imageView.frame.size.width / (qrcodeImage?.extent.size.width)! + let scaleY = imageView.frame.size.height / (qrcodeImage?.extent.size.height)! + let transformedImage = qrcodeImage?.transformed(by: CGAffineTransform(scaleX: scaleX, y: scaleY)) + + activityIndicator.stopAnimating() + + imageView.image = UIImage(ciImage: transformedImage!) + } +} diff --git a/Bitcoin Private/View Controllers/ReceiveViewController.xib b/Bitcoin Private/View Controllers/ReceiveViewController.xib new file mode 100644 index 0000000..272a224 --- /dev/null +++ b/Bitcoin Private/View Controllers/ReceiveViewController.xib @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/View Controllers/ScanViewController.swift b/Bitcoin Private/View Controllers/ScanViewController.swift new file mode 100644 index 0000000..e19e7cb --- /dev/null +++ b/Bitcoin Private/View Controllers/ScanViewController.swift @@ -0,0 +1,129 @@ +// +// ScanViewController.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-11. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import AVFoundation +import UIKit + +protocol ScanViewControllerDelegate: class { + func setQR(value: String) +} + +class ScanViewController: UIViewController { + var captureSession = AVCaptureSession() + var videoPreviewLayer: AVCaptureVideoPreviewLayer? + var qrCodeFrameView: UIView? + + weak var delegate: ScanViewControllerDelegate? + + private let supportedCodeTypes = [AVMetadataObject.ObjectType.upce, + AVMetadataObject.ObjectType.code39, + AVMetadataObject.ObjectType.code39Mod43, + AVMetadataObject.ObjectType.code93, + AVMetadataObject.ObjectType.code128, + AVMetadataObject.ObjectType.ean8, + AVMetadataObject.ObjectType.ean13, + AVMetadataObject.ObjectType.aztec, + AVMetadataObject.ObjectType.pdf417, + AVMetadataObject.ObjectType.itf14, + AVMetadataObject.ObjectType.dataMatrix, + AVMetadataObject.ObjectType.interleaved2of5, + AVMetadataObject.ObjectType.qr] + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + init() { + super.init(nibName: String(describing: ScanViewController.self), bundle: nil) + } + + override func viewDidLoad() { + super.viewDidLoad() + + setupView() + setupCamera() + } + + func setupView() { + navigationItem.title = "Scanning..." + + let image = UIImage(named:"close") + let leftBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(self.dismissView)) + navigationItem.leftBarButtonItem = leftBarButtonItem + + view.backgroundColor = Colors.primaryDark + } + + @objc func dismissView() { + captureSession.stopRunning() + videoPreviewLayer?.removeFromSuperlayer() + + dismiss(animated: true, completion: nil) + } + + func setupCamera() { + let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera, .builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back) + + guard let captureDevice = deviceDiscoverySession.devices.first else { + print("No Camera Found.") + return + } + + do { + let input = try AVCaptureDeviceInput(device: captureDevice) + captureSession.addInput(input) + + let captureMetadataOutput = AVCaptureMetadataOutput() + captureSession.addOutput(captureMetadataOutput) + captureMetadataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main) + captureMetadataOutput.metadataObjectTypes = supportedCodeTypes + } catch { + print(error) + return + } + + videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) + videoPreviewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill + videoPreviewLayer?.frame = view.layer.bounds + view.layer.addSublayer(videoPreviewLayer!) + + captureSession.startRunning() + + qrCodeFrameView = UIView() + + if let qrCodeFrameView = qrCodeFrameView { + qrCodeFrameView.layer.borderColor = Colors.primaryDark.cgColor + qrCodeFrameView.layer.borderWidth = 3.0 + view.addSubview(qrCodeFrameView) + view.bringSubview(toFront: qrCodeFrameView) + } + } +} + +extension ScanViewController: AVCaptureMetadataOutputObjectsDelegate { + func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { + if metadataObjects.count == 0 { + qrCodeFrameView?.frame = CGRect.zero + return + } + + let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject + + if supportedCodeTypes.contains(metadataObj.type) { + let barCodeObject = videoPreviewLayer?.transformedMetadataObject(for: metadataObj) + qrCodeFrameView?.frame = barCodeObject!.bounds + + if let qrValue = metadataObj.stringValue { + delegate?.setQR(value: qrValue) + + navigationItem.title = "Valid QR Code Found" + perform(#selector(self.dismissView), with: nil, afterDelay: 0.8) + } + } + } +} diff --git a/Bitcoin Private/View Controllers/ScanViewController.xib b/Bitcoin Private/View Controllers/ScanViewController.xib new file mode 100644 index 0000000..d0010ec --- /dev/null +++ b/Bitcoin Private/View Controllers/ScanViewController.xib @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/View Controllers/SendAmountViewController.swift b/Bitcoin Private/View Controllers/SendAmountViewController.swift new file mode 100644 index 0000000..fcfef13 --- /dev/null +++ b/Bitcoin Private/View Controllers/SendAmountViewController.swift @@ -0,0 +1,120 @@ +// +// SendAmountViewController.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-10. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class SendAmountViewController: UIViewController { + + @IBOutlet var activityIndicator: UIActivityIndicatorView! + @IBOutlet var amountLabel: UILabel! + @IBOutlet var currencyLabel: UILabel! + @IBOutlet var indicatorView: UIView! + @IBOutlet var indicatorTitle: UILabel! + @IBOutlet var keyboardHolderView: UIView! + @IBOutlet var keyboardPad1: UIButton! + @IBOutlet var keyboardPad2: UIButton! + @IBOutlet var keyboardPad3: UIButton! + @IBOutlet var keyboardPad4: UIButton! + @IBOutlet var keyboardPad5: UIButton! + @IBOutlet var keyboardPad6: UIButton! + @IBOutlet var keyboardPad7: UIButton! + @IBOutlet var keyboardPad8: UIButton! + @IBOutlet var keyboardPad9: UIButton! + @IBOutlet var keyboardPadDot: UIButton! + @IBOutlet var keyboardPad0: UIButton! + @IBOutlet var keyboardPadBackspace: UIButton! + @IBOutlet var sendAddressLabel: UILabel! + + var keyboardPads: [UIButton]! + var receiver: String = "" + var sendingAmount: String = "" + + @IBAction func sendPayment() { + guard let amount = amountLabel.text, !amount.isEmpty, amount != "0" else { + return + } + } + + @IBAction func keyboardTapped(sender: UIButton) { + let keyboardPad = keyboardPads[sender.tag] + if keyboardPad == keyboardPadBackspace { + if sendingAmount.count > 1 { + sendingAmount.remove(at: sendingAmount.index(before: sendingAmount.endIndex)) + } else { + sendingAmount = "" + } + } else if keyboardPad == keyboardPadDot { + if sendingAmount.count == 0 { + sendingAmount += "0." + } else if sendingAmount.range(of:".") == nil { + sendingAmount += "." + } + } else { + if sendingAmount.count == 0 && sender.tag == 0 { + sendingAmount = "" + } else { + sendingAmount += String(sender.tag) + } + } + + amountLabel.text = sendingAmount.count > 0 ? sendingAmount : "0" + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + init(reciever: String) { + super.init(nibName: String(describing: SendAmountViewController.self), bundle: nil) + + self.receiver = reciever + } + + override func viewDidLoad() { + super.viewDidLoad() + + setupView() + } + + func setupView() { + navigationItem.title = "My Wallet" + + let image = UIImage(named:"close") + let rightBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(self.dismissView)) + navigationItem.rightBarButtonItem = rightBarButtonItem + + indicatorView.isHidden = true + + activityIndicator.tintColor = Colors.darkGray + indicatorTitle.textColor = Colors.darkGray + sendAddressLabel.textColor = Colors.darkGray + amountLabel.textColor = Colors.primaryDark + currencyLabel.textColor = Colors.darkGrayTransparent + keyboardHolderView.backgroundColor = Colors.lightBackground + view.backgroundColor = Colors.primaryDark + + sendAddressLabel.text = "To: \(receiver)" + + keyboardPads = [keyboardPad0, keyboardPad1, keyboardPad2, keyboardPad3, keyboardPad4, keyboardPad5, keyboardPad6, keyboardPad7, keyboardPad8, keyboardPad9, keyboardPadDot, keyboardPadBackspace] + + for (index, keyboardPad) in keyboardPads.enumerated() { + keyboardPad.tintColor = Colors.primaryDark + keyboardPad.setTitleColor(Colors.primaryDark, for: .normal) + keyboardPad.backgroundColor = Colors.lightBackground + keyboardPad.tag = index + } + } + + @objc func dismissView() { + view.endEditing(true) + + dismiss(animated: true, completion: nil) + } +} + + diff --git a/Bitcoin Private/View Controllers/SendAmountViewController.xib b/Bitcoin Private/View Controllers/SendAmountViewController.xib new file mode 100644 index 0000000..d8db5db --- /dev/null +++ b/Bitcoin Private/View Controllers/SendAmountViewController.xib @@ -0,0 +1,361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/View Controllers/SendViewController.swift b/Bitcoin Private/View Controllers/SendViewController.swift new file mode 100644 index 0000000..983e89c --- /dev/null +++ b/Bitcoin Private/View Controllers/SendViewController.swift @@ -0,0 +1,125 @@ +// +// SendViewController.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-10. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class SendViewController: UIViewController { + + @IBOutlet var addressHolderView: UIView! + @IBOutlet var balanceLabel: UILabel! + @IBOutlet var bottomLayoutConstraint: NSLayoutConstraint! + @IBOutlet var holdingView: UIView! + @IBOutlet var sendTitleLabel: UILabel! + @IBOutlet var sendAddressTextField: UITextField! + + var safeAreaPadding: CGFloat = 20.0 + + @IBAction func addAmount() { + guard let receiver = sendAddressTextField.text, !receiver.isEmpty else { + return + } + + let sendAmountViewController = SendAmountViewController(reciever: receiver) + + navigationController?.pushViewController(sendAmountViewController, animated: true) + } + + @IBAction func scanQRCode() { + let scanViewController = ScanViewController() + scanViewController.delegate = self + let navigationController = AppNavigationController(rootViewController: scanViewController) + + present(navigationController, animated: true, completion: nil) + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + init() { + super.init(nibName: String(describing: SendViewController.self), bundle: nil) + } + + override func viewDidLoad() { + super.viewDidLoad() + + setupView() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + addKeyboardNotifications() + } + override func viewWillDisappear(_ animated: Bool) { + viewDidDisappear(animated) + + removeKeyboardNotifications() + } + + func setupView() { + navigationItem.title = "My Wallet" + navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) + + let image = UIImage(named:"close") + let leftBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(self.dismissView)) + navigationItem.leftBarButtonItem = leftBarButtonItem + + balanceLabel.textColor = Colors.black + sendTitleLabel.textColor = Colors.darkGrayTransparent + sendAddressTextField.textColor = Colors.darkGray + addressHolderView.backgroundColor = Colors.lightBackground + holdingView.backgroundColor = Colors.lightBackground + view.backgroundColor = Colors.primaryDark + } + + func addKeyboardNotifications() { + NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil) + } + + @objc func keyboardWillShow(notification: NSNotification) { + if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue { + let statusBarHeight = UIApplication.shared.statusBarFrame.height - safeAreaPadding + bottomLayoutConstraint.constant = keyboardSize.size.height + statusBarHeight + + if let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double { + UIView.animate(withDuration: duration, animations: { + self.view.layoutIfNeeded() + }) + } + } + } + + @objc func keyboardWillHide(notification: NSNotification) { + bottomLayoutConstraint.constant = 0 + + if let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double { + UIView.animate(withDuration: duration, animations: { + self.view.layoutIfNeeded() + }) + } + } + + func removeKeyboardNotifications() { + NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil) + NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil) + } + + @objc func dismissView() { + view.endEditing(true) + + dismiss(animated: true, completion: nil) + } +} + +extension SendViewController: ScanViewControllerDelegate { + func setQR(value: String) { + sendAddressTextField.text = value + } +} diff --git a/Bitcoin Private/View Controllers/SendViewController.xib b/Bitcoin Private/View Controllers/SendViewController.xib new file mode 100644 index 0000000..4d22edd --- /dev/null +++ b/Bitcoin Private/View Controllers/SendViewController.xib @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/View Controllers/Wallet Creation and Restoration/MnemonicViewController.swift b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/MnemonicViewController.swift new file mode 100644 index 0000000..ef63d8c --- /dev/null +++ b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/MnemonicViewController.swift @@ -0,0 +1,94 @@ +// +// MnemonicViewController.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-09. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class MnemonicViewController: UIViewController { + + @IBOutlet var holderView: UIView! + @IBOutlet var titleLabel: UILabel! + @IBOutlet var mnemonicHolderView: UIView! + @IBOutlet var activityIndicator: UIActivityIndicatorView! + + var mnemonic = "" + + @IBAction func confirmPhrase() { + let verificationViewController = VerificationViewController(type: .questions, mnemonic: mnemonic) + + navigationController?.pushViewController(verificationViewController, animated: true) + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + init() { + super.init(nibName: String(describing: MnemonicViewController.self), bundle: nil) + } + + override func viewDidLoad() { + super.viewDidLoad() + + setupView() + generateMnemonic() + } + + func setupView() { + navigationItem.title = "Secret Phrase" + + navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) + + let image = UIImage(named:"close") + let leftBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(self.dismissView)) + navigationItem.leftBarButtonItem = leftBarButtonItem + + holderView.backgroundColor = Colors.lightBackground + titleLabel.textColor = Colors.darkGray + view.backgroundColor = Colors.primaryDark + } + + @objc func dismissView() { + view.endEditing(true) + + dismiss(animated: true, completion: nil) + } + + func generateMnemonic() { + activityIndicator.stopAnimating() + + mnemonic = "bench hurt jump file august wise shallow faculty impulse spring exact slush thunder author capable act festival slice deposit sauce coconut afford frown better" + + let words = mnemonic.components(separatedBy: " ") + + var originX: CGFloat = 0.0 + var originY: CGFloat = 0.0 + + for (index, word) in words.enumerated() { + let pillView = PillView(index: String(index + 1), title: word, origin: .zero) + + if index == 0 { + mnemonicHolderView.addSubview(pillView) + + originX += pillView.frame.size.width + } else { + if originX + pillView.frame.size.width > mnemonicHolderView.frame.size.width - pillView.horizontalSpacing { + originY += pillView.verticalSpacing + originX = 0.0 + } else { + originX += pillView.horizontalSpacing + } + + pillView.frame.origin = CGPoint(x: originX, y: originY) + + mnemonicHolderView.addSubview(pillView) + + originX += pillView.frame.size.width + } + } + } +} diff --git a/Bitcoin Private/View Controllers/Wallet Creation and Restoration/MnemonicViewController.xib b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/MnemonicViewController.xib new file mode 100644 index 0000000..a521692 --- /dev/null +++ b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/MnemonicViewController.xib @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/View Controllers/Wallet Creation and Restoration/PinViewController.swift b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/PinViewController.swift new file mode 100644 index 0000000..0fb0537 --- /dev/null +++ b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/PinViewController.swift @@ -0,0 +1,141 @@ +// +// PinViewController.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-09. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit +import Foundation + +class PinViewController: UIViewController { + + @IBOutlet var textField: UITextField! + @IBOutlet var nextButton: AppButton! + @IBOutlet var buttonHolderView: UIView! + @IBOutlet var pinViewHolder: UIView! + @IBOutlet var pinView1: PinView! + @IBOutlet var pinView2: PinView! + @IBOutlet var pinView3: PinView! + @IBOutlet var pinView4: PinView! + + var pinViews: [PinView]! + var previousPin: String! + var mnemonic = "" + + @IBAction func textFieldDidChange() { + guard let digits = textField.text, digits.count < 5 else { + if let text = textField.text { + let index4 = text.index(text.startIndex, offsetBy: 4) + + textField.text = String(text[.. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/View Controllers/Wallet Creation and Restoration/VerificationViewController.swift b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/VerificationViewController.swift new file mode 100644 index 0000000..5696593 --- /dev/null +++ b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/VerificationViewController.swift @@ -0,0 +1,270 @@ +// +// RecoveryViewController.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-11. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class VerificationViewController: UIViewController { + + @IBOutlet var collectionView: UICollectionView! + @IBOutlet var textView: UITextView! + @IBOutlet var textViewHeightConstraint: NSLayoutConstraint! + @IBOutlet var progressView: UIView! + @IBOutlet var progressViewWidthConstraint: NSLayoutConstraint! + @IBOutlet var quicktypeView: UIView! + @IBOutlet var questionHolderView: UIView! + @IBOutlet var questionTitleLabel: UILabel! + @IBOutlet var questionSubtitleLabel: UILabel! + @IBOutlet var questionViewHeightConstraint: NSLayoutConstraint! + + public enum VerificationType { + case recovery + case confirmation + case questions + } + + let defaultQuestionViewHeight: CGFloat = 88.0 + let defaultTextViewHeight: CGFloat = 150.0 + let questionTextViewHeight: CGFloat = 48.0 + let totalQuestionCount = 4 + var questionsAnswered = 0 + var progressWidth: CGFloat { + return UIScreen.main.bounds.size.width / CGFloat(totalQuestionCount) + } + + var type: VerificationType = .recovery + var suggestions: [String] = [] + var questionWords: [String] = [] + var currentWord: String = "" + var mnemonic: String = "" + + let wordList = ["bench", "hurt", "jump", "file", "august", "wise", "shallow", "faculty", "impulse", "spring", "exact", "slush", "thunder", "author", "capable", "act", "festival", "slice", "deposit", "sauce", "coconut", "afford", "frown", "better"] + + @IBAction func nextButtonSelected() { + switch type { + case .questions: + validateAnswer() + default: + // TODO: uncomment to add verification back + /* + guard var mnemonicString = textView.text, !mnemonicString.isEmpty else { + return + } + + let lastCharater = mnemonicString.last + if lastCharater == " " { + mnemonicString = String(mnemonicString.dropLast()) + } + setPin(mnemonic: mnemonicString) + */ + + //TODO remove this when verification above is added. + setPin(mnemonic: mnemonic) + } + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + init(type: VerificationType, mnemonic: String) { + super.init(nibName: String(describing: VerificationViewController.self), bundle: nil) + + self.type = type + self.mnemonic = mnemonic + } + + override func viewDidLoad() { + super.viewDidLoad() + + setupView() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + textView.becomeFirstResponder() + } + + func setupView() { + let collectionViewNib = UINib(nibName: WordSuggestionCell.cellIdentifier, bundle: nil) + collectionView.register(collectionViewNib, forCellWithReuseIdentifier: WordSuggestionCell.cellIdentifier) + + switch type { + case .confirmation: + navigationItem.title = "Re-enter Your Phrase" + + questionViewHeightConstraint.constant = 0.0 + textViewHeightConstraint.constant = defaultTextViewHeight + case .questions: + questionViewHeightConstraint.constant = defaultQuestionViewHeight + textViewHeightConstraint.constant = questionTextViewHeight + + setQuestion(animated: false) + default: + navigationItem.title = "Enter Recovery Phrase" + + questionViewHeightConstraint.constant = 0.0 + textViewHeightConstraint.constant = defaultTextViewHeight + + let image = UIImage(named:"close") + let leftBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(self.dismissView)) + navigationItem.leftBarButtonItem = leftBarButtonItem + } + + textView.textContainerInset = UIEdgeInsets(top: 16.0, left: 16.0, bottom: 16.0, right: 16.0); + textView.inputAccessoryView = quicktypeView + + progressView.backgroundColor = Colors.secondaryDark + textView.textColor = Colors.darkGray + questionHolderView.backgroundColor = Colors.lightBackground + questionTitleLabel.textColor = Colors.darkGray + questionSubtitleLabel.textColor = Colors.darkGray + view.backgroundColor = Colors.lightBackground + } + + @objc func dismissView() { + view.endEditing(true) + + dismiss(animated: true, completion: nil) + } + + func getWords(string: String) -> [String] { + let components = string.components(separatedBy: .whitespacesAndNewlines) + + return components.filter { !$0.isEmpty } + } + + func clearSuggestions(reload: Bool) { + suggestions.removeAll() + + if reload { + collectionView.reloadData() + } + } + + func getAutocompleteSuggestions(userText: String) -> [String] { + var possibleMatches: [String] = [] + for item in wordList { + let myString:NSString! = item as NSString + let substringRange :NSRange! = myString.range(of: userText) + + if (substringRange.location == 0) { + possibleMatches.append(item) + } + } + return possibleMatches.enumerated().flatMap{ $0.offset < 3 ? $0.element : nil } + } + + func validateAnswer() { + if textView.text == currentWord { + if questionsAnswered == 4 { + setPin(mnemonic: mnemonic) + } else { + textView.text = "" + setQuestion(animated: true) + } + } else { + textView.textColor = UIColor.red + textView.shake() + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) { + self.textView.text = "" + self.textView.textColor = Colors.darkGray + } + } + } + + func setQuestion(animated: Bool) { + if questionWords.count == 0 { + questionWords = mnemonic.components(separatedBy: " ") + } + + let randomIndex = Int(arc4random_uniform(UInt32(questionWords.count))) + currentWord = questionWords[randomIndex] + + if let indexOfWord = mnemonic.components(separatedBy: " ").index(of: currentWord) { + questionTitleLabel.text = "What was the word \(String(describing: indexOfWord + 1))?" + questionWords.remove(at: randomIndex) + questionsAnswered += 1 + + setProgress(animated: animated) + } + } + + func setProgress(animated: Bool) { + progressViewWidthConstraint.constant += progressWidth + + navigationItem.title = "Question \(questionsAnswered) of \(totalQuestionCount)" + + if animated { + UIView.animate(withDuration: 0.3) { + self.view.layoutIfNeeded() + } + } + } + + func setPin(mnemonic: String) { + let pinViewController = PinViewController(pin: nil, mnemonic: mnemonic) + + navigationController?.pushViewController(pinViewController, animated: true) + } +} + +extension VerificationViewController: UITextViewDelegate { + func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { + clearSuggestions(reload: false) + + let subString = (textView.text! as NSString).replacingCharacters(in: range, with: text) + + if let lastWord = getWords(string: String(subString)).last { + suggestions.append(contentsOf: getAutocompleteSuggestions(userText: lastWord)) + } + + collectionView.reloadData() + + return true + } +} + +extension VerificationViewController: UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return suggestions.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WordSuggestionCell.cellIdentifier, for: indexPath) as! WordSuggestionCell + cell.titleLabel.text = suggestions[indexPath.row] + return cell + } +} + +extension VerificationViewController: UICollectionViewDelegate { + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + let suggestion = suggestions[indexPath.row] + var words = getWords(string: textView.text) + if words.count > 0 { + words.removeLast() + } + words.append(suggestion) + + textView.text = words.joined(separator: " ") + + if type != .questions { + textView.text.append(" ") + } + + clearSuggestions(reload: true) + } +} + +extension VerificationViewController: UICollectionViewDelegateFlowLayout { + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + return CGSize(width: UIScreen.main.bounds.size.width / 3, height: collectionView.frame.size.height) + } +} + diff --git a/Bitcoin Private/View Controllers/Wallet Creation and Restoration/VerificationViewController.xib b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/VerificationViewController.xib new file mode 100644 index 0000000..adf6c4a --- /dev/null +++ b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/VerificationViewController.xib @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/View Controllers/Wallet Creation and Restoration/WalletTitleViewController.swift b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/WalletTitleViewController.swift new file mode 100644 index 0000000..707ac0a --- /dev/null +++ b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/WalletTitleViewController.swift @@ -0,0 +1,54 @@ +// +// WalletTitleViewController.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-09. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class WalletTitleViewController: UIViewController { + + @IBOutlet var textField: UITextField! + @IBOutlet var underlineView: UIView! + + @IBAction func saveTitle() { + dismissView() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + init() { + super.init(nibName: String(describing: WalletTitleViewController.self), bundle: nil) + } + + override func viewDidLoad() { + super.viewDidLoad() + + setupView() + } + + func setupView() { + navigationItem.title = "New Wallet" + + let image = UIImage(named:"close") + let leftBarButtonItem = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(self.dismissView)) + navigationItem.leftBarButtonItem = leftBarButtonItem + + textField.textColor = Colors.primaryDark + textField.text = "My Wallet" + view.backgroundColor = Colors.lightBackground + + underlineView.backgroundColor = Colors.primaryDark + underlineView.alpha = Alphas.transparent + } + + @objc func dismissView() { + view.endEditing(true) + + dismiss(animated: true, completion: nil) + } +} diff --git a/Bitcoin Private/View Controllers/Wallet Creation and Restoration/WalletTitleViewController.xib b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/WalletTitleViewController.xib new file mode 100644 index 0000000..472b047 --- /dev/null +++ b/Bitcoin Private/View Controllers/Wallet Creation and Restoration/WalletTitleViewController.xib @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/View Controllers/WalletViewController.swift b/Bitcoin Private/View Controllers/WalletViewController.swift new file mode 100644 index 0000000..7151101 --- /dev/null +++ b/Bitcoin Private/View Controllers/WalletViewController.swift @@ -0,0 +1,130 @@ +// +// WalletViewController.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-09. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class WalletViewController: UIViewController { + + @IBOutlet var activityIndicator: UIActivityIndicatorView! + @IBOutlet var collectionView: UICollectionView! + @IBOutlet var pageControl: UIPageControl! + @IBOutlet var tableView: UITableView! + @IBOutlet var tableViewHeader: UIView! + @IBOutlet var tableViewHeaderLeftLabel: UILabel! + @IBOutlet var tableViewHeaderRightLabel: UILabel! + @IBOutlet var logoImageView: UIImageView! + + @IBAction func receiveFunds() { + let receiveViewController = ReceiveViewController(address: "b1RXUJgnuxtzHyJ5UTWerh4pNBWcVikESZe") + let navigationController = AppNavigationController(rootViewController: receiveViewController) + + present(navigationController, animated: true, completion: nil) + } + + @IBAction func sendFunds() { + let sendViewController = SendViewController() + let navigationController = AppNavigationController(rootViewController: sendViewController) + + present(navigationController, animated: true, completion: nil) + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + init() { + super.init(nibName: String(describing: WalletViewController.self), bundle: nil) + } + + override func viewDidLoad() { + super.viewDidLoad() + + setupView() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + navigationItem.setHidesBackButton(true, animated: false) + navigationController?.setNavigationBarHidden(false, animated: true) + } + + func setupView() { + let collectionViewNib = UINib(nibName: WalletCell.cellIdentifier, bundle: nil) + collectionView.register(collectionViewNib, forCellWithReuseIdentifier: WalletCell.cellIdentifier) + + let tableViewNib = UINib(nibName: TransactionHistoryCell.cellIdentifier, bundle: nil) + tableView.register(tableViewNib, forCellReuseIdentifier: TransactionHistoryCell.cellIdentifier) + + navigationItem.titleView = logoImageView + + tableViewHeaderLeftLabel.textColor = Colors.darkGrayTransparent + tableViewHeaderRightLabel.textColor = Colors.darkGrayTransparent + pageControl.currentPageIndicatorTintColor = Colors.primaryDark + pageControl.pageIndicatorTintColor = Colors.primaryDarkTransparent + tableView.backgroundColor = Colors.lightBackground + view.backgroundColor = Colors.primaryDark + } +} + +extension WalletViewController: UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return 2 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WalletCell.cellIdentifier, for: indexPath) as! WalletCell + + return cell + } +} + +extension WalletViewController: UICollectionViewDelegateFlowLayout { + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + return CGSize(width: UIScreen.main.bounds.size.width, height: collectionView.frame.size.height) + } +} + +extension WalletViewController: UITableViewDataSource { + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 10 + } + + func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + return tableViewHeader + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return tableViewHeader.frame.size.height + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: TransactionHistoryCell.cellIdentifier, for: indexPath) as! TransactionHistoryCell + + return cell + } +} + +extension WalletViewController: UITableViewDelegate { + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return TransactionHistoryCell.rowHeight + } +} + +extension WalletViewController: UIScrollViewDelegate { + func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { + if scrollView == collectionView { + pageControl.currentPage = Int(scrollView.contentOffset.x) / Int(scrollView.frame.width) + } + } +} + + diff --git a/Bitcoin Private/View Controllers/WalletViewController.xib b/Bitcoin Private/View Controllers/WalletViewController.xib new file mode 100644 index 0000000..ad6c9a4 --- /dev/null +++ b/Bitcoin Private/View Controllers/WalletViewController.xib @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/Views/AppButton.swift b/Bitcoin Private/Views/AppButton.swift new file mode 100644 index 0000000..984a79c --- /dev/null +++ b/Bitcoin Private/Views/AppButton.swift @@ -0,0 +1,36 @@ +// +// NextButton.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-09. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class AppButton: UIButton { + override init(frame: CGRect) { + super.init(frame: frame) + setupView() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setupView() + } + + private func setupView() { + backgroundColor = Colors.primaryDark + setTitleColor(Colors.white, for: .normal) + } + + public func setEnabled() { + isEnabled = true + alpha = Alphas.opaque + } + + public func setDisabled() { + isEnabled = false + alpha = Alphas.transparent + } +} diff --git a/Bitcoin Private/Views/Cells/TransactionHistoryCell.swift b/Bitcoin Private/Views/Cells/TransactionHistoryCell.swift new file mode 100644 index 0000000..f06acfd --- /dev/null +++ b/Bitcoin Private/Views/Cells/TransactionHistoryCell.swift @@ -0,0 +1,27 @@ +// +// TransactionHistoryCell.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-10. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class TransactionHistoryCell: UITableViewCell { + @IBOutlet var activityLabel: UILabel! + @IBOutlet var amountLabel: UILabel! + @IBOutlet var dateLabel: UILabel! + + static let cellIdentifier = "TransactionHistoryCell" + static let rowHeight: CGFloat = 80.0 + + override func awakeFromNib() { + super.awakeFromNib() + + activityLabel.textColor = Colors.black + amountLabel.textColor = Colors.black + dateLabel.textColor = Colors.blackTransparent + } + +} diff --git a/Bitcoin Private/Views/Cells/TransactionHistoryCell.xib b/Bitcoin Private/Views/Cells/TransactionHistoryCell.xib new file mode 100644 index 0000000..225bf22 --- /dev/null +++ b/Bitcoin Private/Views/Cells/TransactionHistoryCell.xib @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/Views/Cells/WalletCell.swift b/Bitcoin Private/Views/Cells/WalletCell.swift new file mode 100644 index 0000000..ab648cb --- /dev/null +++ b/Bitcoin Private/Views/Cells/WalletCell.swift @@ -0,0 +1,29 @@ +// +// WalletCollectionViewCell.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-10. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class WalletCell: UICollectionViewCell { + + @IBOutlet var holdingView: UIView! + @IBOutlet var titleLabel: UILabel! + @IBOutlet var currencyLabel: UILabel! + @IBOutlet var amountLabel: UILabel! + @IBOutlet var convertedCurrencyLabel: UILabel! + + static let cellIdentifier = "WalletCell" + + override func awakeFromNib() { + super.awakeFromNib() + + titleLabel.textColor = Colors.darkGray + currencyLabel.textColor = Colors.primaryDark + amountLabel.textColor = Colors.darkGray + convertedCurrencyLabel.textColor = Colors.darkGrayTransparent + } +} diff --git a/Bitcoin Private/Views/Cells/WalletCell.xib b/Bitcoin Private/Views/Cells/WalletCell.xib new file mode 100644 index 0000000..d4f7586 --- /dev/null +++ b/Bitcoin Private/Views/Cells/WalletCell.xib @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/Views/Cells/WordSuggestionCell.swift b/Bitcoin Private/Views/Cells/WordSuggestionCell.swift new file mode 100644 index 0000000..cca4559 --- /dev/null +++ b/Bitcoin Private/Views/Cells/WordSuggestionCell.swift @@ -0,0 +1,29 @@ +// +// WordSuggestionCell.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-12. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class WordSuggestionCell: UICollectionViewCell { + + @IBOutlet var titleLabel: UILabel! + + static let cellIdentifier = "WordSuggestionCell" + + override func awakeFromNib() { + super.awakeFromNib() + + titleLabel.textColor = Colors.white + } + + override var isHighlighted: Bool { + didSet { + contentView.backgroundColor = isHighlighted ? Colors.lightGray : nil + titleLabel.textColor = isHighlighted ? Colors.darkGray: Colors.white + } + } +} diff --git a/Bitcoin Private/Views/Cells/WordSuggestionCell.xib b/Bitcoin Private/Views/Cells/WordSuggestionCell.xib new file mode 100644 index 0000000..0d89308 --- /dev/null +++ b/Bitcoin Private/Views/Cells/WordSuggestionCell.xib @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin Private/Views/PillView.swift b/Bitcoin Private/Views/PillView.swift new file mode 100644 index 0000000..59321ff --- /dev/null +++ b/Bitcoin Private/Views/PillView.swift @@ -0,0 +1,54 @@ +// +// PillView.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-09. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class PillView: UIView { + let viewHeight: CGFloat = 30.0 + let indexWidth: CGFloat = 13.0 + let indexPadding: CGFloat = 4.0 + let viewPadding: CGFloat = 10.0 + let verticalSpacing: CGFloat = 42.0 + let horizontalSpacing: CGFloat = 8.0 + + init(index: String, title: String, origin: CGPoint) { + super.init(frame: CGRect(origin: origin, size: CGSize(width: 0.0, height: viewHeight))) + + setupView(index: index, title: title) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func setupView(index: String, title: String) { + let indexLabel = UILabel(frame: CGRect(x: viewPadding, y: 0.0, width: indexWidth, height: viewHeight)) + indexLabel.text = index + indexLabel.textColor = Colors.lightGray + indexLabel.font = UIFont.systemFont(ofSize: 10, weight: .medium) + indexLabel.textAlignment = .left + + addSubview(indexLabel) + + let titleLabel = UILabel(frame: CGRect(x: (viewPadding + indexWidth + indexPadding), y: 0.0, width: 0, height: viewHeight)) + titleLabel.text = title + titleLabel.textColor = Colors.darkGray + titleLabel.font = UIFont.systemFont(ofSize: 14, weight: .medium) + titleLabel.textAlignment = .left + let size = titleLabel.text?.size(withAttributes: [.font: titleLabel.font]) ?? .zero + titleLabel.frame.size.width = size.width + + addSubview(titleLabel) + + frame.size.width = size.width + (viewPadding * 2) + indexWidth + indexPadding + backgroundColor = Colors.white + layer.borderColor = Colors.lightGray.cgColor + layer.borderWidth = 1.0 + layer.cornerRadius = 16.0 + } +} diff --git a/Bitcoin Private/Views/PinView.swift b/Bitcoin Private/Views/PinView.swift new file mode 100644 index 0000000..268b2fb --- /dev/null +++ b/Bitcoin Private/Views/PinView.swift @@ -0,0 +1,51 @@ +// +// PinView.swift +// BlockEQ +// +// Created by Satraj Bambra on 2018-03-09. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import UIKit + +class PinView: UIView { + @IBOutlet weak var dotView: UIView! + @IBOutlet weak var underlineView: UIView! + @IBOutlet weak var view: UIView! + + fileprivate static let nibName = "PinView" + + init(frame: CGRect, title: String) { + super.init(frame: frame) + + setupView() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + setupView() + } + + private func setupView() { + view = NibLoader(nibName: PinView.nibName).loadView(owner: self) + view.frame = CGRect(origin: .zero, size: frame.size) + view.autoresizingMask = UIViewAutoresizing.flexibleWidth + view.backgroundColor = Colors.lightBackground + + addSubview(view) + } + + public func setEmpty() { + dotView.isHidden = true + + underlineView.backgroundColor = Colors.primaryDarkTransparent + } + + public func setFilled() { + dotView.backgroundColor = Colors.primaryDark + dotView.isHidden = false + + underlineView.backgroundColor = Colors.primaryDark + } +} diff --git a/Bitcoin Private/Views/PinView.xib b/Bitcoin Private/Views/PinView.xib new file mode 100644 index 0000000..f605050 --- /dev/null +++ b/Bitcoin Private/Views/PinView.xib @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Bitcoin PrivateTests/Bitcoin_PrivateTests.swift b/Bitcoin PrivateTests/Bitcoin_PrivateTests.swift new file mode 100644 index 0000000..2f47caa --- /dev/null +++ b/Bitcoin PrivateTests/Bitcoin_PrivateTests.swift @@ -0,0 +1,36 @@ +// +// Bitcoin_PrivateTests.swift +// Bitcoin PrivateTests +// +// Created by Satraj Bambra on 2018-03-15. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import XCTest +@testable import Bitcoin_Private + +class Bitcoin_PrivateTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // 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/Bitcoin PrivateTests/Info.plist b/Bitcoin PrivateTests/Info.plist new file mode 100644 index 0000000..6c40a6c --- /dev/null +++ b/Bitcoin PrivateTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Bitcoin PrivateUITests/Bitcoin_PrivateUITests.swift b/Bitcoin PrivateUITests/Bitcoin_PrivateUITests.swift new file mode 100644 index 0000000..e438303 --- /dev/null +++ b/Bitcoin PrivateUITests/Bitcoin_PrivateUITests.swift @@ -0,0 +1,36 @@ +// +// Bitcoin_PrivateUITests.swift +// Bitcoin PrivateUITests +// +// Created by Satraj Bambra on 2018-03-15. +// Copyright © 2018 Satraj Bambra. All rights reserved. +// + +import XCTest + +class Bitcoin_PrivateUITests: XCTestCase { + + override func setUp() { + super.setUp() + + // 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 + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // 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 tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + +} diff --git a/Bitcoin PrivateUITests/Info.plist b/Bitcoin PrivateUITests/Info.plist new file mode 100644 index 0000000..6c40a6c --- /dev/null +++ b/Bitcoin PrivateUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..26f7d75 --- /dev/null +++ b/Podfile @@ -0,0 +1,20 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +target 'Bitcoin Private' do + # Comment the next line if you're not using Swift and don't want to use dynamic frameworks + use_frameworks! + + # Pods for Bitcoin Private + + target 'Bitcoin PrivateTests' do + inherit! :search_paths + # Pods for testing + end + + target 'Bitcoin PrivateUITests' do + inherit! :search_paths + # Pods for testing + end + +end