diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 3630866ec..90aa0e0a4 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -70,14 +70,6 @@ A54195A12934BFEF0035AD19 /* EIP191VerifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A541959D2934BFEF0035AD19 /* EIP191VerifierTests.swift */; }; A54195A52934E83F0035AD19 /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = A54195A42934E83F0035AD19 /* Web3 */; }; A5434023291E6A270068F706 /* SolanaSwift in Frameworks */ = {isa = PBXBuildFile; productRef = A5434022291E6A270068F706 /* SolanaSwift */; }; - A55CAAB028B92AFF00844382 /* ScanModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55CAAAB28B92AFF00844382 /* ScanModule.swift */; }; - A55CAAB128B92AFF00844382 /* ScanPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55CAAAC28B92AFF00844382 /* ScanPresenter.swift */; }; - A55CAAB228B92AFF00844382 /* ScanRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55CAAAD28B92AFF00844382 /* ScanRouter.swift */; }; - A55CAAB328B92AFF00844382 /* ScanInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55CAAAE28B92AFF00844382 /* ScanInteractor.swift */; }; - A55CAAB428B92AFF00844382 /* ScanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55CAAAF28B92AFF00844382 /* ScanView.swift */; }; - A55CAAB928B92B4600844382 /* ScanQRView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55CAAB628B92B4600844382 /* ScanQRView.swift */; }; - A55CAABA28B92B4600844382 /* ScanTargetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55CAAB728B92B4600844382 /* ScanTargetView.swift */; }; - A55CAABB28B92B4600844382 /* ScanQR.swift in Sources */ = {isa = PBXBuildFile; fileRef = A55CAAB828B92B4600844382 /* ScanQR.swift */; }; A5629AA92876A23100094373 /* ChatService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AA82876A23100094373 /* ChatService.swift */; }; A5629ABD2876CBC000094373 /* ChatListModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AB82876CBC000094373 /* ChatListModule.swift */; }; A5629ABE2876CBC000094373 /* ChatListPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AB92876CBC000094373 /* ChatListPresenter.swift */; }; @@ -132,16 +124,6 @@ A58E7D452872EE570082D443 /* ContentMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58E7D442872EE570082D443 /* ContentMessageView.swift */; }; A58E7D482872EF610082D443 /* MessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58E7D472872EF610082D443 /* MessageViewModel.swift */; }; A59CF4F6292F83D50031A42F /* DefaultSignerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */; }; - A59EBEF828B54A2A003EDAAF /* AuthRequestModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59EBEF328B54A2A003EDAAF /* AuthRequestModule.swift */; }; - A59EBEF928B54A2A003EDAAF /* AuthRequestPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59EBEF428B54A2A003EDAAF /* AuthRequestPresenter.swift */; }; - A59EBEFA28B54A2A003EDAAF /* AuthRequestRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59EBEF528B54A2A003EDAAF /* AuthRequestRouter.swift */; }; - A59EBEFB28B54A2A003EDAAF /* AuthRequestInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59EBEF628B54A2A003EDAAF /* AuthRequestInteractor.swift */; }; - A59EBEFC28B54A2A003EDAAF /* AuthRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59EBEF728B54A2A003EDAAF /* AuthRequestView.swift */; }; - A59F876F28B53EA000A9CD80 /* WalletModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59F876A28B53EA000A9CD80 /* WalletModule.swift */; }; - A59F877028B53EA000A9CD80 /* WalletPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59F876B28B53EA000A9CD80 /* WalletPresenter.swift */; }; - A59F877128B53EA000A9CD80 /* WalletRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59F876C28B53EA000A9CD80 /* WalletRouter.swift */; }; - A59F877228B53EA000A9CD80 /* WalletInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59F876D28B53EA000A9CD80 /* WalletInteractor.swift */; }; - A59F877328B53EA000A9CD80 /* WalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59F876E28B53EA000A9CD80 /* WalletView.swift */; }; A59F877628B5462900A9CD80 /* WalletConnectAuth in Frameworks */ = {isa = PBXBuildFile; productRef = A59F877528B5462900A9CD80 /* WalletConnectAuth */; }; A59FAEC928B7B93A002BB66F /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = A59FAEC828B7B93A002BB66F /* Web3 */; }; A5A4FC56283CBB7800BBEC1E /* SessionDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A4FC55283CBB7800BBEC1E /* SessionDetailView.swift */; }; @@ -197,7 +179,73 @@ A5E22D222840C8D300E36487 /* WalletEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D212840C8D300E36487 /* WalletEngine.swift */; }; A5E22D242840C8DB00E36487 /* SafariEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D232840C8DB00E36487 /* SafariEngine.swift */; }; A5E22D2C2840EAC300E36487 /* XCUIElement.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D2B2840EAC300E36487 /* XCUIElement.swift */; }; + C5133A78294125CC00A8314C /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = C5133A77294125CC00A8314C /* Web3 */; }; + C53AA4362941251C008EA57C /* DefaultSignerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */; }; + C55D347F295DD7140004314A /* AuthRequestModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D347A295DD7140004314A /* AuthRequestModule.swift */; }; + C55D3480295DD7140004314A /* AuthRequestPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D347B295DD7140004314A /* AuthRequestPresenter.swift */; }; + C55D3481295DD7140004314A /* AuthRequestRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D347C295DD7140004314A /* AuthRequestRouter.swift */; }; + C55D3482295DD7140004314A /* AuthRequestInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D347D295DD7140004314A /* AuthRequestInteractor.swift */; }; + C55D3483295DD7140004314A /* AuthRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D347E295DD7140004314A /* AuthRequestView.swift */; }; + C55D3489295DD8CA0004314A /* PasteUriModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D3484295DD8CA0004314A /* PasteUriModule.swift */; }; + C55D348A295DD8CA0004314A /* PasteUriPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D3485295DD8CA0004314A /* PasteUriPresenter.swift */; }; + C55D348B295DD8CA0004314A /* PasteUriRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D3486295DD8CA0004314A /* PasteUriRouter.swift */; }; + C55D348C295DD8CA0004314A /* PasteUriInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D3487295DD8CA0004314A /* PasteUriInteractor.swift */; }; + C55D348D295DD8CA0004314A /* PasteUriView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D3488295DD8CA0004314A /* PasteUriView.swift */; }; + C55D3493295DFA750004314A /* WelcomeModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D348E295DFA750004314A /* WelcomeModule.swift */; }; + C55D3494295DFA750004314A /* WelcomePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D348F295DFA750004314A /* WelcomePresenter.swift */; }; + C55D3495295DFA750004314A /* WelcomeRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D3490295DFA750004314A /* WelcomeRouter.swift */; }; + C55D3496295DFA750004314A /* WelcomeInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D3491295DFA750004314A /* WelcomeInteractor.swift */; }; + C55D3497295DFA750004314A /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D3492295DFA750004314A /* WelcomeView.swift */; }; + C55D349929630D440004314A /* Web3Wallet in Frameworks */ = {isa = PBXBuildFile; productRef = C55D349829630D440004314A /* Web3Wallet */; }; + C55D349B2965BC2F0004314A /* TagsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D349A2965BC2F0004314A /* TagsView.swift */; }; + C55D349D2965F8D40004314A /* Proposal.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D349C2965F8D30004314A /* Proposal.swift */; }; + C55D34AE2965FB750004314A /* SessionRequestModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D34A92965FB750004314A /* SessionRequestModule.swift */; }; + C55D34AF2965FB750004314A /* SessionRequestPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D34AA2965FB750004314A /* SessionRequestPresenter.swift */; }; + C55D34B02965FB750004314A /* SessionRequestRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D34AB2965FB750004314A /* SessionRequestRouter.swift */; }; + C55D34B12965FB750004314A /* SessionRequestInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D34AC2965FB750004314A /* SessionRequestInteractor.swift */; }; + C55D34B22965FB750004314A /* SessionRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D34AD2965FB750004314A /* SessionRequestView.swift */; }; + C56EE222293F55EE004840D1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C56EE221293F55EE004840D1 /* Assets.xcassets */; }; + C56EE240293F566D004840D1 /* ScanQRView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE23F293F566C004840D1 /* ScanQRView.swift */; }; + C56EE241293F566D004840D1 /* WalletModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE22D293F5669004840D1 /* WalletModule.swift */; }; + C56EE242293F566D004840D1 /* ScanPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE23B293F566C004840D1 /* ScanPresenter.swift */; }; + C56EE243293F566D004840D1 /* ScanView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE23A293F566B004840D1 /* ScanView.swift */; }; + C56EE245293F566D004840D1 /* WalletPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE22C293F5668004840D1 /* WalletPresenter.swift */; }; + C56EE246293F566D004840D1 /* ScanRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE239293F566B004840D1 /* ScanRouter.swift */; }; + C56EE247293F566D004840D1 /* ScanModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE237293F566B004840D1 /* ScanModule.swift */; }; + C56EE248293F566D004840D1 /* ScanQR.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE23E293F566C004840D1 /* ScanQR.swift */; }; + C56EE249293F566D004840D1 /* ScanInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE238293F566B004840D1 /* ScanInteractor.swift */; }; + C56EE24D293F566D004840D1 /* WalletRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE22E293F5669004840D1 /* WalletRouter.swift */; }; + C56EE24E293F566D004840D1 /* WalletInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE22F293F5669004840D1 /* WalletInteractor.swift */; }; + C56EE24F293F566D004840D1 /* WalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE22B293F5668004840D1 /* WalletView.swift */; }; + C56EE250293F566D004840D1 /* ScanTargetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE23D293F566C004840D1 /* ScanTargetView.swift */; }; + C56EE255293F569A004840D1 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = C56EE254293F569A004840D1 /* Starscream */; }; + C56EE26F293F56D7004840D1 /* Types.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE266293F56D6004840D1 /* Types.swift */; }; + C56EE270293F56D7004840D1 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE26A293F56D6004840D1 /* String.swift */; }; + C56EE271293F56D7004840D1 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE26E293F56D7004840D1 /* View.swift */; }; + C56EE273293F56D7004840D1 /* UIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE26B293F56D6004840D1 /* UIColor.swift */; }; + C56EE274293F56D7004840D1 /* SceneViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE264293F56D6004840D1 /* SceneViewController.swift */; }; + C56EE275293F56D7004840D1 /* InputConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE25D293F56D6004840D1 /* InputConfig.swift */; }; + C56EE276293F56D7004840D1 /* UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE26C293F56D6004840D1 /* UIViewController.swift */; }; + C56EE279293F56D7004840D1 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE268293F56D6004840D1 /* Color.swift */; }; + C56EE27B293F56F8004840D1 /* WalletConnectAuth in Frameworks */ = {isa = PBXBuildFile; productRef = C56EE27A293F56F8004840D1 /* WalletConnectAuth */; }; + C56EE27D293F56F8004840D1 /* WalletConnectChat in Frameworks */ = {isa = PBXBuildFile; productRef = C56EE27C293F56F8004840D1 /* WalletConnectChat */; }; + C56EE288293F5757004840D1 /* ThirdPartyConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE286293F5757004840D1 /* ThirdPartyConfigurator.swift */; }; + C56EE289293F5757004840D1 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE280293F5757004840D1 /* Application.swift */; }; + C56EE28A293F5757004840D1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE27F293F5757004840D1 /* AppDelegate.swift */; }; + C56EE28B293F5757004840D1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE281293F5757004840D1 /* SceneDelegate.swift */; }; + C56EE28C293F5757004840D1 /* Configurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE285293F5757004840D1 /* Configurator.swift */; }; + C56EE28D293F5757004840D1 /* AppearanceConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE287293F5757004840D1 /* AppearanceConfigurator.swift */; }; + C56EE28E293F5757004840D1 /* ApplicationConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE284293F5757004840D1 /* ApplicationConfigurator.swift */; }; + C56EE28F293F5757004840D1 /* MigrationConfigurator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE283293F5757004840D1 /* MigrationConfigurator.swift */; }; + C56EE2A3293F6BAF004840D1 /* UIPasteboardWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE2A2293F6BAF004840D1 /* UIPasteboardWrapper.swift */; }; + C5D4603A29687A5700302C7E /* DefaultSocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */; }; C5DD5BE1294E09E3008FD3A4 /* Web3Wallet in Frameworks */ = {isa = PBXBuildFile; productRef = C5DD5BE0294E09E3008FD3A4 /* Web3Wallet */; }; + C5F32A2C2954814200A6476E /* ConnectionDetailsModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5F32A2B2954814200A6476E /* ConnectionDetailsModule.swift */; }; + C5F32A2E2954814A00A6476E /* ConnectionDetailsRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5F32A2D2954814A00A6476E /* ConnectionDetailsRouter.swift */; }; + C5F32A302954816100A6476E /* ConnectionDetailsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5F32A2F2954816100A6476E /* ConnectionDetailsInteractor.swift */; }; + C5F32A322954816C00A6476E /* ConnectionDetailsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5F32A312954816C00A6476E /* ConnectionDetailsPresenter.swift */; }; + C5F32A342954817600A6476E /* ConnectionDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5F32A332954817600A6476E /* ConnectionDetailsView.swift */; }; + C5F32A362954FE3C00A6476E /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C5F32A352954FE3C00A6476E /* Colors.xcassets */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -279,14 +327,6 @@ A541959B2934BFEF0035AD19 /* SignerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignerTests.swift; sourceTree = ""; }; A541959C2934BFEF0035AD19 /* EIP1271VerifierTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP1271VerifierTests.swift; sourceTree = ""; }; A541959D2934BFEF0035AD19 /* EIP191VerifierTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EIP191VerifierTests.swift; sourceTree = ""; }; - A55CAAAB28B92AFF00844382 /* ScanModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanModule.swift; sourceTree = ""; }; - A55CAAAC28B92AFF00844382 /* ScanPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanPresenter.swift; sourceTree = ""; }; - A55CAAAD28B92AFF00844382 /* ScanRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanRouter.swift; sourceTree = ""; }; - A55CAAAE28B92AFF00844382 /* ScanInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanInteractor.swift; sourceTree = ""; }; - A55CAAAF28B92AFF00844382 /* ScanView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanView.swift; sourceTree = ""; }; - A55CAAB628B92B4600844382 /* ScanQRView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScanQRView.swift; sourceTree = ""; }; - A55CAAB728B92B4600844382 /* ScanTargetView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScanTargetView.swift; sourceTree = ""; }; - A55CAAB828B92B4600844382 /* ScanQR.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScanQR.swift; sourceTree = ""; }; A5629AA82876A23100094373 /* ChatService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatService.swift; sourceTree = ""; }; A5629AB82876CBC000094373 /* ChatListModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListModule.swift; sourceTree = ""; }; A5629AB92876CBC000094373 /* ChatListPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListPresenter.swift; sourceTree = ""; }; @@ -342,16 +382,6 @@ A58E7D442872EE570082D443 /* ContentMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentMessageView.swift; sourceTree = ""; }; A58E7D472872EF610082D443 /* MessageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageViewModel.swift; sourceTree = ""; }; A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultSignerFactory.swift; sourceTree = ""; }; - A59EBEF328B54A2A003EDAAF /* AuthRequestModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestModule.swift; sourceTree = ""; }; - A59EBEF428B54A2A003EDAAF /* AuthRequestPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestPresenter.swift; sourceTree = ""; }; - A59EBEF528B54A2A003EDAAF /* AuthRequestRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestRouter.swift; sourceTree = ""; }; - A59EBEF628B54A2A003EDAAF /* AuthRequestInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestInteractor.swift; sourceTree = ""; }; - A59EBEF728B54A2A003EDAAF /* AuthRequestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestView.swift; sourceTree = ""; }; - A59F876A28B53EA000A9CD80 /* WalletModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletModule.swift; sourceTree = ""; }; - A59F876B28B53EA000A9CD80 /* WalletPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletPresenter.swift; sourceTree = ""; }; - A59F876C28B53EA000A9CD80 /* WalletRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletRouter.swift; sourceTree = ""; }; - A59F876D28B53EA000A9CD80 /* WalletInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletInteractor.swift; sourceTree = ""; }; - A59F876E28B53EA000A9CD80 /* WalletView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletView.swift; sourceTree = ""; }; A5A4FC55283CBB7800BBEC1E /* SessionDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionDetailView.swift; sourceTree = ""; }; A5A4FC57283CBB9F00BBEC1E /* SessionDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionDetailViewModel.swift; sourceTree = ""; }; A5A4FC59283CC08600BBEC1E /* SessionNamespaceViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionNamespaceViewModel.swift; sourceTree = ""; }; @@ -393,6 +423,67 @@ A5E22D232840C8DB00E36487 /* SafariEngine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariEngine.swift; sourceTree = ""; }; A5E22D2B2840EAC300E36487 /* XCUIElement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCUIElement.swift; sourceTree = ""; }; A5F48A0528E43D3F0034CBFB /* Configuration.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Configuration.xcconfig; path = ../Configuration.xcconfig; sourceTree = ""; }; + C55D347A295DD7140004314A /* AuthRequestModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestModule.swift; sourceTree = ""; }; + C55D347B295DD7140004314A /* AuthRequestPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestPresenter.swift; sourceTree = ""; }; + C55D347C295DD7140004314A /* AuthRequestRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestRouter.swift; sourceTree = ""; }; + C55D347D295DD7140004314A /* AuthRequestInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestInteractor.swift; sourceTree = ""; }; + C55D347E295DD7140004314A /* AuthRequestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthRequestView.swift; sourceTree = ""; }; + C55D3484295DD8CA0004314A /* PasteUriModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasteUriModule.swift; sourceTree = ""; }; + C55D3485295DD8CA0004314A /* PasteUriPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasteUriPresenter.swift; sourceTree = ""; }; + C55D3486295DD8CA0004314A /* PasteUriRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasteUriRouter.swift; sourceTree = ""; }; + C55D3487295DD8CA0004314A /* PasteUriInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasteUriInteractor.swift; sourceTree = ""; }; + C55D3488295DD8CA0004314A /* PasteUriView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasteUriView.swift; sourceTree = ""; }; + C55D348E295DFA750004314A /* WelcomeModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeModule.swift; sourceTree = ""; }; + C55D348F295DFA750004314A /* WelcomePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomePresenter.swift; sourceTree = ""; }; + C55D3490295DFA750004314A /* WelcomeRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeRouter.swift; sourceTree = ""; }; + C55D3491295DFA750004314A /* WelcomeInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeInteractor.swift; sourceTree = ""; }; + C55D3492295DFA750004314A /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = ""; }; + C55D349A2965BC2F0004314A /* TagsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsView.swift; sourceTree = ""; }; + C55D349C2965F8D30004314A /* Proposal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Proposal.swift; sourceTree = ""; }; + C55D34A92965FB750004314A /* SessionRequestModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionRequestModule.swift; sourceTree = ""; }; + C55D34AA2965FB750004314A /* SessionRequestPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionRequestPresenter.swift; sourceTree = ""; }; + C55D34AB2965FB750004314A /* SessionRequestRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionRequestRouter.swift; sourceTree = ""; }; + C55D34AC2965FB750004314A /* SessionRequestInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionRequestInteractor.swift; sourceTree = ""; }; + C55D34AD2965FB750004314A /* SessionRequestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionRequestView.swift; sourceTree = ""; }; + C56EE21B293F55ED004840D1 /* WalletApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WalletApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + C56EE221293F55EE004840D1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + C56EE22B293F5668004840D1 /* WalletView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletView.swift; sourceTree = ""; }; + C56EE22C293F5668004840D1 /* WalletPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletPresenter.swift; sourceTree = ""; }; + C56EE22D293F5669004840D1 /* WalletModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletModule.swift; sourceTree = ""; }; + C56EE22E293F5669004840D1 /* WalletRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletRouter.swift; sourceTree = ""; }; + C56EE22F293F5669004840D1 /* WalletInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletInteractor.swift; sourceTree = ""; }; + C56EE237293F566B004840D1 /* ScanModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanModule.swift; sourceTree = ""; }; + C56EE238293F566B004840D1 /* ScanInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanInteractor.swift; sourceTree = ""; }; + C56EE239293F566B004840D1 /* ScanRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanRouter.swift; sourceTree = ""; }; + C56EE23A293F566B004840D1 /* ScanView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanView.swift; sourceTree = ""; }; + C56EE23B293F566C004840D1 /* ScanPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanPresenter.swift; sourceTree = ""; }; + C56EE23D293F566C004840D1 /* ScanTargetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanTargetView.swift; sourceTree = ""; }; + C56EE23E293F566C004840D1 /* ScanQR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanQR.swift; sourceTree = ""; }; + C56EE23F293F566C004840D1 /* ScanQRView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanQRView.swift; sourceTree = ""; }; + C56EE25D293F56D6004840D1 /* InputConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputConfig.swift; sourceTree = ""; }; + C56EE264293F56D6004840D1 /* SceneViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneViewController.swift; sourceTree = ""; }; + C56EE266293F56D6004840D1 /* Types.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Types.swift; sourceTree = ""; }; + C56EE268293F56D6004840D1 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; + C56EE26A293F56D6004840D1 /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = ""; }; + C56EE26B293F56D6004840D1 /* UIColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColor.swift; sourceTree = ""; }; + C56EE26C293F56D6004840D1 /* UIViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewController.swift; sourceTree = ""; }; + C56EE26E293F56D7004840D1 /* View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = ""; }; + C56EE27F293F5757004840D1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + C56EE280293F5757004840D1 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = ""; }; + C56EE281293F5757004840D1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + C56EE283293F5757004840D1 /* MigrationConfigurator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationConfigurator.swift; sourceTree = ""; }; + C56EE284293F5757004840D1 /* ApplicationConfigurator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationConfigurator.swift; sourceTree = ""; }; + C56EE285293F5757004840D1 /* Configurator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configurator.swift; sourceTree = ""; }; + C56EE286293F5757004840D1 /* ThirdPartyConfigurator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThirdPartyConfigurator.swift; sourceTree = ""; }; + C56EE287293F5757004840D1 /* AppearanceConfigurator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceConfigurator.swift; sourceTree = ""; }; + C56EE29F293F5C4F004840D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C56EE2A2293F6BAF004840D1 /* UIPasteboardWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIPasteboardWrapper.swift; sourceTree = ""; }; + C5F32A2B2954814200A6476E /* ConnectionDetailsModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionDetailsModule.swift; sourceTree = ""; }; + C5F32A2D2954814A00A6476E /* ConnectionDetailsRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionDetailsRouter.swift; sourceTree = ""; }; + C5F32A2F2954816100A6476E /* ConnectionDetailsInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionDetailsInteractor.swift; sourceTree = ""; }; + C5F32A312954816C00A6476E /* ConnectionDetailsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionDetailsPresenter.swift; sourceTree = ""; }; + C5F32A332954817600A6476E /* ConnectionDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionDetailsView.swift; sourceTree = ""; }; + C5F32A352954FE3C00A6476E /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -455,6 +546,18 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C56EE218293F55ED004840D1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C56EE27D293F56F8004840D1 /* WalletConnectChat in Frameworks */, + C5133A78294125CC00A8314C /* Web3 in Frameworks */, + C55D349929630D440004314A /* Web3Wallet in Frameworks */, + C56EE255293F569A004840D1 /* Starscream in Frameworks */, + C56EE27B293F56F8004840D1 /* WalletConnectAuth in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -506,6 +609,7 @@ A5A4FC732840C12C00BBEC1E /* UITests */, A5E03DEE286464DB00888481 /* IntegrationTests */, A58E7CE928729F550082D443 /* Showcase */, + C56EE21C293F55ED004840D1 /* WalletApp */, 764E1D3D26F8D3FC00A1FB15 /* Products */, 764E1D5326F8DAC800A1FB15 /* Frameworks */, 764E1D5626F8DB6000A1FB15 /* WalletConnectSwiftV2 */, @@ -520,6 +624,7 @@ A5A4FC722840C12C00BBEC1E /* UITests.xctest */, A5E03DED286464DB00888481 /* IntegrationTests.xctest */, A58E7CE828729F550082D443 /* Showcase.app */, + C56EE21B293F55ED004840D1 /* WalletApp.app */, ); name = Products; sourceTree = ""; @@ -684,29 +789,6 @@ path = Signer; sourceTree = ""; }; - A55CAAAA28B92AF200844382 /* Scan */ = { - isa = PBXGroup; - children = ( - A55CAAB528B92B3200844382 /* Views */, - A55CAAAB28B92AFF00844382 /* ScanModule.swift */, - A55CAAAC28B92AFF00844382 /* ScanPresenter.swift */, - A55CAAAD28B92AFF00844382 /* ScanRouter.swift */, - A55CAAAE28B92AFF00844382 /* ScanInteractor.swift */, - A55CAAAF28B92AFF00844382 /* ScanView.swift */, - ); - path = Scan; - sourceTree = ""; - }; - A55CAAB528B92B3200844382 /* Views */ = { - isa = PBXGroup; - children = ( - A55CAAB828B92B4600844382 /* ScanQR.swift */, - A55CAAB628B92B4600844382 /* ScanQRView.swift */, - A55CAAB728B92B4600844382 /* ScanTargetView.swift */, - ); - path = Views; - sourceTree = ""; - }; A5629AA42876A19D00094373 /* DomainLayer */ = { isa = PBXGroup; children = ( @@ -879,7 +961,6 @@ A58E7D062872A4390082D443 /* PresentationLayer */ = { isa = PBXGroup; children = ( - A59F876928B53E7800A9CD80 /* Wallet */, A59F876828B53E6400A9CD80 /* Chat */, ); path = PresentationLayer; @@ -960,18 +1041,6 @@ path = Models; sourceTree = ""; }; - A59EBEFD28B54A2E003EDAAF /* AuthRequest */ = { - isa = PBXGroup; - children = ( - A59EBEF328B54A2A003EDAAF /* AuthRequestModule.swift */, - A59EBEF428B54A2A003EDAAF /* AuthRequestPresenter.swift */, - A59EBEF528B54A2A003EDAAF /* AuthRequestRouter.swift */, - A59EBEF628B54A2A003EDAAF /* AuthRequestInteractor.swift */, - A59EBEF728B54A2A003EDAAF /* AuthRequestView.swift */, - ); - path = AuthRequest; - sourceTree = ""; - }; A59F876828B53E6400A9CD80 /* Chat */ = { isa = PBXGroup; children = ( @@ -986,28 +1055,6 @@ path = Chat; sourceTree = ""; }; - A59F876928B53E7800A9CD80 /* Wallet */ = { - isa = PBXGroup; - children = ( - A55CAAAA28B92AF200844382 /* Scan */, - A59EBEFD28B54A2E003EDAAF /* AuthRequest */, - A59F877428B53EA500A9CD80 /* Wallet */, - ); - path = Wallet; - sourceTree = ""; - }; - A59F877428B53EA500A9CD80 /* Wallet */ = { - isa = PBXGroup; - children = ( - A59F876A28B53EA000A9CD80 /* WalletModule.swift */, - A59F876B28B53EA000A9CD80 /* WalletPresenter.swift */, - A59F876C28B53EA000A9CD80 /* WalletRouter.swift */, - A59F876D28B53EA000A9CD80 /* WalletInteractor.swift */, - A59F876E28B53EA000A9CD80 /* WalletView.swift */, - ); - path = Wallet; - sourceTree = ""; - }; A5A4FC732840C12C00BBEC1E /* UITests */ = { isa = PBXGroup; children = ( @@ -1183,6 +1230,249 @@ path = Extensions; sourceTree = ""; }; + C55D3471295DC5F60004314A /* PasteUri */ = { + isa = PBXGroup; + children = ( + C55D3484295DD8CA0004314A /* PasteUriModule.swift */, + C55D3485295DD8CA0004314A /* PasteUriPresenter.swift */, + C55D3486295DD8CA0004314A /* PasteUriRouter.swift */, + C55D3487295DD8CA0004314A /* PasteUriInteractor.swift */, + C55D3488295DD8CA0004314A /* PasteUriView.swift */, + ); + path = PasteUri; + sourceTree = ""; + }; + C55D3474295DCB850004314A /* AuthRequest */ = { + isa = PBXGroup; + children = ( + C55D347A295DD7140004314A /* AuthRequestModule.swift */, + C55D347B295DD7140004314A /* AuthRequestPresenter.swift */, + C55D347C295DD7140004314A /* AuthRequestRouter.swift */, + C55D347D295DD7140004314A /* AuthRequestInteractor.swift */, + C55D347E295DD7140004314A /* AuthRequestView.swift */, + ); + path = AuthRequest; + sourceTree = ""; + }; + C55D3477295DD4AA0004314A /* Welcome */ = { + isa = PBXGroup; + children = ( + C55D348E295DFA750004314A /* WelcomeModule.swift */, + C55D348F295DFA750004314A /* WelcomePresenter.swift */, + C55D3490295DFA750004314A /* WelcomeRouter.swift */, + C55D3491295DFA750004314A /* WelcomeInteractor.swift */, + C55D3492295DFA750004314A /* WelcomeView.swift */, + ); + path = Welcome; + sourceTree = ""; + }; + C55D349E2965FAC30004314A /* SessionRequest */ = { + isa = PBXGroup; + children = ( + C55D34B32965FF750004314A /* Modela */, + C55D34A92965FB750004314A /* SessionRequestModule.swift */, + C55D34AA2965FB750004314A /* SessionRequestPresenter.swift */, + C55D34AB2965FB750004314A /* SessionRequestRouter.swift */, + C55D34AC2965FB750004314A /* SessionRequestInteractor.swift */, + C55D34AD2965FB750004314A /* SessionRequestView.swift */, + ); + path = SessionRequest; + sourceTree = ""; + }; + C55D34B32965FF750004314A /* Modela */ = { + isa = PBXGroup; + children = ( + C55D349C2965F8D30004314A /* Proposal.swift */, + ); + path = Modela; + sourceTree = ""; + }; + C56EE21C293F55ED004840D1 /* WalletApp */ = { + isa = PBXGroup; + children = ( + C56EE25C293F56D6004840D1 /* Common */, + C56EE27E293F5756004840D1 /* ApplicationLayer */, + C56EE29E293F577B004840D1 /* PresentationLayer */, + C56EE2A0293F6B10004840D1 /* Other */, + ); + path = WalletApp; + sourceTree = ""; + }; + C56EE229293F5668004840D1 /* Wallet */ = { + isa = PBXGroup; + children = ( + C55D349E2965FAC30004314A /* SessionRequest */, + C55D3477295DD4AA0004314A /* Welcome */, + C55D3474295DCB850004314A /* AuthRequest */, + C55D3471295DC5F60004314A /* PasteUri */, + C5F32A2A2954812900A6476E /* ConnectionDetails */, + C56EE236293F566A004840D1 /* Scan */, + C56EE22A293F5668004840D1 /* Wallet */, + ); + path = Wallet; + sourceTree = ""; + }; + C56EE22A293F5668004840D1 /* Wallet */ = { + isa = PBXGroup; + children = ( + C56EE22D293F5669004840D1 /* WalletModule.swift */, + C56EE22E293F5669004840D1 /* WalletRouter.swift */, + C56EE22F293F5669004840D1 /* WalletInteractor.swift */, + C56EE22C293F5668004840D1 /* WalletPresenter.swift */, + C56EE22B293F5668004840D1 /* WalletView.swift */, + ); + path = Wallet; + sourceTree = ""; + }; + C56EE236293F566A004840D1 /* Scan */ = { + isa = PBXGroup; + children = ( + C56EE23C293F566C004840D1 /* Views */, + C56EE237293F566B004840D1 /* ScanModule.swift */, + C56EE23B293F566C004840D1 /* ScanPresenter.swift */, + C56EE239293F566B004840D1 /* ScanRouter.swift */, + C56EE238293F566B004840D1 /* ScanInteractor.swift */, + C56EE23A293F566B004840D1 /* ScanView.swift */, + ); + path = Scan; + sourceTree = ""; + }; + C56EE23C293F566C004840D1 /* Views */ = { + isa = PBXGroup; + children = ( + C56EE23E293F566C004840D1 /* ScanQR.swift */, + C56EE23F293F566C004840D1 /* ScanQRView.swift */, + C56EE23D293F566C004840D1 /* ScanTargetView.swift */, + ); + path = Views; + sourceTree = ""; + }; + C56EE25C293F56D6004840D1 /* Common */ = { + isa = PBXGroup; + children = ( + C56EE25D293F56D6004840D1 /* InputConfig.swift */, + C56EE265293F56D6004840D1 /* Types */, + C56EE267293F56D6004840D1 /* Style */, + C56EE2A1293F6B9E004840D1 /* Helpers */, + C56EE262293F56D6004840D1 /* Extensions */, + C56EE263293F56D6004840D1 /* VIPER */, + ); + path = Common; + sourceTree = ""; + }; + C56EE262293F56D6004840D1 /* Extensions */ = { + isa = PBXGroup; + children = ( + C56EE26D293F56D6004840D1 /* SwiftUI */, + C56EE269293F56D6004840D1 /* UIKit */, + ); + path = Extensions; + sourceTree = ""; + }; + C56EE263293F56D6004840D1 /* VIPER */ = { + isa = PBXGroup; + children = ( + C56EE264293F56D6004840D1 /* SceneViewController.swift */, + ); + path = VIPER; + sourceTree = ""; + }; + C56EE265293F56D6004840D1 /* Types */ = { + isa = PBXGroup; + children = ( + C56EE266293F56D6004840D1 /* Types.swift */, + ); + path = Types; + sourceTree = ""; + }; + C56EE267293F56D6004840D1 /* Style */ = { + isa = PBXGroup; + children = ( + C56EE268293F56D6004840D1 /* Color.swift */, + ); + path = Style; + sourceTree = ""; + }; + C56EE269293F56D6004840D1 /* UIKit */ = { + isa = PBXGroup; + children = ( + C56EE26C293F56D6004840D1 /* UIViewController.swift */, + C56EE26A293F56D6004840D1 /* String.swift */, + C56EE26B293F56D6004840D1 /* UIColor.swift */, + ); + path = UIKit; + sourceTree = ""; + }; + C56EE26D293F56D6004840D1 /* SwiftUI */ = { + isa = PBXGroup; + children = ( + C56EE26E293F56D7004840D1 /* View.swift */, + ); + path = SwiftUI; + sourceTree = ""; + }; + C56EE27E293F5756004840D1 /* ApplicationLayer */ = { + isa = PBXGroup; + children = ( + C56EE282293F5757004840D1 /* Configurator */, + C56EE280293F5757004840D1 /* Application.swift */, + C56EE27F293F5757004840D1 /* AppDelegate.swift */, + C56EE281293F5757004840D1 /* SceneDelegate.swift */, + ); + path = ApplicationLayer; + sourceTree = ""; + }; + C56EE282293F5757004840D1 /* Configurator */ = { + isa = PBXGroup; + children = ( + C56EE285293F5757004840D1 /* Configurator.swift */, + C56EE286293F5757004840D1 /* ThirdPartyConfigurator.swift */, + C56EE284293F5757004840D1 /* ApplicationConfigurator.swift */, + C56EE283293F5757004840D1 /* MigrationConfigurator.swift */, + C56EE287293F5757004840D1 /* AppearanceConfigurator.swift */, + ); + path = Configurator; + sourceTree = ""; + }; + C56EE29E293F577B004840D1 /* PresentationLayer */ = { + isa = PBXGroup; + children = ( + C56EE229293F5668004840D1 /* Wallet */, + ); + path = PresentationLayer; + sourceTree = ""; + }; + C56EE2A0293F6B10004840D1 /* Other */ = { + isa = PBXGroup; + children = ( + C56EE221293F55EE004840D1 /* Assets.xcassets */, + C56EE29F293F5C4F004840D1 /* Info.plist */, + C5F32A352954FE3C00A6476E /* Colors.xcassets */, + ); + path = Other; + sourceTree = ""; + }; + C56EE2A1293F6B9E004840D1 /* Helpers */ = { + isa = PBXGroup; + children = ( + C56EE2A2293F6BAF004840D1 /* UIPasteboardWrapper.swift */, + C55D349A2965BC2F0004314A /* TagsView.swift */, + ); + path = Helpers; + sourceTree = ""; + }; + C5F32A2A2954812900A6476E /* ConnectionDetails */ = { + isa = PBXGroup; + children = ( + C5F32A2B2954814200A6476E /* ConnectionDetailsModule.swift */, + C5F32A2D2954814A00A6476E /* ConnectionDetailsRouter.swift */, + C5F32A2F2954816100A6476E /* ConnectionDetailsInteractor.swift */, + C5F32A312954816C00A6476E /* ConnectionDetailsPresenter.swift */, + C5F32A332954817600A6476E /* ConnectionDetailsView.swift */, + ); + path = ConnectionDetails; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1305,13 +1595,37 @@ productReference = A5E03DED286464DB00888481 /* IntegrationTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + C56EE21A293F55ED004840D1 /* WalletApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = C56EE228293F55EE004840D1 /* Build configuration list for PBXNativeTarget "WalletApp" */; + buildPhases = ( + C56EE217293F55ED004840D1 /* Sources */, + C56EE218293F55ED004840D1 /* Frameworks */, + C56EE219293F55ED004840D1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = WalletApp; + packageProductDependencies = ( + C56EE254293F569A004840D1 /* Starscream */, + C56EE27A293F56F8004840D1 /* WalletConnectAuth */, + C56EE27C293F56F8004840D1 /* WalletConnectChat */, + C5133A77294125CC00A8314C /* Web3 */, + C55D349829630D440004314A /* Web3Wallet */, + ); + productName = ChatWallet; + productReference = C56EE21B293F55ED004840D1 /* WalletApp.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 764E1D3426F8D3FC00A1FB15 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1330; + LastSwiftUpdateCheck = 1410; LastUpgradeCheck = 1250; TargetAttributes = { 764E1D3B26F8D3FC00A1FB15 = { @@ -1329,6 +1643,9 @@ A5E03DEC286464DB00888481 = { CreatedOnToolsVersion = 13.3; }; + C56EE21A293F55ED004840D1 = { + CreatedOnToolsVersion = 14.1; + }; }; }; buildConfigurationList = 764E1D3726F8D3FC00A1FB15 /* Build configuration list for PBXProject "ExampleApp" */; @@ -1354,6 +1671,7 @@ A5A4FC712840C12C00BBEC1E /* UITests */, A5E03DEC286464DB00888481 /* IntegrationTests */, A58E7CE728729F550082D443 /* Showcase */, + C56EE21A293F55ED004840D1 /* WalletApp */, ); }; /* End PBXProject section */ @@ -1400,6 +1718,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C56EE219293F55ED004840D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C56EE222293F55EE004840D1 /* Assets.xcassets in Resources */, + C5F32A362954FE3C00A6476E /* Colors.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1483,18 +1810,12 @@ A58E7D0E2872A45B0082D443 /* MainRouter.swift in Sources */, A58E7D432872EE320082D443 /* MessageView.swift in Sources */, A58E7D3F2872E99A0082D443 /* TabPage.swift in Sources */, - A59EBEFB28B54A2A003EDAAF /* AuthRequestInteractor.swift in Sources */, - A59F877228B53EA000A9CD80 /* WalletInteractor.swift in Sources */, A58E7D3C2872D55F0082D443 /* ChatPresenter.swift in Sources */, - A59EBEF928B54A2A003EDAAF /* AuthRequestPresenter.swift in Sources */, A5C2020B287D9DEE007E3188 /* WelcomeModule.swift in Sources */, - A59F876F28B53EA000A9CD80 /* WalletModule.swift in Sources */, A58E7D152872A5410082D443 /* UIViewController.swift in Sources */, - A59EBEF828B54A2A003EDAAF /* AuthRequestModule.swift in Sources */, A58E7D132872A4A80082D443 /* Application.swift in Sources */, A58E7D002872A1050082D443 /* SceneViewController.swift in Sources */, A58E7D242872AB130082D443 /* MainViewController.swift in Sources */, - A59EBEFC28B54A2A003EDAAF /* AuthRequestView.swift in Sources */, A5629AE02876CC6E00094373 /* InviteListRouter.swift in Sources */, A58E7D032872A1630082D443 /* String.swift in Sources */, A58E7D3D2872D55F0082D443 /* ChatView.swift in Sources */, @@ -1504,7 +1825,6 @@ A5629ADE2876CC6E00094373 /* InviteListModule.swift in Sources */, A578FA322873036400AA7720 /* InputView.swift in Sources */, A5C2021B287E1FD8007E3188 /* ImportRouter.swift in Sources */, - A59F877328B53EA000A9CD80 /* WalletView.swift in Sources */, A5629AE42876E6D200094373 /* ThreadViewModel.swift in Sources */, A58E7D0C2872A45B0082D443 /* MainModule.swift in Sources */, A5C2021C287E1FD8007E3188 /* ImportInteractor.swift in Sources */, @@ -1514,39 +1834,28 @@ A5629AE12876CC6E00094373 /* InviteListInteractor.swift in Sources */, A58E7CED28729F550082D443 /* SceneDelegate.swift in Sources */, A5C2020F287D9DEE007E3188 /* WelcomeView.swift in Sources */, - A55CAAB128B92AFF00844382 /* ScanPresenter.swift in Sources */, - A59F877128B53EA000A9CD80 /* WalletRouter.swift in Sources */, A5C20226287EB099007E3188 /* AccountNameResolver.swift in Sources */, A5C2020D287D9DEE007E3188 /* WelcomeRouter.swift in Sources */, - A55CAAB328B92AFF00844382 /* ScanInteractor.swift in Sources */, - A55CAABA28B92B4600844382 /* ScanTargetView.swift in Sources */, A578FA372873D8EE00AA7720 /* UIColor.swift in Sources */, A5C2021D287E1FD8007E3188 /* ImportView.swift in Sources */, A5C2021A287E1FD8007E3188 /* ImportPresenter.swift in Sources */, A5629AE828772A0100094373 /* InviteViewModel.swift in Sources */, - A55CAAB928B92B4600844382 /* ScanQRView.swift in Sources */, A5629AA92876A23100094373 /* ChatService.swift in Sources */, A5C20229287EB34C007E3188 /* AccountStorage.swift in Sources */, A5629AC02876CBC000094373 /* ChatListInteractor.swift in Sources */, - A55CAAB428B92AFF00844382 /* ScanView.swift in Sources */, A5629AE22876CC6E00094373 /* InviteListView.swift in Sources */, A5A8E47F293A1D0000FEB97D /* DefaultSocketFactory.swift in Sources */, A578FA3D2874002400AA7720 /* View.swift in Sources */, A5629AD72876CC5700094373 /* InviteView.swift in Sources */, - A59EBEFA28B54A2A003EDAAF /* AuthRequestRouter.swift in Sources */, - A55CAAB228B92AFF00844382 /* ScanRouter.swift in Sources */, A5C20221287EA5B8007E3188 /* TextFieldView.swift in Sources */, A5A8E480293A1D0000FEB97D /* DefaultSignerFactory.swift in Sources */, A5C2022B287EB89A007E3188 /* WelcomeInteractor.swift in Sources */, A5C2020C287D9DEE007E3188 /* WelcomePresenter.swift in Sources */, A58E7D1D2872A57B0082D443 /* Configurator.swift in Sources */, A58E7D482872EF610082D443 /* MessageViewModel.swift in Sources */, - A59F877028B53EA000A9CD80 /* WalletPresenter.swift in Sources */, A5629AD32876CC5700094373 /* InviteModule.swift in Sources */, A5629AD52876CC5700094373 /* InviteRouter.swift in Sources */, - A55CAABB28B92B4600844382 /* ScanQR.swift in Sources */, A5629ABF2876CBC000094373 /* ChatListRouter.swift in Sources */, - A55CAAB028B92AFF00844382 /* ScanModule.swift in Sources */, A5629AC12876CBC000094373 /* ChatListView.swift in Sources */, A578FA392873FCE000AA7720 /* ChatScrollView.swift in Sources */, A58E7D1E2872A57B0082D443 /* ThirdPartyConfigurator.swift in Sources */, @@ -1599,6 +1908,72 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C56EE217293F55ED004840D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C5D4603A29687A5700302C7E /* DefaultSocketFactory.swift in Sources */, + C53AA4362941251C008EA57C /* DefaultSignerFactory.swift in Sources */, + C55D3480295DD7140004314A /* AuthRequestPresenter.swift in Sources */, + C5F32A2E2954814A00A6476E /* ConnectionDetailsRouter.swift in Sources */, + C55D3482295DD7140004314A /* AuthRequestInteractor.swift in Sources */, + C55D34B12965FB750004314A /* SessionRequestInteractor.swift in Sources */, + C56EE247293F566D004840D1 /* ScanModule.swift in Sources */, + C56EE28D293F5757004840D1 /* AppearanceConfigurator.swift in Sources */, + C56EE241293F566D004840D1 /* WalletModule.swift in Sources */, + C56EE26F293F56D7004840D1 /* Types.swift in Sources */, + C56EE245293F566D004840D1 /* WalletPresenter.swift in Sources */, + C56EE240293F566D004840D1 /* ScanQRView.swift in Sources */, + C56EE250293F566D004840D1 /* ScanTargetView.swift in Sources */, + C56EE28F293F5757004840D1 /* MigrationConfigurator.swift in Sources */, + C55D348B295DD8CA0004314A /* PasteUriRouter.swift in Sources */, + C55D348C295DD8CA0004314A /* PasteUriInteractor.swift in Sources */, + C55D3497295DFA750004314A /* WelcomeView.swift in Sources */, + C56EE271293F56D7004840D1 /* View.swift in Sources */, + C56EE24D293F566D004840D1 /* WalletRouter.swift in Sources */, + C5F32A342954817600A6476E /* ConnectionDetailsView.swift in Sources */, + C55D348A295DD8CA0004314A /* PasteUriPresenter.swift in Sources */, + C56EE28E293F5757004840D1 /* ApplicationConfigurator.swift in Sources */, + C55D347F295DD7140004314A /* AuthRequestModule.swift in Sources */, + C56EE242293F566D004840D1 /* ScanPresenter.swift in Sources */, + C56EE28B293F5757004840D1 /* SceneDelegate.swift in Sources */, + C56EE276293F56D7004840D1 /* UIViewController.swift in Sources */, + C56EE275293F56D7004840D1 /* InputConfig.swift in Sources */, + C55D3493295DFA750004314A /* WelcomeModule.swift in Sources */, + C56EE270293F56D7004840D1 /* String.swift in Sources */, + C56EE279293F56D7004840D1 /* Color.swift in Sources */, + C55D3483295DD7140004314A /* AuthRequestView.swift in Sources */, + C56EE243293F566D004840D1 /* ScanView.swift in Sources */, + C56EE288293F5757004840D1 /* ThirdPartyConfigurator.swift in Sources */, + C55D34AE2965FB750004314A /* SessionRequestModule.swift in Sources */, + C55D34B02965FB750004314A /* SessionRequestRouter.swift in Sources */, + C55D3495295DFA750004314A /* WelcomeRouter.swift in Sources */, + C56EE24F293F566D004840D1 /* WalletView.swift in Sources */, + C55D34B22965FB750004314A /* SessionRequestView.swift in Sources */, + C56EE248293F566D004840D1 /* ScanQR.swift in Sources */, + C55D349B2965BC2F0004314A /* TagsView.swift in Sources */, + C56EE289293F5757004840D1 /* Application.swift in Sources */, + C56EE273293F56D7004840D1 /* UIColor.swift in Sources */, + C5F32A322954816C00A6476E /* ConnectionDetailsPresenter.swift in Sources */, + C56EE246293F566D004840D1 /* ScanRouter.swift in Sources */, + C55D349D2965F8D40004314A /* Proposal.swift in Sources */, + C55D3481295DD7140004314A /* AuthRequestRouter.swift in Sources */, + C56EE28C293F5757004840D1 /* Configurator.swift in Sources */, + C55D3489295DD8CA0004314A /* PasteUriModule.swift in Sources */, + C55D3494295DFA750004314A /* WelcomePresenter.swift in Sources */, + C56EE274293F56D7004840D1 /* SceneViewController.swift in Sources */, + C55D3496295DFA750004314A /* WelcomeInteractor.swift in Sources */, + C55D348D295DD8CA0004314A /* PasteUriView.swift in Sources */, + C5F32A2C2954814200A6476E /* ConnectionDetailsModule.swift in Sources */, + C56EE249293F566D004840D1 /* ScanInteractor.swift in Sources */, + C56EE28A293F5757004840D1 /* AppDelegate.swift in Sources */, + C56EE2A3293F6BAF004840D1 /* UIPasteboardWrapper.swift in Sources */, + C56EE24E293F566D004840D1 /* WalletInteractor.swift in Sources */, + C55D34AF2965FB750004314A /* SessionRequestPresenter.swift in Sources */, + C5F32A302954816100A6476E /* ConnectionDetailsInteractor.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -2018,6 +2393,66 @@ }; name = Release; }; + C56EE226293F55EE004840D1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = RQ4NX29V75; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = WalletApp/Other/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.walletapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + C56EE227293F55EE004840D1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = RQ4NX29V75; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = WalletApp/Other/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.walletapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -2075,6 +2510,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + C56EE228293F55EE004840D1 /* Build configuration list for PBXNativeTarget "WalletApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C56EE226293F55EE004840D1 /* Debug */, + C56EE227293F55EE004840D1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ @@ -2206,6 +2650,28 @@ isa = XCSwiftPackageProductDependency; productName = WalletConnectChat; }; + C5133A77294125CC00A8314C /* Web3 */ = { + isa = XCSwiftPackageProductDependency; + package = A5AE354528A1A2AC0059AE8A /* XCRemoteSwiftPackageReference "Web3" */; + productName = Web3; + }; + C55D349829630D440004314A /* Web3Wallet */ = { + isa = XCSwiftPackageProductDependency; + productName = Web3Wallet; + }; + C56EE254293F569A004840D1 /* Starscream */ = { + isa = XCSwiftPackageProductDependency; + package = A5D85224286333D500DAF5C3 /* XCRemoteSwiftPackageReference "Starscream" */; + productName = Starscream; + }; + C56EE27A293F56F8004840D1 /* WalletConnectAuth */ = { + isa = XCSwiftPackageProductDependency; + productName = WalletConnectAuth; + }; + C56EE27C293F56F8004840D1 /* WalletConnectChat */ = { + isa = XCSwiftPackageProductDependency; + productName = WalletConnectChat; + }; C5DD5BE0294E09E3008FD3A4 /* Web3Wallet */ = { isa = XCSwiftPackageProductDependency; productName = Web3Wallet; diff --git a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletApp.xcscheme b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletApp.xcscheme new file mode 100644 index 000000000..036e15875 --- /dev/null +++ b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/WalletApp.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/Showcase/Classes/ApplicationLayer/Configurator/ApplicationConfigurator.swift b/Example/Showcase/Classes/ApplicationLayer/Configurator/ApplicationConfigurator.swift index a50e9c6e6..810260eef 100644 --- a/Example/Showcase/Classes/ApplicationLayer/Configurator/ApplicationConfigurator.swift +++ b/Example/Showcase/Classes/ApplicationLayer/Configurator/ApplicationConfigurator.swift @@ -11,6 +11,6 @@ struct ApplicationConfigurator: Configurator { } func configure() { - MainModule.create(app: app).present() + WelcomeModule.create(app: app).present() } } diff --git a/Example/Showcase/Classes/ApplicationLayer/SceneDelegate.swift b/Example/Showcase/Classes/ApplicationLayer/SceneDelegate.swift index 7681f528a..537e88926 100644 --- a/Example/Showcase/Classes/ApplicationLayer/SceneDelegate.swift +++ b/Example/Showcase/Classes/ApplicationLayer/SceneDelegate.swift @@ -30,8 +30,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { guard let context = URLContexts.first else { return } let uri = context.url.absoluteString.replacingOccurrences(of: "showcase://wc?uri=", with: "") + guard let walletConnectUri = WalletConnectURI(string: uri) else { + return + } + Task { - try await Pair.instance.pair(uri: WalletConnectURI(string: uri)!) + try await Pair.instance.pair(uri: walletConnectUri) } } } diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/Main/MainPresenter.swift b/Example/Showcase/Classes/PresentationLayer/Chat/Main/MainPresenter.swift index b61e7dd27..fde2e49fc 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/Main/MainPresenter.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/Main/MainPresenter.swift @@ -11,8 +11,7 @@ final class MainPresenter { var viewControllers: [UIViewController] { return [ - router.chatViewController, - router.walletViewController + router.chatViewController ] } diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/Main/MainRouter.swift b/Example/Showcase/Classes/PresentationLayer/Chat/Main/MainRouter.swift index d80001361..fdd32686d 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/Main/MainRouter.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/Main/MainRouter.swift @@ -6,10 +6,6 @@ final class MainRouter { private let app: Application - var walletViewController: UIViewController { - return WalletModule.create(app: app).wrapToNavigationController() - } - var chatViewController: UIViewController { return WelcomeModule.create(app: app) } diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeInteractor.swift b/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeInteractor.swift index 8da35b860..548e47f5e 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeInteractor.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeInteractor.swift @@ -1,7 +1,13 @@ import Foundation +import Combine + import WalletConnectRelay +import WalletConnectPairing +import Auth final class WelcomeInteractor { + private var disposeBag = Set() + private let chatService: ChatService private let accountStorage: AccountStorage @@ -21,4 +27,18 @@ final class WelcomeInteractor { func trackConnection() -> Stream { return chatService.connectionPublisher } + + func generateUri() async -> WalletConnectURI { + return try! await Pair.instance.create() + } +} + +protocol IATProvider { + var iat: String { get } +} + +struct DefaultIATProvider: IATProvider { + var iat: String { + return ISO8601DateFormatter().string(from: Date()) + } } diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomePresenter.swift b/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomePresenter.swift index 28eac8895..0ad6296ee 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomePresenter.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomePresenter.swift @@ -1,5 +1,6 @@ import UIKit import Combine +import Auth final class WelcomePresenter: ObservableObject { @@ -22,14 +23,36 @@ final class WelcomePresenter: ObservableObject { } var buttonTitle: String { - return interactor.isAuthorized() ? "Start Messaging" : "Import account" + return interactor.isAuthorized() ? "Start Messaging" : "Connect wallet" } - func didPressImport() { + func didPressImport() async { if let account = interactor.account { router.presentChats(account: account) } else { - router.presentImport() + await authWithWallet() + } + } + + private func authWithWallet() async { + let uri = await interactor.generateUri() + try? await Auth.instance.request( + RequestParams( + domain: "example.wallet", + chainId: "eip155:1", + nonce: "32891756", + aud: "https://example.wallet/login", + nbf: nil, + exp: nil, + statement: "I accept the ServiceOrg Terms of Service: https://service.invalid/tos", + requestId: nil, + resources: ["ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/", "https://example.com/my-web2-claim.json"] + ), + topic: uri.topic + ) + + DispatchQueue.main.async { + self.router.openWallet(uri: uri.absoluteString) } } } diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeRouter.swift b/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeRouter.swift index 1bc4b9e1f..e69faac65 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeRouter.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeRouter.swift @@ -21,4 +21,8 @@ final class WelcomeRouter { .wrapToNavigationController() .present() } + + func openWallet(uri: String) { + UIApplication.shared.open(URL(string: "walletapp://wc?uri=\(uri)")!) + } } diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeView.swift b/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeView.swift index 2d9ba4129..b56ef64e0 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeView.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/Welcome/WelcomeView.swift @@ -32,7 +32,9 @@ struct WelcomeView: View { .multilineTextAlignment(.center) BrandButton(title: presenter.buttonTitle, action: { - presenter.didPressImport() + Task { + await presenter.didPressImport() + } }) Text("By connecting your wallet you agree with our\nTerms of Service") diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestView.swift b/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestView.swift deleted file mode 100644 index c8443c337..000000000 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestView.swift +++ /dev/null @@ -1,54 +0,0 @@ -import SwiftUI - -struct AuthRequestView: View { - - @EnvironmentObject var presenter: AuthRequestPresenter - - var body: some View { - VStack(spacing: 16.0) { - HStack { - Text("Message to sign:") - Spacer() - } - - VStack { - Text(presenter.message) - .font(Font.system(size: 13)) - .padding(16.0) - } - .background(Color.white.opacity(0.1)) - .cornerRadius(10) - - HStack(spacing: 16.0) { - Button(action: { Task(priority: .userInitiated) { try await presenter.rejectPressed() }}, label: { - HStack(spacing: 8.0) { - Text("Reject") - .foregroundColor(.w_foreground) - .font(.system(size: 18, weight: .semibold)) - } - }) - .frame(width: 120, height: 44) - .background( - Capsule() - .foregroundColor(.w_purpleForeground) - ) - - Button(action: { Task(priority: .userInitiated) { try await presenter.approvePressed() }}, label: { - HStack(spacing: 8.0) { - Text("Approve") - .foregroundColor(.w_foreground) - .font(.system(size: 18, weight: .semibold)) - } - }) - .frame(width: 120, height: 44) - .background( - Capsule() - .foregroundColor(.w_greenForground) - ) - } - - Spacer() - } - .padding(16.0) - } -} diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanView.swift b/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanView.swift deleted file mode 100644 index f8f36e7bb..000000000 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanView.swift +++ /dev/null @@ -1,19 +0,0 @@ -import SwiftUI - -struct ScanView: View { - - @EnvironmentObject var presenter: ScanPresenter - - var body: some View { - ScanQR(onValue: presenter.onValue, onError: presenter.onError) - .ignoresSafeArea() - } -} - -#if DEBUG -struct ScanView_Previews: PreviewProvider { - static var previews: some View { - ScanView() - } -} -#endif diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletInteractor.swift b/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletInteractor.swift deleted file mode 100644 index 7379f18c5..000000000 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletInteractor.swift +++ /dev/null @@ -1,14 +0,0 @@ -import Combine -import Auth -import WalletConnectPairing - -final class WalletInteractor { - - func pair(uri: WalletConnectURI) async throws { - try await Pair.instance.pair(uri: uri) - } - - var requestPublisher: AnyPublisher { - return Auth.instance.authRequestPublisher - } -} diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletPresenter.swift b/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletPresenter.swift deleted file mode 100644 index ccf630ca8..000000000 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletPresenter.swift +++ /dev/null @@ -1,63 +0,0 @@ -import UIKit -import Combine -import Auth - -final class WalletPresenter: ObservableObject { - - private let interactor: WalletInteractor - private let router: WalletRouter - private var disposeBag = Set() - - init(interactor: WalletInteractor, router: WalletRouter) { - defer { setupInitialState() } - self.interactor = interactor - self.router = router - } - - func didPastePairingURI() { - guard let string = UIPasteboard.general.string, let uri = WalletConnectURI(string: string) else { return } - print(uri) - pair(uri: uri) - } - - func didScanPairingURI() { - router.presentScan { [unowned self] value in - guard let uri = WalletConnectURI(string: value) else { return } - self.pair(uri: uri) - self.router.dismiss() - } onError: { error in - print(error.localizedDescription) - self.router.dismiss() - } - } -} - -// MARK: SceneViewModel - -extension WalletPresenter: SceneViewModel { - - var sceneTitle: String? { - return "Wallet" - } - - var largeTitleDisplayMode: UINavigationItem.LargeTitleDisplayMode { - return .always - } -} - -// MARK: Privates - -private extension WalletPresenter { - - func setupInitialState() { - interactor.requestPublisher.sink { [unowned self] request in - self.router.present(request: request) - }.store(in: &disposeBag) - } - - func pair(uri: WalletConnectURI) { - Task(priority: .high) { [unowned self] in - try await self.interactor.pair(uri: uri) - } - } -} diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletView.swift b/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletView.swift deleted file mode 100644 index e9469e4b6..000000000 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletView.swift +++ /dev/null @@ -1,46 +0,0 @@ -import SwiftUI - -struct WalletView: View { - - @EnvironmentObject var presenter: WalletPresenter - - var body: some View { - VStack(spacing: 16) { - Button(action: { presenter.didPastePairingURI() }, label: { - HStack(spacing: 8.0) { - Text("Paste pairing URI") - .foregroundColor(.w_foreground) - .font(.system(size: 18, weight: .semibold)) - } - .padding(.trailing, 8.0) - }) - .frame(width: 200, height: 44) - .background( - Capsule() - .foregroundColor(.w_greenForground) - ) - - Button(action: { presenter.didScanPairingURI() }, label: { - HStack(spacing: 8.0) { - Text("Scan pairing URI") - .foregroundColor(.w_foreground) - .font(.system(size: 18, weight: .semibold)) - } - .padding(.trailing, 8.0) - }) - .frame(width: 200, height: 44) - .background( - Capsule() - .foregroundColor(.w_purpleForeground) - ) - } - } -} - -#if DEBUG -struct WalletView_Previews: PreviewProvider { - static var previews: some View { - WalletView() - } -} -#endif diff --git a/Example/Showcase/Common/Extensions/UIKit/UIViewController.swift b/Example/Showcase/Common/Extensions/UIKit/UIViewController.swift index 89cacb640..e55dbb821 100644 --- a/Example/Showcase/Common/Extensions/UIKit/UIViewController.swift +++ b/Example/Showcase/Common/Extensions/UIKit/UIViewController.swift @@ -1,9 +1,7 @@ import UIKit import SwiftUI -import StoreKit extension UIViewController { - var topController: UIViewController { var topController = self while let presentedViewController = topController.presentedViewController { @@ -44,7 +42,6 @@ extension UIViewController { } extension UIApplication { - static var currentWindow: UIWindow { return UIApplication.shared.connectedScenes .compactMap { $0.delegate as? SceneDelegate } diff --git a/Example/Showcase/Common/InputConfig.swift b/Example/Showcase/Common/InputConfig.swift index 53931721a..bfbb51956 100644 --- a/Example/Showcase/Common/InputConfig.swift +++ b/Example/Showcase/Common/InputConfig.swift @@ -5,6 +5,10 @@ struct InputConfig { static var projectId: String { return config(for: "PROJECT_ID")! } + + static var relayHost: String { + return config(for: "RELAY_HOST")! + } private static func config(for key: String) -> String? { return Bundle.main.object(forInfoDictionaryKey: key) as? String diff --git a/Example/Showcase/Other/Info.plist b/Example/Showcase/Other/Info.plist index 2b842100f..136371e1c 100644 --- a/Example/Showcase/Other/Info.plist +++ b/Example/Showcase/Other/Info.plist @@ -4,6 +4,8 @@ PROJECT_ID $(PROJECT_ID) + RELAY_HOST + $(RELAY_HOST) CFBundleIconName AppIcon CFBundleURLTypes diff --git a/Example/WalletApp/ApplicationLayer/AppDelegate.swift b/Example/WalletApp/ApplicationLayer/AppDelegate.swift new file mode 100644 index 000000000..821a8f719 --- /dev/null +++ b/Example/WalletApp/ApplicationLayer/AppDelegate.swift @@ -0,0 +1,18 @@ +import UIKit + +@main +final class AppDelegate: UIResponder, UIApplicationDelegate { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + let sceneConfig: UISceneConfiguration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role) + sceneConfig.delegateClass = SceneDelegate.self + return sceneConfig + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {} +} diff --git a/Example/WalletApp/ApplicationLayer/Application.swift b/Example/WalletApp/ApplicationLayer/Application.swift new file mode 100644 index 000000000..97fc2aaf6 --- /dev/null +++ b/Example/WalletApp/ApplicationLayer/Application.swift @@ -0,0 +1,6 @@ +import Foundation +import WalletConnectChat + +final class Application { + var uri: String? +} diff --git a/Example/WalletApp/ApplicationLayer/Configurator/AppearanceConfigurator.swift b/Example/WalletApp/ApplicationLayer/Configurator/AppearanceConfigurator.swift new file mode 100644 index 000000000..793e9a835 --- /dev/null +++ b/Example/WalletApp/ApplicationLayer/Configurator/AppearanceConfigurator.swift @@ -0,0 +1,17 @@ +import UIKit + +struct AppearanceConfigurator: Configurator { + + func configure() { + let appearance = UINavigationBarAppearance() + appearance.backgroundColor = .w_background + appearance.shadowColor = .clear + appearance.titleTextAttributes = [ + .foregroundColor: UIColor.w_foreground + ] + + UINavigationBar.appearance().standardAppearance = appearance + UINavigationBar.appearance().scrollEdgeAppearance = appearance + UINavigationBar.appearance().compactAppearance = appearance + } +} diff --git a/Example/WalletApp/ApplicationLayer/Configurator/ApplicationConfigurator.swift b/Example/WalletApp/ApplicationLayer/Configurator/ApplicationConfigurator.swift new file mode 100644 index 000000000..810260eef --- /dev/null +++ b/Example/WalletApp/ApplicationLayer/Configurator/ApplicationConfigurator.swift @@ -0,0 +1,16 @@ +import Combine + +struct ApplicationConfigurator: Configurator { + + private var publishers = Set() + + private let app: Application + + init(app: Application) { + self.app = app + } + + func configure() { + WelcomeModule.create(app: app).present() + } +} diff --git a/Example/WalletApp/ApplicationLayer/Configurator/Configurator.swift b/Example/WalletApp/ApplicationLayer/Configurator/Configurator.swift new file mode 100644 index 000000000..2eb6d30cb --- /dev/null +++ b/Example/WalletApp/ApplicationLayer/Configurator/Configurator.swift @@ -0,0 +1,9 @@ +protocol Configurator { + func configure() +} + +extension Array where Element == Configurator { + func configure() { + forEach { $0.configure() } + } +} diff --git a/Example/WalletApp/ApplicationLayer/Configurator/MigrationConfigurator.swift b/Example/WalletApp/ApplicationLayer/Configurator/MigrationConfigurator.swift new file mode 100644 index 000000000..db8d18c9e --- /dev/null +++ b/Example/WalletApp/ApplicationLayer/Configurator/MigrationConfigurator.swift @@ -0,0 +1,9 @@ +struct MigrationConfigurator: Configurator { + let app: Application + + init(app: Application) { + self.app = app + } + + func configure() {} +} diff --git a/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift new file mode 100644 index 000000000..25279daaa --- /dev/null +++ b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift @@ -0,0 +1,17 @@ +import WalletConnectNetworking +import Web3Wallet + +struct ThirdPartyConfigurator: Configurator { + func configure() { + Networking.configure(projectId: InputConfig.projectId, socketFactory: DefaultSocketFactory()) + + let metadata = AppMetadata( + name: "Example Wallet", + description: "wallet description", + url: "example.wallet", + icons: ["https://avatars.githubusercontent.com/u/37784886"] + ) + + Web3Wallet.configure(metadata: metadata, signerFactory: DefaultSignerFactory()) + } +} diff --git a/Example/WalletApp/ApplicationLayer/SceneDelegate.swift b/Example/WalletApp/ApplicationLayer/SceneDelegate.swift new file mode 100644 index 000000000..1fa5738e2 --- /dev/null +++ b/Example/WalletApp/ApplicationLayer/SceneDelegate.swift @@ -0,0 +1,44 @@ +import UIKit +import Auth +import WalletConnectPairing + +final class SceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? + + private let app = Application() + + private var configurators: [Configurator] { + return [ + MigrationConfigurator(app: app), + ThirdPartyConfigurator(), + ApplicationConfigurator(app: app), + AppearanceConfigurator() + ] + } + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + let sceneConfig: UISceneConfiguration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role) + sceneConfig.delegateClass = SceneDelegate.self + return sceneConfig + } + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + guard let windowScene = (scene as? UIWindowScene) else { return } + + window = UIWindow(windowScene: windowScene) + window?.makeKeyAndVisible() + + app.uri = connectionOptions.urlContexts.first?.url.absoluteString.replacingOccurrences(of: "walletapp://wc?uri=", with: "") + + configurators.configure() + } + + func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { + guard let context = URLContexts.first else { return } + + let uri = context.url.absoluteString.replacingOccurrences(of: "walletapp://wc?uri=", with: "") + Task { + try await Pair.instance.pair(uri: WalletConnectURI(string: uri)!) + } + } +} diff --git a/Example/WalletApp/Common/Extensions/SwiftUI/View.swift b/Example/WalletApp/Common/Extensions/SwiftUI/View.swift new file mode 100644 index 000000000..eb830798d --- /dev/null +++ b/Example/WalletApp/Common/Extensions/SwiftUI/View.swift @@ -0,0 +1,17 @@ +import SwiftUI + +extension View { + func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View { + clipShape( RoundedCorner(radius: radius, corners: corners) ) + } +} + +struct RoundedCorner: Shape { + let radius: CGFloat + let corners: UIRectCorner + + func path(in rect: CGRect) -> Path { + let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius)) + return Path(path.cgPath) + } +} diff --git a/Example/WalletApp/Common/Extensions/UIKit/String.swift b/Example/WalletApp/Common/Extensions/UIKit/String.swift new file mode 100644 index 000000000..32161cd7a --- /dev/null +++ b/Example/WalletApp/Common/Extensions/UIKit/String.swift @@ -0,0 +1,8 @@ +import Foundation + +extension String { + + static var empty: String { + return "" + } +} diff --git a/Example/WalletApp/Common/Extensions/UIKit/UIColor.swift b/Example/WalletApp/Common/Extensions/UIKit/UIColor.swift new file mode 100644 index 000000000..1f175e66e --- /dev/null +++ b/Example/WalletApp/Common/Extensions/UIKit/UIColor.swift @@ -0,0 +1,20 @@ +import UIKit + +extension UIColor { + + convenience init(red: Int, green: Int, blue: Int) { + assert(red >= 0 && red <= 255, "Invalid red component") + assert(green >= 0 && green <= 255, "Invalid green component") + assert(blue >= 0 && blue <= 255, "Invalid blue component") + + self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0) + } + + convenience init(rgb: Int) { + self.init( + red: (rgb >> 16) & 0xFF, + green: (rgb >> 8) & 0xFF, + blue: rgb & 0xFF + ) + } +} diff --git a/Example/WalletApp/Common/Extensions/UIKit/UIViewController.swift b/Example/WalletApp/Common/Extensions/UIKit/UIViewController.swift new file mode 100644 index 000000000..c058d9ef6 --- /dev/null +++ b/Example/WalletApp/Common/Extensions/UIKit/UIViewController.swift @@ -0,0 +1,59 @@ +import UIKit +import SwiftUI +import StoreKit + +extension UIViewController { + var topController: UIViewController { + var topController = self + while let presentedViewController = topController.presentedViewController { + topController = presentedViewController + } + return topController + } + + func present() { + UIApplication.currentWindow.rootViewController = self + } + + func push(from viewController: UIViewController) { + viewController.navigationController?.pushViewController(self, animated: true) + } + + func present(from viewController: UIViewController) { + viewController.present(self, animated: true, completion: nil) + } + + func presentFullScreen(from viewController: UIViewController, transparentBackground: Bool = false) { + if transparentBackground { + view.backgroundColor = .clear + } + modalPresentationStyle = .overCurrentContext + viewController.present(self, animated: true, completion: nil) + } + + func pop() { + _ = navigationController?.popViewController(animated: true) + } + + func dismiss() { + dismiss(animated: true, completion: nil) + } + + func popToRoot() { + navigationController?.popToRootViewController(animated: true) + } + + func wrapToNavigationController() -> UINavigationController { + let navigationController = UINavigationController(rootViewController: self) + navigationController.navigationBar.prefersLargeTitles = true + return navigationController + } +} + +extension UIApplication { + static var currentWindow: UIWindow { + return UIApplication.shared.connectedScenes + .compactMap { $0.delegate as? SceneDelegate } + .first!.window! + } +} diff --git a/Example/WalletApp/Common/Helpers/TagsView.swift b/Example/WalletApp/Common/Helpers/TagsView.swift new file mode 100644 index 000000000..5e53329cd --- /dev/null +++ b/Example/WalletApp/Common/Helpers/TagsView.swift @@ -0,0 +1,105 @@ +import SwiftUI + +private struct HeightPreferenceKey: PreferenceKey { + static func reduce(value _: inout CGFloat, nextValue _: () -> CGFloat) {} + static var defaultValue: CGFloat = 0 +} + +private struct HeightReaderView: View { + @Binding var binding: CGFloat + + var body: some View { + GeometryReader { geo in + Color.clear + .preference(key: HeightPreferenceKey.self, value: geo.frame(in: .local).size.height) + } + .onPreferenceChange(HeightPreferenceKey.self) { h in + binding = h + } + } +} + +public let tagsViewDefaultItemSpacing: CGFloat = 4 + +public struct TagsView: View { + @Binding var binding: RefreshBinding + let items: [Data] + let itemSpacing: CGFloat + @ViewBuilder let viewMapping: (Data) -> ItemView + + @State private var totalHeight: CGFloat + + public init( + binding: Binding, + items: [Data], + itemSpacing: CGFloat = tagsViewDefaultItemSpacing, + @ViewBuilder viewMapping: @escaping (Data) -> ItemView + ) { + _binding = binding + self.items = items + self.itemSpacing = itemSpacing + self.viewMapping = viewMapping + _totalHeight = State(initialValue: .zero) + } + + public var body: some View { + let stack = VStack { + GeometryReader { geometry in + self.content(in: geometry) + } + } + return Group { + stack.frame(height: totalHeight) + } + } + + private func content(in geometry: GeometryProxy) -> some View { + var width = CGFloat.zero + var height = CGFloat.zero + var lastHeight = CGFloat.zero + let itemCount = items.count + return ZStack(alignment: .topLeading) { + ForEach(Array(items.enumerated()), id: \.offset) { index, item in + viewMapping(item) + .padding([.horizontal, .vertical], itemSpacing) + .alignmentGuide(.leading, computeValue: { d in + if (abs(width - d.width) > geometry.size.width) { + width = 0 + height -= lastHeight + } + lastHeight = d.height + let result = width + if index == itemCount - 1 { + width = 0 + } else { + width -= d.width + } + return result + }) + .alignmentGuide(.top, computeValue: { d in + let result = height + if index == itemCount - 1 { + height = 0 + } + return result + }) + } + } + .background(HeightReaderView(binding: $totalHeight)) + } +} + +public extension TagsView where RefreshBinding == Never? { + init( + items: [Data], + itemSpacing: CGFloat = tagsViewDefaultItemSpacing, + @ViewBuilder viewMapping: @escaping (Data) -> ItemView + ) { + self.init( + binding: .constant(nil), + items: items, + itemSpacing: itemSpacing, + viewMapping: viewMapping + ) + } +} diff --git a/Example/WalletApp/Common/Helpers/UIPasteboardWrapper.swift b/Example/WalletApp/Common/Helpers/UIPasteboardWrapper.swift new file mode 100644 index 000000000..27820ea54 --- /dev/null +++ b/Example/WalletApp/Common/Helpers/UIPasteboardWrapper.swift @@ -0,0 +1,8 @@ +import Foundation +import UIKit + +struct UIPasteboardWrapper { + static var string: String? { + UIPasteboard.general.string + } +} diff --git a/Example/WalletApp/Common/InputConfig.swift b/Example/WalletApp/Common/InputConfig.swift new file mode 100644 index 000000000..1a4e505cf --- /dev/null +++ b/Example/WalletApp/Common/InputConfig.swift @@ -0,0 +1,11 @@ +import Foundation + +struct InputConfig { + static var projectId: String { + return config(for: "PROJECT_ID")! + } + + private static func config(for key: String) -> String? { + return Bundle.main.object(forInfoDictionaryKey: key) as? String + } +} diff --git a/Example/WalletApp/Common/Style/Color.swift b/Example/WalletApp/Common/Style/Color.swift new file mode 100644 index 000000000..b88f03e98 --- /dev/null +++ b/Example/WalletApp/Common/Style/Color.swift @@ -0,0 +1,36 @@ +import SwiftUI + +extension Color { + static let blue100 = Color("blue100") + static let blue200 = Color("blue200") + static let cyanBackround = Color("cyan-background") + static let translucentBackround = Color("translucent-background") + static let whiteBackground = Color("white-background") + static let lightBackground = Color("light-background") + static let grey8 = Color("grey8") + static let grey50 = Color("grey50") + static let grey70 = Color("grey70") + static let grey95 = Color("grey95") + static let grey100 = Color("grey100") + static let lightBlue = Color("light-blue") + static let lightForegroundNegative = Color("light-foreground-negative") + static let foregroundNegative = Color("foreground-negative") + static let lightForegroundPositive = Color("light-foreground-positive") + static let foregroundPositive = Color("foreground-positive") + static let systemGrayLight = Color("system-gray-light") +} + +extension UIColor { + static let w_background = UIColor(named: "grey100")! + static let w_secondaryBackground: UIColor = UIColor(rgb: 0x272A2A) + static let w_tertiaryBackground: UIColor = UIColor(rgb: 0x3B4040) + + static let w_foreground: UIColor = UIColor.label + static let w_secondaryForeground: UIColor = UIColor(rgb: 0x9EA9A9) + + static let w_purpleBackground: UIColor = UIColor(rgb: 0x794CFF) + static let w_purpleForeground: UIColor = UIColor(rgb: 0x987DE8) + + static let w_greenBackground: UIColor = UIColor(rgb: 0x1B3229) + static let w_greenForground: UIColor = UIColor(rgb: 0x2BEE6C) +} diff --git a/Example/WalletApp/Common/Types/Types.swift b/Example/WalletApp/Common/Types/Types.swift new file mode 100644 index 000000000..3df10ee8a --- /dev/null +++ b/Example/WalletApp/Common/Types/Types.swift @@ -0,0 +1,3 @@ +import WalletConnectUtils + +typealias Account = WalletConnectUtils.Account diff --git a/Example/WalletApp/Common/VIPER/SceneViewController.swift b/Example/WalletApp/Common/VIPER/SceneViewController.swift new file mode 100644 index 000000000..0c990baf7 --- /dev/null +++ b/Example/WalletApp/Common/VIPER/SceneViewController.swift @@ -0,0 +1,87 @@ +import SwiftUI + +enum NavigationBarStyle { + case translucent(UIColor) +} + +protocol SceneViewModel { + var sceneTitle: String? { get } + var largeTitleDisplayMode: UINavigationItem.LargeTitleDisplayMode { get } + var leftBarButtonItem: UIBarButtonItem? { get } + var rightBarButtonItem: UIBarButtonItem? { get } + var navigationBarStyle: NavigationBarStyle { get } + var preferredStatusBarStyle: UIStatusBarStyle { get } + var isNavigationBarTranslucent: Bool { get } + +} + +extension SceneViewModel { + var sceneTitle: String? { + return nil + } + var largeTitleDisplayMode: UINavigationItem.LargeTitleDisplayMode { + return .never + } + var leftBarButtonItem: UIBarButtonItem? { + return .none + } + var rightBarButtonItem: UIBarButtonItem? { + return .none + } + var navigationBarStyle: NavigationBarStyle { + return .translucent(.w_background) + } + var preferredStatusBarStyle: UIStatusBarStyle { + return .default + } + var isNavigationBarTranslucent: Bool { + return true + } +} + +class SceneViewController: UIHostingController { + private let viewModel: ViewModel + + init(viewModel: ViewModel, content: Content) { + self.viewModel = viewModel + super.init(rootView: content) + } + + override var preferredStatusBarStyle: UIStatusBarStyle { + return viewModel.preferredStatusBarStyle + } + + override func viewDidLoad() { + super.viewDidLoad() + setupView() + setupNavigation() + setupNavigationBarStyle() + } + + @objc required dynamic init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +// MARK: Privates +private extension SceneViewController { + func setupView() { + view.backgroundColor = .w_background + } + + func setupNavigation() { + navigationItem.title = viewModel.sceneTitle + navigationItem.backButtonTitle = .empty + navigationItem.largeTitleDisplayMode = viewModel.largeTitleDisplayMode + navigationItem.rightBarButtonItem = viewModel.rightBarButtonItem + navigationItem.leftBarButtonItem = viewModel.leftBarButtonItem + } + + func setupNavigationBarStyle() { + switch viewModel.navigationBarStyle { + case .translucent(let color): + navigationController?.navigationBar.barTintColor = color + navigationController?.navigationBar.isTranslucent = true + } + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/AccentColor.colorset/Contents.json b/Example/WalletApp/Other/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 000000000..eb8789700 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..78d34c2c3 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "filename" : "Icon-App-20x20@2x.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "filename" : "Icon-App-20x20@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "filename" : "Icon-App-29x29@2x.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "filename" : "Icon-App-29x29@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "filename" : "Icon-App-40x40@2x.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "filename" : "Icon-App-40x40@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "filename" : "Icon-App-60x60@2x.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "filename" : "Icon-App-60x60@3x.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "filename" : "Icon-App-20x20@1x.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "filename" : "Icon-App-20x20@2x-1.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "filename" : "Icon-App-29x29@1x.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "filename" : "Icon-App-29x29@2x-1.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "filename" : "Icon-App-40x40@1x.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "filename" : "Icon-App-40x40@2x-1.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "filename" : "Icon-App-76x76@1x.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "filename" : "Icon-App-76x76@2x.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "filename" : "Icon-App-83.5x83.5@2x.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "filename" : "ItunesArtwork@2x.png", + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 000000000..e8b3b928c Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png new file mode 100644 index 000000000..7f3a702c3 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x-1.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 000000000..7f3a702c3 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 000000000..d38db763f Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 000000000..941819fce Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png new file mode 100644 index 000000000..d71e54b8d Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x-1.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 000000000..d71e54b8d Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 000000000..dd60b860b Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 000000000..7f3a702c3 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png new file mode 100644 index 000000000..5c0665582 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x-1.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 000000000..5c0665582 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 000000000..0fdab5f95 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 000000000..0fdab5f95 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 000000000..3b88e179c Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 000000000..d0c9a1a98 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 000000000..03bb3d021 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 000000000..fd505b567 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png new file mode 100644 index 000000000..f527fe624 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png differ diff --git a/Example/WalletApp/Other/Assets.xcassets/Contents.json b/Example/WalletApp/Other/Assets.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/connect-template.imageset/Contents.json b/Example/WalletApp/Other/Assets.xcassets/connect-template.imageset/Contents.json new file mode 100644 index 000000000..b087841d7 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/connect-template.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "connect-template.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/connect-template.imageset/connect-template.svg b/Example/WalletApp/Other/Assets.xcassets/connect-template.imageset/connect-template.svg new file mode 100644 index 000000000..6295dcc53 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/connect-template.imageset/connect-template.svg @@ -0,0 +1,3 @@ + + + diff --git a/Example/WalletApp/Other/Assets.xcassets/copy.imageset/Contents.json b/Example/WalletApp/Other/Assets.xcassets/copy.imageset/Contents.json new file mode 100644 index 000000000..4a7bb95ea --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/copy.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "copy.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/copy.imageset/copy.svg b/Example/WalletApp/Other/Assets.xcassets/copy.imageset/copy.svg new file mode 100644 index 000000000..7988f4062 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/copy.imageset/copy.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/WalletApp/Other/Assets.xcassets/forward-shevron.imageset/Contents.json b/Example/WalletApp/Other/Assets.xcassets/forward-shevron.imageset/Contents.json new file mode 100644 index 000000000..92c5c6bf6 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/forward-shevron.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "forward-shevron.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/forward-shevron.imageset/forward-shevron.svg b/Example/WalletApp/Other/Assets.xcassets/forward-shevron.imageset/forward-shevron.svg new file mode 100644 index 000000000..51ca50897 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/forward-shevron.imageset/forward-shevron.svg @@ -0,0 +1,3 @@ + + + diff --git a/Example/WalletApp/Other/Assets.xcassets/foundation.imageset/Contents.json b/Example/WalletApp/Other/Assets.xcassets/foundation.imageset/Contents.json new file mode 100644 index 000000000..42d7ff857 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/foundation.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "foundation.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/foundation.imageset/foundation.svg b/Example/WalletApp/Other/Assets.xcassets/foundation.imageset/foundation.svg new file mode 100644 index 000000000..d5568fe23 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/foundation.imageset/foundation.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/Example/WalletApp/Other/Assets.xcassets/header.imageset/Contents.json b/Example/WalletApp/Other/Assets.xcassets/header.imageset/Contents.json new file mode 100644 index 000000000..53a334d2d --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/header.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Visual.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/header.imageset/Visual.svg b/Example/WalletApp/Other/Assets.xcassets/header.imageset/Visual.svg new file mode 100644 index 000000000..08290c2ae --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/header.imageset/Visual.svg @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/WalletApp/Other/Assets.xcassets/scan.imageset/Contents.json b/Example/WalletApp/Other/Assets.xcassets/scan.imageset/Contents.json new file mode 100644 index 000000000..653102307 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/scan.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "scan.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/scan.imageset/scan.svg b/Example/WalletApp/Other/Assets.xcassets/scan.imageset/scan.svg new file mode 100644 index 000000000..9f5649d72 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/scan.imageset/scan.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/WalletApp/Other/Colors.xcassets/Contents.json b/Example/WalletApp/Other/Colors.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/blue100.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/blue100.colorset/Contents.json new file mode 100644 index 000000000..241e42995 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/blue100.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "255", + "green" : "150", + "red" : "51" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0x96", + "red" : "0x33" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/blue200.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/blue200.colorset/Contents.json new file mode 100644 index 000000000..437b9e3f0 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/blue200.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "242", + "green" : "125", + "red" : "13" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.949", + "green" : "0.490", + "red" : "0.051" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/cyan-background.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/cyan-background.colorset/Contents.json new file mode 100644 index 000000000..c3e520b1d --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/cyan-background.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE5", + "green" : "0xAC", + "red" : "0x00" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xC6", + "red" : "0x1A" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/foreground-negative.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/foreground-negative.colorset/Contents.json new file mode 100644 index 000000000..5fef43462 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/foreground-negative.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "103", + "green" : "90", + "red" : "242" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "103", + "green" : "90", + "red" : "242" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/foreground-positive.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/foreground-positive.colorset/Contents.json new file mode 100644 index 000000000..0e8a8da41 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/foreground-positive.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "108", + "green" : "238", + "red" : "43" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0.424", + "green" : "0.933", + "red" : "0.169" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/grey100.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/grey100.colorset/Contents.json new file mode 100644 index 000000000..ee2f44f71 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/grey100.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xFF", + "green" : "0xFF", + "red" : "0xFF" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x14", + "green" : "0x14", + "red" : "0x14" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/grey50.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/grey50.colorset/Contents.json new file mode 100644 index 000000000..ec37b029c --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/grey50.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x86", + "green" : "0x86", + "red" : "0x79" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x86", + "green" : "0x86", + "red" : "0x79" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/grey70.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/grey70.colorset/Contents.json new file mode 100644 index 000000000..066fa92e6 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/grey70.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xA9", + "green" : "0xA9", + "red" : "0x9E" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x86", + "green" : "0x86", + "red" : "0x79" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/grey8.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/grey8.colorset/Contents.json new file mode 100644 index 000000000..3142df2de --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/grey8.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x14", + "green" : "0x14", + "red" : "0x14" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE7", + "green" : "0xE7", + "red" : "0xE4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/grey95.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/grey95.colorset/Contents.json new file mode 100644 index 000000000..c32b826d0 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/grey95.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF3", + "green" : "0xF3", + "red" : "0xF1" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x2A", + "green" : "0x2A", + "red" : "0x27" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/light-background.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/light-background.colorset/Contents.json new file mode 100644 index 000000000..7db3262ea --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/light-background.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "230", + "green" : "226", + "red" : "226" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "44", + "green" : "42", + "red" : "42" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/light-blue.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/light-blue.colorset/Contents.json new file mode 100644 index 000000000..914293344 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/light-blue.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xF8", + "green" : "0xF1", + "red" : "0xDD" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x47", + "green" : "0x3B", + "red" : "0x15" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/light-foreground-negative.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/light-foreground-negative.colorset/Contents.json new file mode 100644 index 000000000..5dd72bea9 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/light-foreground-negative.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "66", + "green" : "81", + "red" : "240" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "103", + "green" : "90", + "red" : "242" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/light-foreground-positive.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/light-foreground-positive.colorset/Contents.json new file mode 100644 index 000000000..f06599e88 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/light-foreground-positive.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "86", + "green" : "201", + "red" : "29" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "86", + "green" : "201", + "red" : "29" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/system-gray-light.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/system-gray-light.colorset/Contents.json new file mode 100644 index 000000000..2312e4873 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/system-gray-light.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x93", + "green" : "0x8E", + "red" : "0x8E" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x93", + "green" : "0x8E", + "red" : "0x8E" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Colors.xcassets/white-background.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/white-background.colorset/Contents.json new file mode 100644 index 000000000..0ba907fa8 --- /dev/null +++ b/Example/WalletApp/Other/Colors.xcassets/white-background.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "255", + "green" : "255", + "red" : "255" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "30", + "green" : "28", + "red" : "28" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Info.plist b/Example/WalletApp/Other/Info.plist new file mode 100644 index 000000000..ef9e6d46f --- /dev/null +++ b/Example/WalletApp/Other/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleIconName + AppIcon + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + walletapp + + + + ITSAppUsesNonExemptEncryption + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + PROJECT_ID + $(PROJECT_ID) + NSCameraUsageDescription + Camera access for scanning QR code + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + + diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift similarity index 75% rename from Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift rename to Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift index 816d0b398..361d0b8fe 100644 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestInteractor.swift @@ -1,9 +1,7 @@ import Foundation -import Auth -import WalletConnectUtils +import Web3Wallet final class AuthRequestInteractor { - private let signer = MessageSignerFactory(signerFactory: DefaultSignerFactory()).create() private let account = Account("eip155:1:0xe5EeF1368781911d265fDB6946613dA61915a501")! @@ -14,15 +12,15 @@ final class AuthRequestInteractor { address: account.address, privateKey: privateKey, type: .eip191) - try await Auth.instance.respond(requestId: request.id, signature: signature, from: account) + try await Web3Wallet.instance.respond(requestId: request.id, signature: signature, from: account) } func reject(request: AuthRequest) async throws { - try await Auth.instance.reject(requestId: request.id) + try await Web3Wallet.instance.reject(requestId: request.id) } func formatted(request: AuthRequest) -> String { - return try! Auth.instance.formatMessage( + return try! Web3Wallet.instance.formatMessage( payload: request.payload, address: account.address ) diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestModule.swift b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestModule.swift similarity index 80% rename from Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestModule.swift rename to Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestModule.swift index 230e05bbc..484e7d354 100644 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestModule.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestModule.swift @@ -1,13 +1,12 @@ import SwiftUI -import Auth +import Web3Wallet final class AuthRequestModule { - @discardableResult static func create(app: Application, request: AuthRequest) -> UIViewController { let router = AuthRequestRouter(app: app) let interactor = AuthRequestInteractor() - let presenter = AuthRequestPresenter(request: request, interactor: interactor, router: router) + let presenter = AuthRequestPresenter(interactor: interactor, router: router, request: request) let view = AuthRequestView().environmentObject(presenter) let viewController = SceneViewController(viewModel: presenter, content: view) @@ -15,5 +14,4 @@ final class AuthRequestModule { return viewController } - } diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestPresenter.swift similarity index 64% rename from Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestPresenter.swift rename to Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestPresenter.swift index 3aece0e97..56d11f511 100644 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestPresenter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestPresenter.swift @@ -1,56 +1,52 @@ import UIKit import Combine -import Auth -final class AuthRequestPresenter: ObservableObject { +import Web3Wallet - private let request: AuthRequest +final class AuthRequestPresenter: ObservableObject { private let interactor: AuthRequestInteractor private let router: AuthRequestRouter + + let request: AuthRequest + + var message: String { + return interactor.formatted(request: request) + } + private var disposeBag = Set() - init(request: AuthRequest, interactor: AuthRequestInteractor, router: AuthRequestRouter) { + init( + interactor: AuthRequestInteractor, + router: AuthRequestRouter, + request: AuthRequest + ) { defer { setupInitialState() } - self.request = request self.interactor = interactor self.router = router - } - - var message: String { - return interactor.formatted(request: request) + self.request = request } @MainActor - func approvePressed() async throws { + func onApprove() async throws { try await interactor.approve(request: request) router.dismiss() } @MainActor - func rejectPressed() async throws { + func onReject() async throws { try await interactor.reject(request: request) router.dismiss() } } -// MARK: SceneViewModel - -extension AuthRequestPresenter: SceneViewModel { - - var sceneTitle: String? { - return "Auth Request" - } +// MARK: - Private functions +private extension AuthRequestPresenter { + func setupInitialState() { - var largeTitleDisplayMode: UINavigationItem.LargeTitleDisplayMode { - return .always } } -// MARK: Privates - -private extension AuthRequestPresenter { - - func setupInitialState() { +// MARK: - SceneViewModel +extension AuthRequestPresenter: SceneViewModel { - } } diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestRouter.swift similarity index 68% rename from Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestRouter.swift rename to Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestRouter.swift index 53d3d684e..76e35da11 100644 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/AuthRequest/AuthRequestRouter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestRouter.swift @@ -1,7 +1,6 @@ import UIKit final class AuthRequestRouter { - weak var viewController: UIViewController! private let app: Application @@ -9,8 +8,9 @@ final class AuthRequestRouter { init(app: Application) { self.app = app } - + func dismiss() { - viewController.navigationController?.dismiss() + viewController.dismiss() + UIApplication.shared.open(URL(string: "showcase://")!) } } diff --git a/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestView.swift b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestView.swift new file mode 100644 index 000000000..93a602fb2 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestView.swift @@ -0,0 +1,139 @@ +import SwiftUI + +struct AuthRequestView: View { + @EnvironmentObject var presenter: AuthRequestPresenter + + @State var text = "" + + var body: some View { + ZStack { + Color.black.opacity(0.6) + + VStack { + Spacer() + + VStack(spacing: 0) { + Image("header") + .resizable() + .scaledToFit() + + Text(presenter.request.payload.domain) + .foregroundColor(.grey8) + .font(.system(size: 22, weight: .bold, design: .rounded)) + .padding(.top, 10) + + Text("would like to connect") + .foregroundColor(.grey8) + .font(.system(size: 22, weight: .medium, design: .rounded)) + + Text(presenter.request.payload.domain) + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + .multilineTextAlignment(.center) + .lineSpacing(4) + .padding(.top, 8) + + authRequestView() + + HStack(spacing: 20) { + Button { + Task(priority: .userInitiated) { try await + presenter.onReject() + } + } label: { + Text("Decline") + .frame(maxWidth: .infinity) + .foregroundColor(.white) + .font(.system(size: 20, weight: .semibold, design: .rounded)) + .padding(.vertical, 11) + .background( + LinearGradient( + gradient: Gradient(colors: [ + .foregroundNegative, + .lightForegroundNegative + ]), + startPoint: .top, endPoint: .bottom) + ) + .cornerRadius(20) + } + .shadow(color: .white.opacity(0.25), radius: 8, y: 2) + + Button { + Task(priority: .userInitiated) { try await + presenter.onApprove() + } + } label: { + Text("Allow") + .frame(maxWidth: .infinity) + .foregroundColor(.white) + .font(.system(size: 20, weight: .semibold, design: .rounded)) + .padding(.vertical, 11) + .background( + LinearGradient( + gradient: Gradient(colors: [ + .foregroundPositive, + .lightForegroundPositive + ]), + startPoint: .top, endPoint: .bottom) + ) + .cornerRadius(20) + } + .shadow(color: .white.opacity(0.25), radius: 8, y: 2) + } + .padding(.top, 25) + } + .padding(20) + .background(.ultraThinMaterial) + .cornerRadius(34) + .padding(.horizontal, 10) + + Spacer() + } + } + .edgesIgnoringSafeArea(.all) + } + + private func authRequestView() -> some View { + VStack { + VStack(alignment: .leading) { + Text("Message") + .font(.system(size: 15, weight: .semibold, design: .rounded)) + .foregroundColor(.whiteBackground) + .padding(.horizontal, 8) + .padding(.vertical, 5) + .background(Color.grey70) + .cornerRadius(28, corners: .allCorners) + .padding(.leading, 15) + .padding(.top, 9) + + VStack(spacing: 0) { + HStack { + Text(presenter.message) + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + + Spacer() + } + .padding(.horizontal, 18) + .padding(.vertical, 10) + } + .background(Color.whiteBackground) + .cornerRadius(20, corners: .allCorners) + .padding(.horizontal, 5) + .padding(.bottom, 5) + + } + .background(.thinMaterial) + .cornerRadius(25, corners: .allCorners) + } + .padding(.top, 30) + } +} + +#if DEBUG +struct AuthRequestView_Previews: PreviewProvider { + static var previews: some View { + AuthRequestView() + } +} +#endif diff --git a/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsInteractor.swift new file mode 100644 index 000000000..c9fe17a65 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsInteractor.swift @@ -0,0 +1,17 @@ +import Combine + +import Web3Wallet + +final class ConnectionDetailsInteractor { + var requestPublisher: AnyPublisher { + return Web3Wallet.instance.authRequestPublisher + } + + func pair(uri: WalletConnectURI) async throws { + try await Web3Wallet.instance.pair(uri: uri) + } + + func disconnectSession(session: Session) async throws { + try await Web3Wallet.instance.disconnect(topic: session.topic) + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsModule.swift b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsModule.swift new file mode 100644 index 000000000..d42807d98 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsModule.swift @@ -0,0 +1,22 @@ +import SwiftUI + +import Web3Wallet + +final class ConnectionDetailsModule { + @discardableResult + static func create(app: Application, session: Session) -> UIViewController { + let router = ConnectionDetailsRouter(app: app) + let interactor = ConnectionDetailsInteractor() + let presenter = ConnectionDetailsPresenter( + interactor: interactor, + router: router, + session: session + ) + let view = ConnectionDetailsView().environmentObject(presenter) + let viewController = SceneViewController(viewModel: presenter, content: view) + + router.viewController = viewController + + return viewController + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsPresenter.swift new file mode 100644 index 000000000..335eed580 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsPresenter.swift @@ -0,0 +1,51 @@ +import UIKit +import Combine + +import Auth +import Web3Wallet + +final class ConnectionDetailsPresenter: ObservableObject { + private let interactor: ConnectionDetailsInteractor + private let router: ConnectionDetailsRouter + + let session: Session + + private var disposeBag = Set() + + init( + interactor: ConnectionDetailsInteractor, + router: ConnectionDetailsRouter, + session: Session + ) { + self.interactor = interactor + self.router = router + self.session = session + } + + func onDelete() { + Task { + do { + try await interactor.disconnectSession(session: session) + DispatchQueue.main.async { + self.router.dismiss() + } + } catch { + print(error) + } + } + } + + func accountReference(namespace: String) -> String { + "\(session.namespaces[namespace]?.accounts.first?.namespace ?? ""):\((session.namespaces[namespace]?.accounts.first?.reference ?? ""))" + } +} + +// MARK: - Private functions +private extension ConnectionDetailsPresenter { + +} + +// MARK: - SceneViewModel +extension ConnectionDetailsPresenter: SceneViewModel { + +} diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsRouter.swift similarity index 82% rename from Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletRouter.swift rename to Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsRouter.swift index 288f481f8..4dcf67cd1 100644 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletRouter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsRouter.swift @@ -1,8 +1,7 @@ import UIKit -import Auth - -final class WalletRouter { +import Web3Wallet +final class ConnectionDetailsRouter { weak var viewController: UIViewController! private let app: Application @@ -24,6 +23,6 @@ final class WalletRouter { } func dismiss() { - viewController.navigationController?.dismiss() + viewController.navigationController?.popViewController(animated: true) } } diff --git a/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsView.swift b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsView.swift new file mode 100644 index 000000000..ab82d18a3 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsView.swift @@ -0,0 +1,136 @@ +import SwiftUI + +struct ConnectionDetailsView: View { + @EnvironmentObject var presenter: ConnectionDetailsPresenter + + var body: some View { + ZStack { + Color.grey100 + .edgesIgnoringSafeArea(.all) + + ScrollView { + VStack(spacing: 0) { + VStack(spacing: 2) { + AsyncImage(url: URL(string: presenter.session.peer.icons.first ?? "")) { phase in + if let image = phase.image { + image + .resizable() + .frame(width: 60, height: 60) + .background(Color.black) + .cornerRadius(30, corners: .allCorners) + } else { + Color.black + .frame(width: 60, height: 60) + .cornerRadius(30, corners: .allCorners) + } + } + .padding(.bottom, 6) + + Text(presenter.session.peer.name) + .foregroundColor(.grey8) + .font(.system(size: 22, weight: .bold, design: .rounded)) + + Text(presenter.session.peer.url) + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .medium, design: .rounded)) + } + + ForEach(presenter.session.namespaces.keys.sorted(), id: \.self) { namespace in + VStack { + VStack(alignment: .leading) { + Text(namespace) + .font(.system(size: 15, weight: .semibold, design: .rounded)) + .foregroundColor(.whiteBackground) + .padding(.horizontal, 8) + .padding(.vertical, 5) + .background(Color.grey70) + .cornerRadius(28, corners: .allCorners) + .padding(.leading, 15) + .padding(.top, 9) + + VStack(spacing: 0) { + HStack { + Text("Accounts") + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + + Spacer() + } + .padding(.horizontal, 18) + .padding(.top, 10) + + HStack(spacing: 0) { + Text(presenter.accountReference(namespace: namespace)) + .foregroundColor(.cyanBackround) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + .padding(.horizontal, 8) + .padding(.vertical, 3) + .background(Color.cyanBackround.opacity(0.2)) + .cornerRadius(10, corners: .allCorners) + + Spacer() + } + .padding(10) + + } + .background(Color.whiteBackground) + .cornerRadius(20, corners: .allCorners) + .padding(.horizontal, 5) + + VStack(alignment: .leading, spacing: 0) { + HStack { + Text("Methods") + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + + Spacer() + } + .padding(.horizontal, 18) + .padding(.top, 10) + + TagsView(items: Array(presenter.session.namespaces[namespace]?.methods ?? [])) { + Text($0) + .foregroundColor(.cyanBackround) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + .padding(.horizontal, 8) + .padding(.vertical, 3) + .background(Color.cyanBackround.opacity(0.2)) + .cornerRadius(10, corners: .allCorners) + } + .padding(10) + } + .background(Color.whiteBackground) + .cornerRadius(20, corners: .allCorners) + .padding(.horizontal, 5) + .padding(.bottom, 5) + } + .background(Color("grey95")) + .cornerRadius(25, corners: .allCorners) + } + .padding(.horizontal, 20) + .padding(.top, 30) + } + + Button { + presenter.onDelete() + } label: { + Text("Delete") + .foregroundColor(.lightForegroundNegative) + .font(.system(size: 20, weight: .semibold, design: .rounded)) + } + .padding(.top, 20) + + Spacer() + } + } + } + } +} + +#if DEBUG +struct ConnectionDetailsView_Previews: PreviewProvider { + static var previews: some View { + ConnectionDetailsView() + } +} +#endif diff --git a/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriInteractor.swift new file mode 100644 index 000000000..a489ba4cb --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriInteractor.swift @@ -0,0 +1,3 @@ +final class PasteUriInteractor { + +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriModule.swift b/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriModule.swift new file mode 100644 index 000000000..1f425a710 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriModule.swift @@ -0,0 +1,25 @@ +import SwiftUI + +final class PasteUriModule { + @discardableResult + static func create( + app: Application, + onValue: @escaping (String) -> Void, + onError: @escaping (Error) -> Void + ) -> UIViewController { + let router = PasteUriRouter(app: app) + let interactor = PasteUriInteractor() + let presenter = PasteUriPresenter( + interactor: interactor, + router: router, + onValue: onValue, + onError: onError + ) + let view = PasteUriView().environmentObject(presenter) + let viewController = SceneViewController(viewModel: presenter, content: view) + + router.viewController = viewController + + return viewController + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriPresenter.swift new file mode 100644 index 000000000..cf011016b --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriPresenter.swift @@ -0,0 +1,38 @@ +import UIKit +import Combine + +final class PasteUriPresenter: ObservableObject { + private let interactor: PasteUriInteractor + private let router: PasteUriRouter + private var disposeBag = Set() + + let onValue: (String) -> Void + let onError: (Error) -> Void + + init( + interactor: PasteUriInteractor, + router: PasteUriRouter, + onValue: @escaping (String) -> Void, + onError: @escaping (Error) -> Void + ) { + defer { + setupInitialState() + } + self.interactor = interactor + self.router = router + self.onValue = onValue + self.onError = onError + } +} + +// MARK: - Private functions +extension PasteUriPresenter { + private func setupInitialState() { + + } +} + +// MARK: - SceneViewModel +extension PasteUriPresenter: SceneViewModel { + +} diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriRouter.swift similarity index 84% rename from Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanRouter.swift rename to Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriRouter.swift index eef0df5c6..ac1bb11bb 100644 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanRouter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriRouter.swift @@ -1,7 +1,6 @@ import UIKit -final class ScanRouter { - +final class PasteUriRouter { weak var viewController: UIViewController! private let app: Application diff --git a/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriView.swift b/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriView.swift new file mode 100644 index 000000000..7f60086e6 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/PasteUri/PasteUriView.swift @@ -0,0 +1,105 @@ +import SwiftUI + +private enum FocusField: Hashable { + case uriField +} + +struct PasteUriView: View { + @Environment(\.dismiss) var dismiss + + @EnvironmentObject var presenter: PasteUriPresenter + + @State private var text = "" + + var body: some View { + ZStack { + Color(red: 20/255, green: 20/255, blue: 20/255, opacity: 0.4) + .edgesIgnoringSafeArea(.all) + + VStack { + Spacer() + VStack(spacing: 6) { + Text("Enter a WalletConnect URI") + .foregroundColor(.grey8) + .font(.system(size: 22, weight: .bold, design: .rounded)) + + Text("To get the URI press the copy to clipboard button in wallet connection interfaces.") + .foregroundColor(.grey50) + .font(.system(size: 15, weight: .medium, design: .rounded)) + .multilineTextAlignment(.center) + .lineSpacing(4) + + ZStack { + RoundedRectangle(cornerRadius: 15) + .fill(Color.whiteBackground) + + HStack { + TextField("wc://a13aef...", text: $text) + .padding(.horizontal, 17) + .foregroundColor(.grey50) + .font(.system(size: 17, weight: .regular, design: .rounded)) + + Button { + text = "" + } label: { + Image(systemName: "xmark.circle.fill") + .foregroundColor(.systemGrayLight) + } + .padding(.trailing, 12) + } + } + .frame(height: 44) + .padding(.top, 20) + .ignoresSafeArea(.keyboard) + + Button { + presenter.onValue(text) + dismiss() + } label: { + Text("Connect") + .frame(maxWidth: .infinity) + .foregroundColor(.white) + .font(.system(size: 20, weight: .semibold, design: .rounded)) + .padding(.vertical, 11) + .background( + LinearGradient( + gradient: Gradient(colors: [ + .blue100, + .blue200 + ]), + startPoint: .top, endPoint: .bottom) + ) + .cornerRadius(20) + } + .padding(.top, 20) + .shadow(color: .white.opacity(0.25), radius: 8, y: 2) + .disabled(text.isEmpty) + + Button { + dismiss() + } label: { + Text("Cancel") + .frame(maxWidth: .infinity) + .foregroundColor(.blue100) + .font(.system(size: 20, weight: .semibold, design: .rounded)) + } + .padding(.top, 20) + } + .padding(20) + .background(Color.lightBackground) + .cornerRadius(34) + .padding(.horizontal, 10) + } + .padding(.bottom, 20) + } + .edgesIgnoringSafeArea(.top) + } +} + +#if DEBUG +struct PasteUriView_Previews: PreviewProvider { + static var previews: some View { + PasteUriView() + } +} +#endif diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/Scan/ScanInteractor.swift similarity index 100% rename from Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanInteractor.swift rename to Example/WalletApp/PresentationLayer/Wallet/Scan/ScanInteractor.swift diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanModule.swift b/Example/WalletApp/PresentationLayer/Wallet/Scan/ScanModule.swift similarity index 99% rename from Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanModule.swift rename to Example/WalletApp/PresentationLayer/Wallet/Scan/ScanModule.swift index eac6302cd..cf877ff7c 100644 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanModule.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/Scan/ScanModule.swift @@ -1,7 +1,6 @@ import SwiftUI final class ScanModule { - @discardableResult static func create( app: Application, @@ -18,5 +17,4 @@ final class ScanModule { return viewController } - } diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/Scan/ScanPresenter.swift similarity index 78% rename from Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanPresenter.swift rename to Example/WalletApp/PresentationLayer/Wallet/Scan/ScanPresenter.swift index f36c77456..53ab44c7c 100644 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/ScanPresenter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/Scan/ScanPresenter.swift @@ -2,7 +2,6 @@ import UIKit import Combine final class ScanPresenter: ObservableObject { - private let interactor: ScanInteractor private let router: ScanRouter @@ -23,26 +22,21 @@ final class ScanPresenter: ObservableObject { self.onValue = onValue self.onError = onError } -} - -// MARK: SceneViewModel - -extension ScanPresenter: SceneViewModel { - - var sceneTitle: String? { - return "Scan URI" - } - - var largeTitleDisplayMode: UINavigationItem.LargeTitleDisplayMode { - return .always + + func dismiss() { + router.dismiss() } } -// MARK: Privates +// MARK: - Private functions private extension ScanPresenter { - func setupInitialState() { } } + +// MARK: - SceneViewModel +extension ScanPresenter: SceneViewModel { + +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/Scan/ScanRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/Scan/ScanRouter.swift new file mode 100644 index 000000000..cdd0e33e2 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/Scan/ScanRouter.swift @@ -0,0 +1,15 @@ +import UIKit + +final class ScanRouter { + weak var viewController: UIViewController! + + private let app: Application + + init(app: Application) { + self.app = app + } + + func dismiss() { + viewController.dismiss() + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/Scan/ScanView.swift b/Example/WalletApp/PresentationLayer/Wallet/Scan/ScanView.swift new file mode 100644 index 000000000..e04d1204a --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/Scan/ScanView.swift @@ -0,0 +1,52 @@ +import SwiftUI + +struct ScanView: View { + @EnvironmentObject var presenter: ScanPresenter + + var body: some View { + ZStack { + ScanQR(onValue: { value in + presenter.onValue(value) + presenter.dismiss() + }, onError: { error in + presenter.onError(error) + presenter.dismiss() + }) + .ignoresSafeArea() + + VStack { + ZStack { + Text("Scan the code") + .foregroundColor(.white) + .font(.system(size: 20, weight: .semibold, design: .rounded)) + + HStack { + Spacer() + + Button { + presenter.dismiss() + } label: { + Image(systemName: "xmark.circle.fill") + .resizable() + .foregroundColor(.grey95) + .frame(width: 30, height: 30) + } + } + .padding(.trailing, 30) + } + + Spacer() + } + .padding(.top, 24) + } + .navigationBarHidden(true) + } +} + +#if DEBUG +struct ScanView_Previews: PreviewProvider { + static var previews: some View { + ScanView() + } +} +#endif diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/Views/ScanQR.swift b/Example/WalletApp/PresentationLayer/Wallet/Scan/Views/ScanQR.swift similarity index 100% rename from Example/Showcase/Classes/PresentationLayer/Wallet/Scan/Views/ScanQR.swift rename to Example/WalletApp/PresentationLayer/Wallet/Scan/Views/ScanQR.swift diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/Views/ScanQRView.swift b/Example/WalletApp/PresentationLayer/Wallet/Scan/Views/ScanQRView.swift similarity index 97% rename from Example/Showcase/Classes/PresentationLayer/Wallet/Scan/Views/ScanQRView.swift rename to Example/WalletApp/PresentationLayer/Wallet/Scan/Views/ScanQRView.swift index 08ce85b45..165028ad6 100644 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/Views/ScanQRView.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/Scan/Views/ScanQRView.swift @@ -22,8 +22,7 @@ final class ScanQRView: UIView { private var captureSession: AVCaptureSession? private lazy var borderView: UIView = { - let borderView = ScanTargetView(radius: 24.0, color: .white, strokeWidth: 2.0, length: 36.0) - borderView.alpha = 0.85 + let borderView = ScanTargetView(radius: 24.0, color: UIColor(displayP3Red: 184/255, green: 245/255, blue: 61/255, alpha: 1.0), strokeWidth: 7, length: 60) return borderView }() diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Scan/Views/ScanTargetView.swift b/Example/WalletApp/PresentationLayer/Wallet/Scan/Views/ScanTargetView.swift similarity index 100% rename from Example/Showcase/Classes/PresentationLayer/Wallet/Scan/Views/ScanTargetView.swift rename to Example/WalletApp/PresentationLayer/Wallet/Scan/Views/ScanTargetView.swift diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/Modela/Proposal.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/Modela/Proposal.swift new file mode 100644 index 000000000..437feb37b --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/Modela/Proposal.swift @@ -0,0 +1,58 @@ +import WalletConnectSign + +struct Proposal { + let proposerName: String + let proposerDescription: String + let proposerURL: String + let iconURL: String + let permissions: [Namespace] + + struct Namespace: Hashable { + let chains: [String] + let methods: [String] + let events: [String] + } + + internal init(proposal: Session.Proposal) { + self.proposerName = proposal.proposer.name + self.proposerDescription = proposal.proposer.description + self.proposerURL = proposal.proposer.url + self.iconURL = proposal.proposer.icons.first ?? "https://avatars.githubusercontent.com/u/37784886" + self.permissions = [ + Namespace( + chains: ["eip155:1"], + methods: ["eth_sendTransaction", "personal_sign", "eth_signTypedData"], + events: ["accountsChanged", "chainChanged"] + ) + ] + } + + internal init(proposerName: String, proposerDescription: String, proposerURL: String, iconURL: String, permissions: [Proposal.Namespace]) { + self.proposerName = proposerName + self.proposerDescription = proposerDescription + self.proposerURL = proposerURL + self.iconURL = iconURL + self.permissions = permissions + } + + static func mock() -> Proposal { + Proposal( + proposerName: "Example name", + proposerDescription: "Example description", + proposerURL: "example.url", + iconURL: "https://avatars.githubusercontent.com/u/37784886", + permissions: [ + Namespace( + chains: ["eip155:1"], + methods: ["eth_sendTransaction", "personal_sign", "eth_signTypedData"], + events: ["accountsChanged", "chainChanged"] + ), + Namespace( + chains: ["cosmos:cosmoshub-2"], + methods: ["cosmos_signDirect", "cosmos_signAmino"], + events: [] + ) + ] + ) + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestInteractor.swift new file mode 100644 index 000000000..bdc73d3c1 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestInteractor.swift @@ -0,0 +1,37 @@ +import Foundation + +import Web3Wallet + +final class SessionRequestInteractor { + private let signer = MessageSignerFactory(signerFactory: DefaultSignerFactory()).create() + private let account = Account("eip155:1:0xe5EeF1368781911d265fDB6946613dA61915a501")! + + func approve(proposal: Session.Proposal) async throws { + var sessionNamespaces = [String: SessionNamespace]() + proposal.requiredNamespaces.forEach { + let caip2Namespace = $0.key + let proposalNamespace = $0.value + let accounts = Set(proposalNamespace.chains.compactMap { Account($0.absoluteString + ":\(account.namespace)") }) + + let extensions: [SessionNamespace.Extension]? = proposalNamespace.extensions?.map { element in + let accounts = Set(element.chains.compactMap { Account($0.absoluteString + ":\(account.namespace)") }) + return SessionNamespace.Extension(accounts: accounts, methods: element.methods, events: element.events) + } + let sessionNamespace = SessionNamespace(accounts: accounts, methods: proposalNamespace.methods, events: proposalNamespace.events, extensions: extensions) + sessionNamespaces[caip2Namespace] = sessionNamespace + } + + try await Web3Wallet.instance.approve(proposalId: proposal.id, namespaces: sessionNamespaces) + } + + func reject(proposal: Session.Proposal) async throws { + try await Web3Wallet.instance.reject(proposalId: proposal.id, reason: .userRejected) + } + + func formatted(request: AuthRequest) -> String { + return try! Web3Wallet.instance.formatMessage( + payload: request.payload, + address: account.address + ) + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestModule.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestModule.swift new file mode 100644 index 000000000..d547d6291 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestModule.swift @@ -0,0 +1,22 @@ +import SwiftUI + +import Web3Wallet + +final class SessionRequestModule { + @discardableResult + static func create(app: Application, proposal: Session.Proposal) -> UIViewController { + let router = SessionRequestRouter(app: app) + let interactor = SessionRequestInteractor() + let presenter = SessionRequestPresenter( + interactor: interactor, + router: router, + proposal: proposal + ) + let view = SessionRequestView().environmentObject(presenter) + let viewController = SceneViewController(viewModel: presenter, content: view) + + router.viewController = viewController + + return viewController + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestPresenter.swift new file mode 100644 index 000000000..a32d957fc --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestPresenter.swift @@ -0,0 +1,50 @@ +import UIKit +import Combine + +import Web3Wallet + +final class SessionRequestPresenter: ObservableObject { + private let interactor: SessionRequestInteractor + private let router: SessionRequestRouter + + let proposal: Proposal + private let sessionProposal: Session.Proposal + + private var disposeBag = Set() + + init( + interactor: SessionRequestInteractor, + router: SessionRequestRouter, + proposal: Session.Proposal + ) { + defer { setupInitialState() } + self.interactor = interactor + self.router = router + self.proposal = Proposal(proposal: proposal) + self.sessionProposal = proposal + } + + @MainActor + func onApprove() async throws { + try await interactor.approve(proposal: sessionProposal) + router.dismiss() + } + + @MainActor + func onReject() async throws { + try await interactor.reject(proposal: sessionProposal) + router.dismiss() + } +} + +// MARK: - Private functions +private extension SessionRequestPresenter { + func setupInitialState() { + + } +} + +// MARK: - SceneViewModel +extension SessionRequestPresenter: SceneViewModel { + +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestRouter.swift new file mode 100644 index 000000000..cb7dff530 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestRouter.swift @@ -0,0 +1,15 @@ +import UIKit + +final class SessionRequestRouter { + weak var viewController: UIViewController! + + private let app: Application + + init(app: Application) { + self.app = app + } + + func dismiss() { + viewController.dismiss() + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestView.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestView.swift new file mode 100644 index 000000000..6af49c1c9 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestView.swift @@ -0,0 +1,175 @@ +import SwiftUI + +struct SessionRequestView: View { + @EnvironmentObject var presenter: SessionRequestPresenter + + @State var text = "" + + var body: some View { + ZStack { + Color.black.opacity(0.6) + + VStack { + Spacer() + + VStack(spacing: 0) { + Image("header") + .resizable() + .scaledToFit() + + Text(presenter.proposal.proposerName) + .foregroundColor(.grey8) + .font(.system(size: 22, weight: .bold, design: .rounded)) + .padding(.top, 10) + + Text("would like to connect") + .foregroundColor(.grey8) + .font(.system(size: 22, weight: .medium, design: .rounded)) + + Text(presenter.proposal.proposerName) + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + .multilineTextAlignment(.center) + .lineSpacing(4) + .padding(.top, 8) + + sessionProposalView() + + HStack(spacing: 20) { + Button { + Task(priority: .userInitiated) { try await + presenter.onReject() + } + } label: { + Text("Decline") + .frame(maxWidth: .infinity) + .foregroundColor(.white) + .font(.system(size: 20, weight: .semibold, design: .rounded)) + .padding(.vertical, 11) + .background( + LinearGradient( + gradient: Gradient(colors: [ + .foregroundNegative, + .lightForegroundNegative + ]), + startPoint: .top, endPoint: .bottom) + ) + .cornerRadius(20) + } + .shadow(color: .white.opacity(0.25), radius: 8, y: 2) + + Button { + Task(priority: .userInitiated) { try await + presenter.onApprove() + } + } label: { + Text("Allow") + .frame(maxWidth: .infinity) + .foregroundColor(.white) + .font(.system(size: 20, weight: .semibold, design: .rounded)) + .padding(.vertical, 11) + .background( + LinearGradient( + gradient: Gradient(colors: [ + .foregroundPositive, + .lightForegroundPositive + ]), + startPoint: .top, endPoint: .bottom) + ) + .cornerRadius(20) + } + .shadow(color: .white.opacity(0.25), radius: 8, y: 2) + } + .padding(.top, 25) + } + .padding(20) + .background(.ultraThinMaterial) + .cornerRadius(34) + .padding(.horizontal, 10) + + Spacer() + } + } + .edgesIgnoringSafeArea(.all) + } + + private func sessionProposalView() -> some View { + VStack { + VStack(alignment: .leading) { + Text(presenter.proposal.permissions.first?.chains.first ?? "Chain") + .font(.system(size: 15, weight: .semibold, design: .rounded)) + .foregroundColor(.whiteBackground) + .padding(.horizontal, 8) + .padding(.vertical, 5) + .background(Color.grey70) + .cornerRadius(28, corners: .allCorners) + .padding(.leading, 15) + .padding(.top, 9) + + VStack(spacing: 0) { + HStack { + Text("Methods") + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + + Spacer() + } + .padding(.horizontal, 18) + .padding(.top, 10) + + TagsView(items: presenter.proposal.permissions.first?.methods ?? []) { + Text($0) + .foregroundColor(.cyanBackround) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + .padding(.horizontal, 8) + .padding(.vertical, 3) + .background(Color.cyanBackround.opacity(0.2)) + .cornerRadius(10, corners: .allCorners) + } + .padding(10) + } + .background(Color.whiteBackground) + .cornerRadius(20, corners: .allCorners) + .padding(.horizontal, 5) + + VStack(spacing: 0) { + HStack { + Text("Events") + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + + Spacer() + } + .padding(.horizontal, 18) + .padding(.top, 10) + + TagsView(items: presenter.proposal.permissions.first?.events ?? []) { + Text($0) + .foregroundColor(.cyanBackround) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + .padding(.horizontal, 8) + .padding(.vertical, 3) + .background(Color.cyanBackround.opacity(0.2)) + .cornerRadius(10, corners: .allCorners) + } + .padding(10) + } + .background(Color.whiteBackground) + .cornerRadius(20, corners: .allCorners) + .padding(.horizontal, 5) + .padding(.bottom, 5) + } + .background(.thinMaterial) + .cornerRadius(25, corners: .allCorners) + } + .padding(.top, 30) + } +} + +#if DEBUG +struct SessionRequestView_Previews: PreviewProvider { + static var previews: some View { + SessionRequestView() + } +} +#endif diff --git a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletInteractor.swift new file mode 100644 index 000000000..e17234aa5 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletInteractor.swift @@ -0,0 +1,25 @@ +import Combine + +import Web3Wallet + +final class WalletInteractor { + var requestPublisher: AnyPublisher { + return Web3Wallet.instance.authRequestPublisher + } + + var sessionProposalPublisher: AnyPublisher { + return Web3Wallet.instance.sessionProposalPublisher + } + + var sessionsPublisher: AnyPublisher<[Session], Never> { + return Web3Wallet.instance.sessionsPublisher + } + + func getSessions() -> [Session] { + return Web3Wallet.instance.getSessions() + } + + func pair(uri: WalletConnectURI) async throws { + try await Web3Wallet.instance.pair(uri: uri) + } +} diff --git a/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletModule.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletModule.swift similarity index 94% rename from Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletModule.swift rename to Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletModule.swift index fed9b1307..534e5f676 100644 --- a/Example/Showcase/Classes/PresentationLayer/Wallet/Wallet/WalletModule.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletModule.swift @@ -1,12 +1,11 @@ import SwiftUI final class WalletModule { - @discardableResult static func create(app: Application) -> UIViewController { let router = WalletRouter(app: app) let interactor = WalletInteractor() - let presenter = WalletPresenter(interactor: interactor, router: router) + let presenter = WalletPresenter(interactor: interactor, router: router, uri: app.uri) let view = WalletView().environmentObject(presenter) let viewController = SceneViewController(viewModel: presenter, content: view) @@ -14,5 +13,4 @@ final class WalletModule { return viewController } - } diff --git a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletPresenter.swift new file mode 100644 index 000000000..24a540b3a --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletPresenter.swift @@ -0,0 +1,107 @@ +import UIKit +import Combine + +import Web3Wallet + +final class WalletPresenter: ObservableObject { + private let interactor: WalletInteractor + private let router: WalletRouter + + @Published var sessions = [Session]() + + private let uri: String? + + private var disposeBag = Set() + + init( + interactor: WalletInteractor, + router: WalletRouter, + uri: String? + ) { + defer { + setupInitialState() + } + self.interactor = interactor + self.router = router + self.uri = uri + } + + func onConnection(session: Session) { + router.presentConnectionDetails(session: session) + } + + func onPasteUri() { + router.presentPaste { [weak self] uri in + guard let uri = WalletConnectURI(string: uri) else { + return + } + print(uri) + self?.pair(uri: uri) + + } onError: { [weak self] error in + print(error.localizedDescription) + self?.router.dismiss() + } + } + + func onScanUri() { + router.presentScan { [unowned self] value in + guard let uri = WalletConnectURI(string: value) else { return } + self.pair(uri: uri) + self.router.dismiss() + } onError: { error in + print(error.localizedDescription) + self.router.dismiss() + } + } +} + +// MARK: - Private functions +extension WalletPresenter { + private func setupInitialState() { + interactor.requestPublisher.sink { [weak self] request in + self?.router.present(request: request) + } + .store(in: &disposeBag) + + interactor.sessionProposalPublisher.sink { [weak self] proposal in + self?.router.present(proposal: proposal) + } + .store(in: &disposeBag) + + interactor.sessionsPublisher.sink { [weak self] sessions in + self?.sessions = sessions + } + .store(in: &disposeBag) + + sessions = interactor.getSessions() + + pairFromDapp() + } + + private func pair(uri: WalletConnectURI) { + Task(priority: .high) { [unowned self] in + try await self.interactor.pair(uri: uri) + } + } + + private func pairFromDapp() { + guard let uri = uri, + let walletConnectUri = WalletConnectURI(string: uri) + else { + return + } + pair(uri: walletConnectUri) + } +} + +// MARK: - SceneViewModel +extension WalletPresenter: SceneViewModel { + var sceneTitle: String? { + return "Connections" + } + + var largeTitleDisplayMode: UINavigationItem.LargeTitleDisplayMode { + return .always + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletRouter.swift new file mode 100644 index 000000000..221f328ce --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletRouter.swift @@ -0,0 +1,43 @@ +import UIKit + +import Web3Wallet + +final class WalletRouter { + weak var viewController: UIViewController! + + private let app: Application + + init(app: Application) { + self.app = app + } + + func present(request: AuthRequest) { + AuthRequestModule.create(app: app, request: request) + .presentFullScreen(from: viewController, transparentBackground: true) + } + + func present(proposal: Session.Proposal) { + SessionRequestModule.create(app: app, proposal: proposal) + .presentFullScreen(from: viewController, transparentBackground: true) + } + + func presentPaste(onValue: @escaping (String) -> Void, onError: @escaping (Error) -> Void) { + PasteUriModule.create(app: app, onValue: onValue, onError: onError) + .presentFullScreen(from: viewController, transparentBackground: true) + } + + func presentConnectionDetails(session: Session) { + ConnectionDetailsModule.create(app: app, session: session) + .push(from: viewController) + } + + func presentScan(onValue: @escaping (String) -> Void, onError: @escaping (Error) -> Void) { + ScanModule.create(app: app, onValue: onValue, onError: onError) + .wrapToNavigationController() + .present(from: viewController) + } + + func dismiss() { + viewController.navigationController?.dismiss() + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletView.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletView.swift new file mode 100644 index 000000000..6cd276a1c --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletView.swift @@ -0,0 +1,111 @@ +import SwiftUI +import Web3Wallet + +struct WalletView: View { + @EnvironmentObject var presenter: WalletPresenter + + var body: some View { + ZStack { + Color.grey100 + .edgesIgnoringSafeArea(.all) + + VStack(alignment: .leading, spacing: 16) { + ZStack { + if presenter.sessions.isEmpty { + VStack(spacing: 10) { + Image("connect-template") + + Text("Apps you connect with will appear here. To connect scan or paste the code that’s displayed in the app.") + .foregroundColor(.grey50) + .font(.system(size: 15, weight: .regular, design: .rounded)) + .multilineTextAlignment(.center) + .lineSpacing(4) + } + } + + VStack { + if !presenter.sessions.isEmpty { + ScrollView { + ForEach(presenter.sessions, id: \.peer.name) { session in + connectionView(session: session) + } + } + } + + Spacer() + + HStack(spacing: 20) { + Spacer() + + Button { + presenter.onPasteUri() + } label: { + Image("copy") + .resizable() + .frame(width: 56, height: 56) + } + .shadow(color: .black.opacity(0.25), radius: 8, y: 4) + + Button { + presenter.onScanUri() + } label: { + Image("scan") + .resizable() + .frame(width: 56, height: 56) + } + .shadow(color: .black.opacity(0.25), radius: 8, y: 4) + } + } + } + } + .padding(20) + } + } + + private func connectionView(session: Session) -> some View { + Button { + presenter.onConnection(session: session) + } label: { + VStack { + HStack(spacing: 10) { + AsyncImage(url: URL(string: session.peer.icons.first ?? "")) { phase in + if let image = phase.image { + image + .resizable() + .frame(width: 60, height: 60) + .background(Color.black) + .cornerRadius(30, corners: .allCorners) + } else { + Color.black + .frame(width: 60, height: 60) + .cornerRadius(30, corners: .allCorners) + } + } + + VStack(alignment: .leading, spacing: 2) { + Text(session.peer.name) + .foregroundColor(.grey8) + .font(.system(size: 20, weight: .semibold, design: .rounded)) + + Text(session.peer.url) + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .medium, design: .rounded)) + } + + Spacer() + + Image("forward-shevron") + .foregroundColor(.grey8) + } + } + } + } +} + +#if DEBUG +struct WalletView_Previews: PreviewProvider { + static var previews: some View { + WalletView() + } +} +#endif diff --git a/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeInteractor.swift new file mode 100644 index 000000000..95934398d --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeInteractor.swift @@ -0,0 +1,3 @@ +final class WelcomeInteractor { + +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeModule.swift b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeModule.swift new file mode 100644 index 000000000..000f8e651 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeModule.swift @@ -0,0 +1,16 @@ +import SwiftUI + +final class WelcomeModule { + @discardableResult + static func create(app: Application) -> UIViewController { + let router = WelcomeRouter(app: app) + let interactor = WelcomeInteractor() + let presenter = WelcomePresenter(interactor: interactor, router: router) + let view = WelcomeView().environmentObject(presenter) + let viewController = SceneViewController(viewModel: presenter, content: view) + + router.viewController = viewController + + return viewController + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomePresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomePresenter.swift new file mode 100644 index 000000000..31381569c --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomePresenter.swift @@ -0,0 +1,32 @@ +import UIKit +import Combine + +final class WelcomePresenter: ObservableObject { + private let interactor: WelcomeInteractor + private let router: WelcomeRouter + private var disposeBag = Set() + + init(interactor: WelcomeInteractor, router: WelcomeRouter) { + defer { + setupInitialState() + } + self.interactor = interactor + self.router = router + } + + func onGetStarted() { + router.presentWallet() + } +} + +// MARK: Private functions +extension WelcomePresenter { + private func setupInitialState() { + + } +} + +// MARK: - SceneViewModel +extension WelcomePresenter: SceneViewModel { + +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeRouter.swift new file mode 100644 index 000000000..9ebd6c7bf --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeRouter.swift @@ -0,0 +1,17 @@ +import UIKit + +final class WelcomeRouter { + weak var viewController: UIViewController! + + private let app: Application + + init(app: Application) { + self.app = app + } + + func presentWallet() { + WalletModule.create(app: app) + .wrapToNavigationController() + .presentFullScreen(from: viewController) + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeView.swift b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeView.swift new file mode 100644 index 000000000..42c65d8e8 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeView.swift @@ -0,0 +1,60 @@ +import SwiftUI + +struct WelcomeView: View { + @EnvironmentObject var presenter: WelcomePresenter + + @State private var presentWallet = false + + var body: some View { + ZStack { + Color.grey100 + .edgesIgnoringSafeArea(.all) + + VStack(spacing: 0) { + Text("Welcome") + .foregroundColor(.grey8) + .font(.system(size: 34, weight: .bold, design: .rounded)) + + Text("We made this Example Wallet App to help developers integrate the WalletConnect SDK and provide an amazing experience to their users.") + .foregroundColor(.grey50) + .font(.system(size: 15, weight: .medium, design: .rounded)) + .multilineTextAlignment(.center) + .lineSpacing(3) + .padding(.top, 10) + + Spacer() + + Button { + presenter.onGetStarted() + } label: { + Text("Get Started") + .frame(maxWidth: .infinity) + .foregroundColor(.white) + .font(.system(size: 20, weight: .semibold, design: .rounded)) + .padding(.vertical, 15) + .background( + LinearGradient( + gradient: Gradient(colors: [ + .blue100, + .blue200 + ]), + startPoint: .top, endPoint: .bottom) + ) + .cornerRadius(20) + } + .padding(.top, 20) + .shadow(color: .white.opacity(0.25), radius: 8, y: 2) + .fullScreenCover(isPresented: $presentWallet, content: WalletView.init) + } + .padding([.horizontal, .vertical], 20) + } + } +} + +#if DEBUG +struct WelcomeView_Previews: PreviewProvider { + static var previews: some View { + WelcomeView() + } +} +#endif diff --git a/README.md b/README.md index bf481bd7a..d7724421b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ![CI develop](https://github.com/WalletConnect/WalletConnectSwiftV2/actions/workflows/ci.yml/badge.svg?branch=develop) Swift implementation of WalletConnect v.2 protocol for native iOS applications. -## Requirements +## Requirements - iOS 13 - XCode 13 - Swift 5 @@ -15,6 +15,7 @@ Swift implementation of WalletConnect v.2 protocol for native iOS applications. - [Beginner guide to WalletConnect v2.0 for iOS Developers](https://medium.com/walletconnect/beginner-guide-to-walletconnect-v2-0-for-swift-developers-4534b0975218) - [Protocol Documentation](https://github.com/WalletConnect/walletconnect-specs) - [Glossary](https://docs.walletconnect.com/2.0/introduction/glossary) +- [Migration guide from Sign and Auth to Web3Wallet](https://github.com/WalletConnect/walletconnect-docs/blob/main/docs/swift/guides/web3wallet-migration.md) ## Installation @@ -47,6 +48,10 @@ SIMULATOR_IDENTIFIER = YOUR_SIMULATOR_IDENTIFIER ## Example App open `Example/ExampleApp.xcodeproj` +## Web3Wallet +Web3Wallet SDK introduces a new interface for all wallets that wraps the Sign and Auth clients internally. +- [Migration guide from Sign and Auth to Web3Wallet](https://github.com/WalletConnect/walletconnect-docs/blob/main/docs/swift/guides/web3wallet-migration.md) + ## License Apache 2.0 diff --git a/Sources/Auth/AuthClientProtocol.swift b/Sources/Auth/AuthClientProtocol.swift index 2604ac2f2..9e1a1fb62 100644 --- a/Sources/Auth/AuthClientProtocol.swift +++ b/Sources/Auth/AuthClientProtocol.swift @@ -6,5 +6,6 @@ public protocol AuthClientProtocol { func formatMessage(payload: AuthPayload, address: String) throws -> String func respond(requestId: RPCID, signature: CacaoSignature, from account: Account) async throws + func reject(requestId: RPCID) async throws func getPendingRequests(account: Account) throws -> [AuthRequest] } diff --git a/Sources/WalletConnectRelay/PackageConfig.json b/Sources/WalletConnectRelay/PackageConfig.json index 18631a482..5d6fcfcfb 100644 --- a/Sources/WalletConnectRelay/PackageConfig.json +++ b/Sources/WalletConnectRelay/PackageConfig.json @@ -1 +1 @@ -{"version": "1.2.0"} +{"version": "1.2.1"} diff --git a/Sources/WalletConnectSign/Sign/SignClientProtocol.swift b/Sources/WalletConnectSign/Sign/SignClientProtocol.swift index 933d476ba..d176a0e51 100644 --- a/Sources/WalletConnectSign/Sign/SignClientProtocol.swift +++ b/Sources/WalletConnectSign/Sign/SignClientProtocol.swift @@ -4,6 +4,7 @@ import Combine public protocol SignClientProtocol { var sessionProposalPublisher: AnyPublisher { get } var sessionRequestPublisher: AnyPublisher { get } + var sessionsPublisher: AnyPublisher<[Session], Never> { get } func approve(proposalId: String, namespaces: [String: SessionNamespace]) async throws func reject(proposalId: String, reason: RejectionReason) async throws diff --git a/Sources/Web3Wallet/Web3Wallet.swift b/Sources/Web3Wallet/Web3Wallet.swift index 38eabb617..3fb7bc876 100644 --- a/Sources/Web3Wallet/Web3Wallet.swift +++ b/Sources/Web3Wallet/Web3Wallet.swift @@ -17,7 +17,7 @@ public class Web3Wallet { /// Web3Wallett client instance public static var instance: Web3WalletClient = { guard let config = Web3Wallet.config else { - fatalError("Error - you must call Wallet.configure(_:) before accessing the shared instance.") + fatalError("Error - you must call Web3Wallet.configure(_:) before accessing the shared instance.") } return Web3WalletClientFactory.create( diff --git a/Sources/Web3Wallet/Web3WalletClient.swift b/Sources/Web3Wallet/Web3WalletClient.swift index 196a0a471..43c709b95 100644 --- a/Sources/Web3Wallet/Web3WalletClient.swift +++ b/Sources/Web3Wallet/Web3WalletClient.swift @@ -29,6 +29,13 @@ public class Web3WalletClient { public var authRequestPublisher: AnyPublisher { authClient.authRequestPublisher.eraseToAnyPublisher() } + + /// Publisher that sends sessions on every sessions update + /// + /// Event will be emited on controller and non-controller clients. + public var sessionsPublisher: AnyPublisher<[Session], Never> { + signClient.sessionsPublisher.eraseToAnyPublisher() + } // MARK: - Private Properties private let authClient: AuthClientProtocol @@ -62,6 +69,12 @@ public class Web3WalletClient { public func reject(proposalId: String, reason: RejectionReason) async throws { try await signClient.reject(proposalId: proposalId, reason: reason) } + + /// For wallet to reject authentication request + /// - Parameter requestId: authentication request id + public func reject(requestId: RPCID) async throws { + try await authClient.reject(requestId: requestId) + } /// For the wallet to update session namespaces /// - Parameters: @@ -123,7 +136,6 @@ public class Web3WalletClient { try await signClient.disconnect(topic: topic) } - /// Query sessions /// - Returns: All sessions public func getSessions() -> [Session] { diff --git a/Tests/Web3WalletTests/Mocks/AuthClientMock.swift b/Tests/Web3WalletTests/Mocks/AuthClientMock.swift index 2b5a407f7..3b1a3a68d 100644 --- a/Tests/Web3WalletTests/Mocks/AuthClientMock.swift +++ b/Tests/Web3WalletTests/Mocks/AuthClientMock.swift @@ -5,6 +5,7 @@ import Combine final class AuthClientMock: AuthClientProtocol { var respondCalled = false + var rejectCalled = false private var authRequest: AuthRequest { let requestParams = RequestParams( @@ -37,6 +38,10 @@ final class AuthClientMock: AuthClientProtocol { respondCalled = true } + func reject(requestId: JSONRPC.RPCID) async throws { + rejectCalled = true + } + func getPendingRequests(account: WalletConnectUtils.Account) throws -> [AuthRequest] { return [authRequest] } diff --git a/Tests/Web3WalletTests/Mocks/SignClientMock.swift b/Tests/Web3WalletTests/Mocks/SignClientMock.swift index dacd19109..72ad8f006 100644 --- a/Tests/Web3WalletTests/Mocks/SignClientMock.swift +++ b/Tests/Web3WalletTests/Mocks/SignClientMock.swift @@ -4,6 +4,8 @@ import Combine @testable import WalletConnectSign final class SignClientMock: SignClientProtocol { + + var approveCalled = false var rejectCalled = false var updateCalled = false @@ -25,11 +27,18 @@ final class SignClientMock: SignClientProtocol { ) .publicRepresentation() - return Result.Publisher(sessionProposal).eraseToAnyPublisher() + return Result.Publisher(sessionProposal) + .eraseToAnyPublisher() } var sessionRequestPublisher: AnyPublisher { - return Result.Publisher(request).eraseToAnyPublisher() + return Result.Publisher(request) + .eraseToAnyPublisher() + } + + var sessionsPublisher: AnyPublisher<[WalletConnectSign.Session], Never> { + return Result.Publisher([WalletConnectSign.Session(topic: "", peer: metadata, namespaces: [:], expiryDate: Date())]) + .eraseToAnyPublisher() } func approve(proposalId: String, namespaces: [String : WalletConnectSign.SessionNamespace]) async throws { diff --git a/Tests/Web3WalletTests/Web3WalletTests.swift b/Tests/Web3WalletTests/Web3WalletTests.swift index 5aff74851..7ce173cc5 100644 --- a/Tests/Web3WalletTests/Web3WalletTests.swift +++ b/Tests/Web3WalletTests/Web3WalletTests.swift @@ -69,16 +69,36 @@ final class Web3WalletTests: XCTestCase { } } + func testSessionsCalled() { + var success = false + web3WalletClient.sessionsPublisher.sink { value in + success = true + XCTAssertTrue(true) + } + .store(in: &disposeBag) + + let expectation = expectation(description: "Fail after 0.1s timeout") + let result = XCTWaiter.wait(for: [expectation], timeout: 0.1) + if result == XCTWaiter.Result.timedOut && success == false { + XCTFail() + } + } + func testApproveCalled() async { try! await web3WalletClient.approve(proposalId: "", namespaces: [:]) XCTAssertTrue(signClient.approveCalled) } - func testRejectCalled() async { + func testRejectSessionCalled() async { try! await web3WalletClient.reject(proposalId: "", reason: .userRejected) XCTAssertTrue(signClient.rejectCalled) } + func testRejectAuthRequestCalled() async { + try! await web3WalletClient.reject(requestId: .left("")) + XCTAssertTrue(authClient.rejectCalled) + } + func testUpdateCalled() async { try! await web3WalletClient.update(topic: "", namespaces: [:]) XCTAssertTrue(signClient.updateCalled) @@ -171,4 +191,3 @@ final class Web3WalletTests: XCTestCase { XCTAssertEqual(1, pendingRequests.count) } } -