diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 90aa0e0a4..d5d883e65 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -28,7 +28,6 @@ 76B149F02821C03B00F05F91 /* Proposal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76B149EF2821C03B00F05F91 /* Proposal.swift */; }; 76B6E39F2807A3B6004DF775 /* WalletViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76B6E39E2807A3B6004DF775 /* WalletViewController.swift */; }; 840BCF142949B9F900CB0655 /* WalletConnectPush in Frameworks */ = {isa = PBXBuildFile; productRef = 840BCF132949B9F900CB0655 /* WalletConnectPush */; }; - 840BCF162949C6C100CB0655 /* WalletConnectEcho in Frameworks */ = {isa = PBXBuildFile; productRef = 840BCF152949C6C100CB0655 /* WalletConnectEcho */; }; 8439CB89293F658E00F2F2E2 /* PushMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8439CB88293F658E00F2F2E2 /* PushMessage.swift */; }; 8448F1D427E4726F0000B866 /* WalletConnect in Frameworks */ = {isa = PBXBuildFile; productRef = 8448F1D327E4726F0000B866 /* WalletConnect */; }; 84494388278D9C1B00CC26BB /* UIAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84494387278D9C1B00CC26BB /* UIAlertController.swift */; }; @@ -36,9 +35,13 @@ 8460DCFC274F98A10081F94C /* RequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8460DCFB274F98A10081F94C /* RequestViewController.swift */; }; 847CF3AF28E3141700F1D760 /* WalletConnectPush in Frameworks */ = {isa = PBXBuildFile; productRef = 847CF3AE28E3141700F1D760 /* WalletConnectPush */; settings = {ATTRIBUTES = (Required, ); }; }; 8485617D295079730064877B /* WalletConnectPairing in Frameworks */ = {isa = PBXBuildFile; productRef = 8485617C295079730064877B /* WalletConnectPairing */; }; + 8485617F295307C20064877B /* PushNotificationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8485617E295307C20064877B /* PushNotificationTests.swift */; }; 849D7A90292665D3006A2BD4 /* WalletConnectVerify in Frameworks */ = {isa = PBXBuildFile; productRef = 849D7A8F292665D3006A2BD4 /* WalletConnectVerify */; }; 849D7A93292E2169006A2BD4 /* PushTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849D7A92292E2169006A2BD4 /* PushTests.swift */; }; 84AA01DB28CF0CD7005D48D8 /* XCTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AA01DA28CF0CD7005D48D8 /* XCTest.swift */; }; + 84B767792954554A00E92316 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B767782954554A00E92316 /* NotificationService.swift */; }; + 84B7677D2954554A00E92316 /* PushDecryptionService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 84B767762954554A00E92316 /* PushDecryptionService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 84B76789295494D500E92316 /* WalletConnectPush in Frameworks */ = {isa = PBXBuildFile; productRef = 84B76788295494D500E92316 /* WalletConnectPush */; }; 84CE641F27981DED00142511 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE641E27981DED00142511 /* AppDelegate.swift */; }; 84CE642127981DED00142511 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE642027981DED00142511 /* SceneDelegate.swift */; }; 84CE642827981DF000142511 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 84CE642727981DF000142511 /* Assets.xcassets */; }; @@ -199,11 +202,11 @@ 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 */; }; + C55D34AE2965FB750004314A /* SessionProposalModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D34A92965FB750004314A /* SessionProposalModule.swift */; }; + C55D34AF2965FB750004314A /* SessionProposalPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D34AA2965FB750004314A /* SessionProposalPresenter.swift */; }; + C55D34B02965FB750004314A /* SessionProposalRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D34AB2965FB750004314A /* SessionProposalRouter.swift */; }; + C55D34B12965FB750004314A /* SessionProposalInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D34AC2965FB750004314A /* SessionProposalInteractor.swift */; }; + C55D34B22965FB750004314A /* SessionProposalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D34AD2965FB750004314A /* SessionProposalView.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 */; }; @@ -219,7 +222,6 @@ 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 */; }; @@ -238,6 +240,17 @@ 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 */; }; + C5B2F6F629705293000DBA0E /* SessionRequestModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5B2F6F12970511B000DBA0E /* SessionRequestModule.swift */; }; + C5B2F6F729705293000DBA0E /* SessionRequestRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5B2F6F32970511B000DBA0E /* SessionRequestRouter.swift */; }; + C5B2F6F829705293000DBA0E /* SessionRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5B2F6F52970511B000DBA0E /* SessionRequestView.swift */; }; + C5B2F6F929705293000DBA0E /* SessionRequestPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5B2F6F22970511B000DBA0E /* SessionRequestPresenter.swift */; }; + C5B2F6FA29705293000DBA0E /* SessionRequestInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5B2F6F42970511B000DBA0E /* SessionRequestInteractor.swift */; }; + C5B2F6FB297055B0000DBA0E /* ETHSigner.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57E71A5291CF76400325797 /* ETHSigner.swift */; }; + C5B2F6FC297055B0000DBA0E /* SOLSigner.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57E71A7291CF8A500325797 /* SOLSigner.swift */; }; + C5B2F6FD297055B0000DBA0E /* Signer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C1279582D200D0A289 /* Signer.swift */; }; + C5B2F7052970573D000DBA0E /* SolanaSwift in Frameworks */ = {isa = PBXBuildFile; productRef = C5B2F7042970573D000DBA0E /* SolanaSwift */; }; + C5B2F71029705827000DBA0E /* EthereumTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C32795832A00D0A289 /* EthereumTransaction.swift */; }; + C5B2F7112970583B000DBA0E /* SessionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C64A526FCB0AA004239D1 /* SessionInfo.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 */; }; @@ -249,6 +262,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 84B7677B2954554A00E92316 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 764E1D3426F8D3FC00A1FB15 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 84B767752954554A00E92316; + remoteInfo = PushDecryptionService; + }; A5A4FC7D2840C5D400BBEC1E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 764E1D3426F8D3FC00A1FB15 /* Project object */; @@ -265,6 +285,20 @@ }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + 84B7677E2954554A00E92316 /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + 84B7677D2954554A00E92316 /* PushDecryptionService.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 760022382819FBF90011DD38 /* ProposalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProposalViewController.swift; sourceTree = ""; }; 7600223A2819FC0B0011DD38 /* ProposalView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProposalView.swift; sourceTree = ""; }; @@ -292,12 +326,17 @@ 7694A5252874296A0001257E /* RegistryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistryTests.swift; sourceTree = ""; }; 76B149EF2821C03B00F05F91 /* Proposal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Proposal.swift; sourceTree = ""; }; 76B6E39E2807A3B6004DF775 /* WalletViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletViewController.swift; sourceTree = ""; }; + 8414FC832962F3D9007E20C9 /* PushDecryptionService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PushDecryptionService.entitlements; sourceTree = ""; }; 8439CB88293F658E00F2F2E2 /* PushMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushMessage.swift; sourceTree = ""; }; 84494387278D9C1B00CC26BB /* UIAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAlertController.swift; sourceTree = ""; }; 845B8D8B2934B36C0084A966 /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = ""; }; 8460DCFB274F98A10081F94C /* RequestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestViewController.swift; sourceTree = ""; }; + 8485617E295307C20064877B /* PushNotificationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationTests.swift; sourceTree = ""; }; 849D7A92292E2169006A2BD4 /* PushTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushTests.swift; sourceTree = ""; }; 84AA01DA28CF0CD7005D48D8 /* XCTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCTest.swift; sourceTree = ""; }; + 84B767762954554A00E92316 /* PushDecryptionService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PushDecryptionService.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 84B767782954554A00E92316 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; + 84B7677A2954554A00E92316 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 84CE641C27981DED00142511 /* DApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 84CE641E27981DED00142511 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 84CE642027981DED00142511 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -440,11 +479,11 @@ 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 = ""; }; + C55D34A92965FB750004314A /* SessionProposalModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionProposalModule.swift; sourceTree = ""; }; + C55D34AA2965FB750004314A /* SessionProposalPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionProposalPresenter.swift; sourceTree = ""; }; + C55D34AB2965FB750004314A /* SessionProposalRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionProposalRouter.swift; sourceTree = ""; }; + C55D34AC2965FB750004314A /* SessionProposalInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionProposalInteractor.swift; sourceTree = ""; }; + C55D34AD2965FB750004314A /* SessionProposalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionProposalView.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 = ""; }; @@ -462,7 +501,6 @@ 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 = ""; }; @@ -478,6 +516,11 @@ 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 = ""; }; + C5B2F6F12970511B000DBA0E /* SessionRequestModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionRequestModule.swift; sourceTree = ""; }; + C5B2F6F22970511B000DBA0E /* SessionRequestPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionRequestPresenter.swift; sourceTree = ""; }; + C5B2F6F32970511B000DBA0E /* SessionRequestRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionRequestRouter.swift; sourceTree = ""; }; + C5B2F6F42970511B000DBA0E /* SessionRequestInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionRequestInteractor.swift; sourceTree = ""; }; + C5B2F6F52970511B000DBA0E /* SessionRequestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionRequestView.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 = ""; }; @@ -494,7 +537,6 @@ A5AE354728A1A2AC0059AE8A /* Web3 in Frameworks */, A5434023291E6A270068F706 /* SolanaSwift in Frameworks */, 849D7A90292665D3006A2BD4 /* WalletConnectVerify in Frameworks */, - 840BCF162949C6C100CB0655 /* WalletConnectEcho in Frameworks */, 8485617D295079730064877B /* WalletConnectPairing in Frameworks */, 764E1D5826F8DBAB00A1FB15 /* WalletConnect in Frameworks */, 840BCF142949B9F900CB0655 /* WalletConnectPush in Frameworks */, @@ -503,6 +545,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 84B767732954554A00E92316 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 84B76789295494D500E92316 /* WalletConnectPush in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 84CE641927981DED00142511 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -552,6 +602,7 @@ files = ( C56EE27D293F56F8004840D1 /* WalletConnectChat in Frameworks */, C5133A78294125CC00A8314C /* Web3 in Frameworks */, + C5B2F7052970573D000DBA0E /* SolanaSwift in Frameworks */, C55D349929630D440004314A /* Web3Wallet in Frameworks */, C56EE255293F569A004840D1 /* Starscream in Frameworks */, C56EE27B293F56F8004840D1 /* WalletConnectAuth in Frameworks */, @@ -609,6 +660,7 @@ A5A4FC732840C12C00BBEC1E /* UITests */, A5E03DEE286464DB00888481 /* IntegrationTests */, A58E7CE928729F550082D443 /* Showcase */, + 84B767772954554A00E92316 /* PushDecryptionService */, C56EE21C293F55ED004840D1 /* WalletApp */, 764E1D3D26F8D3FC00A1FB15 /* Products */, 764E1D5326F8DAC800A1FB15 /* Frameworks */, @@ -624,6 +676,7 @@ A5A4FC722840C12C00BBEC1E /* UITests.xctest */, A5E03DED286464DB00888481 /* IntegrationTests.xctest */, A58E7CE828729F550082D443 /* Showcase.app */, + 84B767762954554A00E92316 /* PushDecryptionService.appex */, C56EE21B293F55ED004840D1 /* WalletApp.app */, ); name = Products; @@ -694,6 +747,16 @@ path = Push; sourceTree = ""; }; + 84B767772954554A00E92316 /* PushDecryptionService */ = { + isa = PBXGroup; + children = ( + 8414FC832962F3D9007E20C9 /* PushDecryptionService.entitlements */, + 84B767782954554A00E92316 /* NotificationService.swift */, + 84B7677A2954554A00E92316 /* Info.plist */, + ); + path = PushDecryptionService; + sourceTree = ""; + }; 84CE641D27981DED00142511 /* DApp */ = { isa = PBXGroup; children = ( @@ -1218,6 +1281,7 @@ isa = PBXGroup; children = ( A5A4FC762840C12C00BBEC1E /* RegressionTests.swift */, + 8485617E295307C20064877B /* PushNotificationTests.swift */, ); path = Regression; sourceTree = ""; @@ -1266,25 +1330,25 @@ path = Welcome; sourceTree = ""; }; - C55D349E2965FAC30004314A /* SessionRequest */ = { + C55D349E2965FAC30004314A /* SessionProposal */ = { isa = PBXGroup; children = ( - C55D34B32965FF750004314A /* Modela */, - C55D34A92965FB750004314A /* SessionRequestModule.swift */, - C55D34AA2965FB750004314A /* SessionRequestPresenter.swift */, - C55D34AB2965FB750004314A /* SessionRequestRouter.swift */, - C55D34AC2965FB750004314A /* SessionRequestInteractor.swift */, - C55D34AD2965FB750004314A /* SessionRequestView.swift */, + C55D34B32965FF750004314A /* Models */, + C55D34A92965FB750004314A /* SessionProposalModule.swift */, + C55D34AA2965FB750004314A /* SessionProposalPresenter.swift */, + C55D34AB2965FB750004314A /* SessionProposalRouter.swift */, + C55D34AC2965FB750004314A /* SessionProposalInteractor.swift */, + C55D34AD2965FB750004314A /* SessionProposalView.swift */, ); - path = SessionRequest; + path = SessionProposal; sourceTree = ""; }; - C55D34B32965FF750004314A /* Modela */ = { + C55D34B32965FF750004314A /* Models */ = { isa = PBXGroup; children = ( C55D349C2965F8D30004314A /* Proposal.swift */, ); - path = Modela; + path = Models; sourceTree = ""; }; C56EE21C293F55ED004840D1 /* WalletApp */ = { @@ -1301,9 +1365,10 @@ C56EE229293F5668004840D1 /* Wallet */ = { isa = PBXGroup; children = ( - C55D349E2965FAC30004314A /* SessionRequest */, C55D3477295DD4AA0004314A /* Welcome */, C55D3474295DCB850004314A /* AuthRequest */, + C55D349E2965FAC30004314A /* SessionProposal */, + C5B2F6F029705111000DBA0E /* SessionRequest */, C55D3471295DC5F60004314A /* PasteUri */, C5F32A2A2954812900A6476E /* ConnectionDetails */, C56EE236293F566A004840D1 /* Scan */, @@ -1351,7 +1416,6 @@ isa = PBXGroup; children = ( C56EE25D293F56D6004840D1 /* InputConfig.swift */, - C56EE265293F56D6004840D1 /* Types */, C56EE267293F56D6004840D1 /* Style */, C56EE2A1293F6B9E004840D1 /* Helpers */, C56EE262293F56D6004840D1 /* Extensions */, @@ -1377,14 +1441,6 @@ path = VIPER; sourceTree = ""; }; - C56EE265293F56D6004840D1 /* Types */ = { - isa = PBXGroup; - children = ( - C56EE266293F56D6004840D1 /* Types.swift */, - ); - path = Types; - sourceTree = ""; - }; C56EE267293F56D6004840D1 /* Style */ = { isa = PBXGroup; children = ( @@ -1461,6 +1517,18 @@ path = Helpers; sourceTree = ""; }; + C5B2F6F029705111000DBA0E /* SessionRequest */ = { + isa = PBXGroup; + children = ( + C5B2F6F12970511B000DBA0E /* SessionRequestModule.swift */, + C5B2F6F22970511B000DBA0E /* SessionRequestPresenter.swift */, + C5B2F6F32970511B000DBA0E /* SessionRequestRouter.swift */, + C5B2F6F42970511B000DBA0E /* SessionRequestInteractor.swift */, + C5B2F6F52970511B000DBA0E /* SessionRequestView.swift */, + ); + path = SessionRequest; + sourceTree = ""; + }; C5F32A2A2954812900A6476E /* ConnectionDetails */ = { isa = PBXGroup; children = ( @@ -1483,10 +1551,12 @@ 764E1D3826F8D3FC00A1FB15 /* Sources */, 764E1D3926F8D3FC00A1FB15 /* Frameworks */, 764E1D3A26F8D3FC00A1FB15 /* Resources */, + 84B7677E2954554A00E92316 /* Embed Foundation Extensions */, ); buildRules = ( ); dependencies = ( + 84B7677C2954554A00E92316 /* PBXTargetDependency */, ); name = Wallet; packageProductDependencies = ( @@ -1497,13 +1567,32 @@ A5434022291E6A270068F706 /* SolanaSwift */, 849D7A8F292665D3006A2BD4 /* WalletConnectVerify */, 840BCF132949B9F900CB0655 /* WalletConnectPush */, - 840BCF152949C6C100CB0655 /* WalletConnectEcho */, 8485617C295079730064877B /* WalletConnectPairing */, ); productName = ExampleApp; productReference = 764E1D3C26F8D3FC00A1FB15 /* WalletConnect Wallet.app */; productType = "com.apple.product-type.application"; }; + 84B767752954554A00E92316 /* PushDecryptionService */ = { + isa = PBXNativeTarget; + buildConfigurationList = 84B767812954554A00E92316 /* Build configuration list for PBXNativeTarget "PushDecryptionService" */; + buildPhases = ( + 84B767722954554A00E92316 /* Sources */, + 84B767732954554A00E92316 /* Frameworks */, + 84B767742954554A00E92316 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PushDecryptionService; + packageProductDependencies = ( + 84B76788295494D500E92316 /* WalletConnectPush */, + ); + productName = PushDecryptionService; + productReference = 84B767762954554A00E92316 /* PushDecryptionService.appex */; + productType = "com.apple.product-type.app-extension"; + }; 84CE641B27981DED00142511 /* DApp */ = { isa = PBXNativeTarget; buildConfigurationList = 84CE642F27981DF000142511 /* Build configuration list for PBXNativeTarget "DApp" */; @@ -1614,6 +1703,7 @@ C56EE27C293F56F8004840D1 /* WalletConnectChat */, C5133A77294125CC00A8314C /* Web3 */, C55D349829630D440004314A /* Web3Wallet */, + C5B2F7042970573D000DBA0E /* SolanaSwift */, ); productName = ChatWallet; productReference = C56EE21B293F55ED004840D1 /* WalletApp.app */; @@ -1625,12 +1715,15 @@ 764E1D3426F8D3FC00A1FB15 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1410; + LastSwiftUpdateCheck = 1420; LastUpgradeCheck = 1250; TargetAttributes = { 764E1D3B26F8D3FC00A1FB15 = { CreatedOnToolsVersion = 12.5.1; }; + 84B767752954554A00E92316 = { + CreatedOnToolsVersion = 14.2; + }; 84CE641B27981DED00142511 = { CreatedOnToolsVersion = 13.2; }; @@ -1671,6 +1764,7 @@ A5A4FC712840C12C00BBEC1E /* UITests */, A5E03DEC286464DB00888481 /* IntegrationTests */, A58E7CE728729F550082D443 /* Showcase */, + 84B767752954554A00E92316 /* PushDecryptionService */, C56EE21A293F55ED004840D1 /* WalletApp */, ); }; @@ -1686,6 +1780,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 84B767742954554A00E92316 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 84CE641A27981DED00142511 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1765,6 +1866,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 84B767722954554A00E92316 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 84B767792954554A00E92316 /* NotificationService.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 84CE641827981DED00142511 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1869,6 +1978,7 @@ buildActionMask = 2147483647; files = ( A5E22D202840C8C700E36487 /* DAppEngine.swift in Sources */, + 8485617F295307C20064877B /* PushNotificationTests.swift in Sources */, A5E22D1E2840C8BF00E36487 /* RoutingEngine.swift in Sources */, A5E22D222840C8D300E36487 /* WalletEngine.swift in Sources */, A5E22D1C2840C85D00E36487 /* App.swift in Sources */, @@ -1917,11 +2027,11 @@ C55D3480295DD7140004314A /* AuthRequestPresenter.swift in Sources */, C5F32A2E2954814A00A6476E /* ConnectionDetailsRouter.swift in Sources */, C55D3482295DD7140004314A /* AuthRequestInteractor.swift in Sources */, - C55D34B12965FB750004314A /* SessionRequestInteractor.swift in Sources */, + C55D34B12965FB750004314A /* SessionProposalInteractor.swift in Sources */, C56EE247293F566D004840D1 /* ScanModule.swift in Sources */, C56EE28D293F5757004840D1 /* AppearanceConfigurator.swift in Sources */, + C5B2F7112970583B000DBA0E /* SessionInfo.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 */, @@ -1929,7 +2039,9 @@ C55D348B295DD8CA0004314A /* PasteUriRouter.swift in Sources */, C55D348C295DD8CA0004314A /* PasteUriInteractor.swift in Sources */, C55D3497295DFA750004314A /* WelcomeView.swift in Sources */, + C5B2F71029705827000DBA0E /* EthereumTransaction.swift in Sources */, C56EE271293F56D7004840D1 /* View.swift in Sources */, + C5B2F6FD297055B0000DBA0E /* Signer.swift in Sources */, C56EE24D293F566D004840D1 /* WalletRouter.swift in Sources */, C5F32A342954817600A6476E /* ConnectionDetailsView.swift in Sources */, C55D348A295DD8CA0004314A /* PasteUriPresenter.swift in Sources */, @@ -1945,11 +2057,13 @@ 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 */, + C5B2F6FA29705293000DBA0E /* SessionRequestInteractor.swift in Sources */, + C55D34AE2965FB750004314A /* SessionProposalModule.swift in Sources */, + C55D34B02965FB750004314A /* SessionProposalRouter.swift in Sources */, C55D3495295DFA750004314A /* WelcomeRouter.swift in Sources */, + C5B2F6F729705293000DBA0E /* SessionRequestRouter.swift in Sources */, C56EE24F293F566D004840D1 /* WalletView.swift in Sources */, - C55D34B22965FB750004314A /* SessionRequestView.swift in Sources */, + C55D34B22965FB750004314A /* SessionProposalView.swift in Sources */, C56EE248293F566D004840D1 /* ScanQR.swift in Sources */, C55D349B2965BC2F0004314A /* TagsView.swift in Sources */, C56EE289293F5757004840D1 /* Application.swift in Sources */, @@ -1958,18 +2072,23 @@ C56EE246293F566D004840D1 /* ScanRouter.swift in Sources */, C55D349D2965F8D40004314A /* Proposal.swift in Sources */, C55D3481295DD7140004314A /* AuthRequestRouter.swift in Sources */, + C5B2F6F829705293000DBA0E /* SessionRequestView.swift in Sources */, C56EE28C293F5757004840D1 /* Configurator.swift in Sources */, C55D3489295DD8CA0004314A /* PasteUriModule.swift in Sources */, C55D3494295DFA750004314A /* WelcomePresenter.swift in Sources */, + C5B2F6F929705293000DBA0E /* SessionRequestPresenter.swift in Sources */, + C5B2F6FB297055B0000DBA0E /* ETHSigner.swift in Sources */, C56EE274293F56D7004840D1 /* SceneViewController.swift in Sources */, C55D3496295DFA750004314A /* WelcomeInteractor.swift in Sources */, + C5B2F6FC297055B0000DBA0E /* SOLSigner.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 */, + C5B2F6F629705293000DBA0E /* SessionRequestModule.swift in Sources */, C56EE24E293F566D004840D1 /* WalletInteractor.swift in Sources */, - C55D34AF2965FB750004314A /* SessionRequestPresenter.swift in Sources */, + C55D34AF2965FB750004314A /* SessionProposalPresenter.swift in Sources */, C5F32A302954816100A6476E /* ConnectionDetailsInteractor.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1977,6 +2096,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 84B7677C2954554A00E92316 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 84B767752954554A00E92316 /* PushDecryptionService */; + targetProxy = 84B7677B2954554A00E92316 /* PBXContainerItemProxy */; + }; A5A4FC7E2840C5D400BBEC1E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 84CE641B27981DED00142511 /* DApp */; @@ -2139,6 +2263,7 @@ 764E1D5126F8D3FE00A1FB15 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Wallet.entitlements; @@ -2164,6 +2289,7 @@ 764E1D5226F8D3FE00A1FB15 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Wallet.entitlements; @@ -2186,6 +2312,64 @@ }; name = Release; }; + 84B7677F2954554A00E92316 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_ENTITLEMENTS = PushDecryptionService/PushDecryptionService.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W5R8AG9K22; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = PushDecryptionService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = PushDecryptionService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.example.PushDecryptionService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 84B767802954554A00E92316 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_ENTITLEMENTS = PushDecryptionService/PushDecryptionService.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W5R8AG9K22; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = PushDecryptionService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = PushDecryptionService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.example.PushDecryptionService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 84CE642D27981DF000142511 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2474,6 +2658,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 84B767812954554A00E92316 /* Build configuration list for PBXNativeTarget "PushDecryptionService" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 84B7677F2954554A00E92316 /* Debug */, + 84B767802954554A00E92316 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 84CE642F27981DF000142511 /* Build configuration list for PBXNativeTarget "DApp" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -2557,10 +2750,6 @@ isa = XCSwiftPackageProductDependency; productName = WalletConnectPush; }; - 840BCF152949C6C100CB0655 /* WalletConnectEcho */ = { - isa = XCSwiftPackageProductDependency; - productName = WalletConnectEcho; - }; 8448F1D327E4726F0000B866 /* WalletConnect */ = { isa = XCSwiftPackageProductDependency; productName = WalletConnect; @@ -2577,6 +2766,10 @@ isa = XCSwiftPackageProductDependency; productName = WalletConnectVerify; }; + 84B76788295494D500E92316 /* WalletConnectPush */ = { + isa = XCSwiftPackageProductDependency; + productName = WalletConnectPush; + }; 84DDB4EC28ABB663003D66ED /* WalletConnectAuth */ = { isa = XCSwiftPackageProductDependency; productName = WalletConnectAuth; @@ -2672,6 +2865,11 @@ isa = XCSwiftPackageProductDependency; productName = WalletConnectChat; }; + C5B2F7042970573D000DBA0E /* SolanaSwift */ = { + isa = XCSwiftPackageProductDependency; + package = A5434021291E6A270068F706 /* XCRemoteSwiftPackageReference "solana-swift" */; + productName = SolanaSwift; + }; C5DD5BE0294E09E3008FD3A4 /* Web3Wallet */ = { isa = XCSwiftPackageProductDependency; productName = Web3Wallet; diff --git a/Example/ExampleApp/AppDelegate.swift b/Example/ExampleApp/AppDelegate.swift index 8e4872106..bdf63d927 100644 --- a/Example/ExampleApp/AppDelegate.swift +++ b/Example/ExampleApp/AppDelegate.swift @@ -1,7 +1,6 @@ import UIKit import UserNotifications import WalletConnectNetworking -import WalletConnectEcho import WalletConnectPairing import WalletConnectPush import Combine @@ -23,13 +22,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { Networking.configure(projectId: InputConfig.projectId, socketFactory: DefaultSocketFactory()) Pair.configure(metadata: metadata) - let clientId = try! Networking.interactor.getClientId() - let sanitizedClientId = clientId.replacingOccurrences(of: "did:key:", with: "") - - Echo.configure(projectId: InputConfig.projectId, clientId: sanitizedClientId) - Push.wallet.requestPublisher.sink { id, _ in + Push.configure() + Push.wallet.requestPublisher.sink { (id: RPCID, account: Account, metadata: AppMetadata) in Task(priority: .high) { try! await Push.wallet.approve(id: id) } }.store(in: &publishers) + Push.wallet.pushMessagePublisher.sink { pm in print(pm) }.store(in: &publishers) @@ -61,20 +58,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate { .requestAuthorization( options: [.alert, .sound, .badge]) { [weak self] granted, _ in print("Permission granted: \(granted)") - guard granted else { return } - self?.getNotificationSettings() - #if targetEnvironment(simulator) - -// let clientId = try! Networking.interactor.socketConnectionStatusPublisher -// .first {$0 == .connected} -// .sink(receiveValue: { status in -// let deviceToken = InputConfig.simulatorIdentifier -// assert(deviceToken != "SIMULATOR_IDENTIFIER", "Please set your Simulator identifier") -// Task(priority: .high) { -// try await Echo.instance.register(deviceToken: deviceToken) -// } -// }) - #endif + guard granted else { return } + self?.getNotificationSettings() +#if targetEnvironment(simulator) + Networking.interactor.socketConnectionStatusPublisher + .first {$0 == .connected} + .sink{ status in + let deviceToken = InputConfig.simulatorIdentifier + assert(deviceToken != "SIMULATOR_IDENTIFIER", "Please set your Simulator identifier") + Task(priority: .high) { + try await Push.wallet.register(deviceToken: deviceToken) + } + }.store(in: &self!.publishers) +#endif } } @@ -90,7 +86,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data ) { Task(priority: .high) { - try await Echo.instance.register(deviceToken: deviceToken) + try await Push.wallet.register(deviceToken: deviceToken) } } @@ -101,5 +97,5 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // TODO: when is this invoked? print("Failed to register: \(error)") } - } + diff --git a/Example/IntegrationTests/Pairing/PairingTests.swift b/Example/IntegrationTests/Pairing/PairingTests.swift index 1952af7e4..8390e4e38 100644 --- a/Example/IntegrationTests/Pairing/PairingTests.swift +++ b/Example/IntegrationTests/Pairing/PairingTests.swift @@ -73,6 +73,7 @@ final class PairingTests: XCTestCase { walletPushClient = WalletPushClientFactory.create(logger: pushLogger, keyValueStorage: keyValueStorage, keychainStorage: keychain, + groupKeychainStorage: KeychainStorageMock(), networkInteractor: networkingInteractor, pairingRegisterer: pairingClient, echoClient: echoClient) diff --git a/Example/IntegrationTests/Push/PushTests.swift b/Example/IntegrationTests/Push/PushTests.swift index e004b6abd..123549b51 100644 --- a/Example/IntegrationTests/Push/PushTests.swift +++ b/Example/IntegrationTests/Push/PushTests.swift @@ -73,6 +73,7 @@ final class PushTests: XCTestCase { walletPushClient = WalletPushClientFactory.create(logger: pushLogger, keyValueStorage: keyValueStorage, keychainStorage: keychain, + groupKeychainStorage: KeychainStorageMock(), networkInteractor: networkingInteractor, pairingRegisterer: pairingClient, echoClient: echoClient) @@ -90,7 +91,7 @@ final class PushTests: XCTestCase { try! await walletPairingClient.pair(uri: uri) try! await dappPushClient.request(account: Account.stub(), topic: uri.topic) - walletPushClient.requestPublisher.sink { (_, _) in + walletPushClient.requestPublisher.sink { (_, _, _) in expectation.fulfill() } .store(in: &publishers) @@ -104,7 +105,7 @@ final class PushTests: XCTestCase { try! await walletPairingClient.pair(uri: uri) try! await dappPushClient.request(account: Account.stub(), topic: uri.topic) - walletPushClient.requestPublisher.sink { [unowned self] (id, _) in + walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in Task(priority: .high) { try! await walletPushClient.approve(id: id) } }.store(in: &publishers) @@ -127,7 +128,7 @@ final class PushTests: XCTestCase { try! await walletPairingClient.pair(uri: uri) try! await dappPushClient.request(account: Account.stub(), topic: uri.topic) - walletPushClient.requestPublisher.sink { [unowned self] (id, _) in + walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in Task(priority: .high) { try! await walletPushClient.reject(id: id) } }.store(in: &publishers) @@ -150,7 +151,7 @@ final class PushTests: XCTestCase { try! await walletPairingClient.pair(uri: uri) try! await dappPushClient.request(account: Account.stub(), topic: uri.topic) - walletPushClient.requestPublisher.sink { [unowned self] (id, _) in + walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in Task(priority: .high) { try! await walletPushClient.approve(id: id) } }.store(in: &publishers) @@ -178,7 +179,7 @@ final class PushTests: XCTestCase { try! await dappPushClient.request(account: Account.stub(), topic: uri.topic) var subscriptionTopic: String! - walletPushClient.requestPublisher.sink { [unowned self] (id, _) in + walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in Task(priority: .high) { try! await walletPushClient.approve(id: id) } }.store(in: &publishers) @@ -205,7 +206,7 @@ final class PushTests: XCTestCase { try! await dappPushClient.request(account: Account.stub(), topic: uri.topic) var subscriptionTopic: String! - walletPushClient.requestPublisher.sink { [unowned self] (id, _) in + walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in Task(priority: .high) { try! await walletPushClient.approve(id: id) } }.store(in: &publishers) diff --git a/Example/PushDecryptionService/Info.plist b/Example/PushDecryptionService/Info.plist new file mode 100644 index 000000000..57421ebf9 --- /dev/null +++ b/Example/PushDecryptionService/Info.plist @@ -0,0 +1,13 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).NotificationService + + + diff --git a/Example/PushDecryptionService/NotificationService.swift b/Example/PushDecryptionService/NotificationService.swift new file mode 100644 index 000000000..737026677 --- /dev/null +++ b/Example/PushDecryptionService/NotificationService.swift @@ -0,0 +1,42 @@ +// + +import UserNotifications +import WalletConnectPush + +class NotificationService: UNNotificationServiceExtension { + + var contentHandler: ((UNNotificationContent) -> Void)? + var bestAttemptContent: UNMutableNotificationContent? + + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { + self.contentHandler = contentHandler + bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) + if let bestAttemptContent = bestAttemptContent { + let topic = bestAttemptContent.userInfo["topic"] as! String + let ciphertext = bestAttemptContent.userInfo["ciphertext"] as! String + do { + let service = PushDecryptionService() + let pushMessage = try service.decryptMessage(topic: topic, ciphertext: ciphertext) + bestAttemptContent.title = pushMessage.title + bestAttemptContent.body = pushMessage.body + contentHandler(bestAttemptContent) + return + } + catch { + print(error) + } + bestAttemptContent.title = "" + bestAttemptContent.body = "content not set" + contentHandler(bestAttemptContent) + } + } + + override func serviceExtensionTimeWillExpire() { + // Called just before the extension will be terminated by the system. + // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. + if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { + contentHandler(bestAttemptContent) + } + } + +} diff --git a/Example/PushDecryptionService/PushDecryptionService.entitlements b/Example/PushDecryptionService/PushDecryptionService.entitlements new file mode 100644 index 000000000..0bd7a7310 --- /dev/null +++ b/Example/PushDecryptionService/PushDecryptionService.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.application-groups + + group.com.walletconnect.sdk + + + diff --git a/Example/UITests/Regression/PushNotificationTests.swift b/Example/UITests/Regression/PushNotificationTests.swift new file mode 100644 index 000000000..c37df7a66 --- /dev/null +++ b/Example/UITests/Regression/PushNotificationTests.swift @@ -0,0 +1,21 @@ + +import XCTest + +class PushNotificationTests: XCTestCase { + let wallet = XCUIApplication(bundleIdentifier: "com.walletconnect.example") + let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard") + + func testPushNotification() { + wallet.launch() + + sleep(1) + + // Launch springboard + springboard.activate() + let text = "Is this working" + + let notification = springboard.otherElements["Notification"].descendants(matching: .any)["NotificationShortLookView"] + XCTAssertTrue(notification.waitForExistence(timeout: 5)) + notification.tap() + } +} diff --git a/Example/UITests/Regression/RegressionTests.swift b/Example/UITests/Regression/RegressionTests.swift index 6b5047e9c..201957a47 100644 --- a/Example/UITests/Regression/RegressionTests.swift +++ b/Example/UITests/Regression/RegressionTests.swift @@ -1,7 +1,6 @@ import XCTest class PairingTests: XCTestCase { - private let engine: Engine = Engine() override class func setUp() { diff --git a/Example/Wallet.entitlements b/Example/Wallet.entitlements index 55235d503..403118be1 100644 --- a/Example/Wallet.entitlements +++ b/Example/Wallet.entitlements @@ -8,5 +8,9 @@ applinks:walletconnect.com + com.apple.security.application-groups + + group.com.walletconnect.sdk + diff --git a/Example/WalletApp/Common/Types/Types.swift b/Example/WalletApp/Common/Types/Types.swift deleted file mode 100644 index 3df10ee8a..000000000 --- a/Example/WalletApp/Common/Types/Types.swift +++ /dev/null @@ -1,3 +0,0 @@ -import WalletConnectUtils - -typealias Account = WalletConnectUtils.Account diff --git a/Example/WalletApp/Other/Assets.xcassets/welcome-dark.imageset/Contents.json b/Example/WalletApp/Other/Assets.xcassets/welcome-dark.imageset/Contents.json new file mode 100644 index 000000000..24c3bb490 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/welcome-dark.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "welcome-dark.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/welcome-dark.imageset/welcome-dark.pdf b/Example/WalletApp/Other/Assets.xcassets/welcome-dark.imageset/welcome-dark.pdf new file mode 100644 index 000000000..c3e3876e8 Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/welcome-dark.imageset/welcome-dark.pdf differ diff --git a/Example/WalletApp/Other/Assets.xcassets/welcome-light.imageset/Contents.json b/Example/WalletApp/Other/Assets.xcassets/welcome-light.imageset/Contents.json new file mode 100644 index 000000000..9033367f0 --- /dev/null +++ b/Example/WalletApp/Other/Assets.xcassets/welcome-light.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "welcome-light.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/WalletApp/Other/Assets.xcassets/welcome-light.imageset/welcome-light.pdf b/Example/WalletApp/Other/Assets.xcassets/welcome-light.imageset/welcome-light.pdf new file mode 100644 index 000000000..8ceb993aa Binary files /dev/null and b/Example/WalletApp/Other/Assets.xcassets/welcome-light.imageset/welcome-light.pdf differ diff --git a/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestView.swift b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestView.swift index 93a602fb2..00086e83b 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestView.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/AuthRequest/AuthRequestView.swift @@ -107,15 +107,14 @@ struct AuthRequestView: View { .padding(.top, 9) VStack(spacing: 0) { - HStack { + ScrollView { Text(presenter.message) .foregroundColor(.grey50) .font(.system(size: 13, weight: .semibold, design: .rounded)) - - Spacer() } .padding(.horizontal, 18) .padding(.vertical, 10) + .frame(height: 250) } .background(Color.whiteBackground) .cornerRadius(20, corners: .allCorners) diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/Modela/Proposal.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/Models/Proposal.swift similarity index 100% rename from Example/WalletApp/PresentationLayer/Wallet/SessionRequest/Modela/Proposal.swift rename to Example/WalletApp/PresentationLayer/Wallet/SessionProposal/Models/Proposal.swift diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalInteractor.swift new file mode 100644 index 000000000..c88d43aef --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalInteractor.swift @@ -0,0 +1,32 @@ +import Foundation + +import Web3Wallet + +final class SessionProposalInteractor { + lazy var accounts = [ + "eip155": ETHSigner.address, + "solana": SOLSigner.address + ] + + 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 + ":\(self.accounts[$0.namespace]!)") }) + + let extensions: [SessionNamespace.Extension]? = proposalNamespace.extensions?.map { element in + let accounts = Set(element.chains.compactMap { Account($0.absoluteString + ":\(self.accounts[$0.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) + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalModule.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalModule.swift new file mode 100644 index 000000000..4f0736d0a --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalModule.swift @@ -0,0 +1,22 @@ +import SwiftUI + +import Web3Wallet + +final class SessionProposalModule { + @discardableResult + static func create(app: Application, proposal: Session.Proposal) -> UIViewController { + let router = SessionProposalRouter(app: app) + let interactor = SessionProposalInteractor() + let presenter = SessionProposalPresenter( + interactor: interactor, + router: router, + proposal: proposal + ) + let view = SessionProposalView().environmentObject(presenter) + let viewController = SceneViewController(viewModel: presenter, content: view) + + router.viewController = viewController + + return viewController + } +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalPresenter.swift new file mode 100644 index 000000000..8e8b6b564 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalPresenter.swift @@ -0,0 +1,50 @@ +import UIKit +import Combine + +import Web3Wallet + +final class SessionProposalPresenter: ObservableObject { + private let interactor: SessionProposalInteractor + private let router: SessionProposalRouter + + let proposal: Proposal + private let sessionProposal: Session.Proposal + + private var disposeBag = Set() + + init( + interactor: SessionProposalInteractor, + router: SessionProposalRouter, + 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 SessionProposalPresenter { + func setupInitialState() { + + } +} + +// MARK: - SceneViewModel +extension SessionProposalPresenter: SceneViewModel { + +} diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalRouter.swift new file mode 100644 index 000000000..cd9de7971 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalRouter.swift @@ -0,0 +1,15 @@ +import UIKit + +final class SessionProposalRouter { + 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/SessionProposal/SessionProposalView.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalView.swift new file mode 100644 index 000000000..b8b3fc9e6 --- /dev/null +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalView.swift @@ -0,0 +1,175 @@ +import SwiftUI + +struct SessionProposalView: View { + @EnvironmentObject var presenter: SessionProposalPresenter + + @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 SessionProposalView_Previews: PreviewProvider { + static var previews: some View { + SessionProposalView() + } +} +#endif diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestInteractor.swift index bdc73d3c1..dce7d5fca 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestInteractor.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestInteractor.swift @@ -1,37 +1,21 @@ 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 approve(sessionRequest: Request) async throws { + let result = Signer.sign(request: sessionRequest) + try await Web3Wallet.instance.respond( + topic: sessionRequest.topic, + requestId: sessionRequest.id, + response: .response(result) + ) } - func formatted(request: AuthRequest) -> String { - return try! Web3Wallet.instance.formatMessage( - payload: request.payload, - address: account.address + func reject(sessionRequest: Request) async throws { + try await Web3Wallet.instance.respond( + topic: sessionRequest.topic, + requestId: sessionRequest.id, + response: .error(.init(code: 0, message: "")) ) } } diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestModule.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestModule.swift index d547d6291..7c1aca962 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestModule.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestModule.swift @@ -1,22 +1,17 @@ import SwiftUI - import Web3Wallet final class SessionRequestModule { @discardableResult - static func create(app: Application, proposal: Session.Proposal) -> UIViewController { + static func create(app: Application, sessionRequest: Request) -> UIViewController { let router = SessionRequestRouter(app: app) let interactor = SessionRequestInteractor() - let presenter = SessionRequestPresenter( - interactor: interactor, - router: router, - proposal: proposal - ) + let presenter = SessionRequestPresenter(interactor: interactor, router: router, sessionRequest: sessionRequest) 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 index a32d957fc..bdff02f2b 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestPresenter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestPresenter.swift @@ -7,32 +7,34 @@ final class SessionRequestPresenter: ObservableObject { private let interactor: SessionRequestInteractor private let router: SessionRequestRouter - let proposal: Proposal - private let sessionProposal: Session.Proposal + let sessionRequest: Request + + var message: String { + return String(describing: sessionRequest.params.value) + } private var disposeBag = Set() init( interactor: SessionRequestInteractor, router: SessionRequestRouter, - proposal: Session.Proposal + sessionRequest: Request ) { defer { setupInitialState() } self.interactor = interactor self.router = router - self.proposal = Proposal(proposal: proposal) - self.sessionProposal = proposal + self.sessionRequest = sessionRequest } - + @MainActor func onApprove() async throws { - try await interactor.approve(proposal: sessionProposal) + try await interactor.approve(sessionRequest: sessionRequest) router.dismiss() } @MainActor func onReject() async throws { - try await interactor.reject(proposal: sessionProposal) + try await interactor.reject(sessionRequest: sessionRequest) router.dismiss() } } diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestView.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestView.swift index 6af49c1c9..053cb34c2 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestView.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestView.swift @@ -17,23 +17,12 @@ struct SessionRequestView: View { .resizable() .scaledToFit() - Text(presenter.proposal.proposerName) + Text(presenter.sessionRequest.method) .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() + authRequestView() HStack(spacing: 20) { Button { @@ -93,10 +82,10 @@ struct SessionRequestView: View { .edgesIgnoringSafeArea(.all) } - private func sessionProposalView() -> some View { + private func authRequestView() -> some View { VStack { VStack(alignment: .leading) { - Text(presenter.proposal.permissions.first?.chains.first ?? "Chain") + Text("Message") .font(.system(size: 15, weight: .semibold, design: .rounded)) .foregroundColor(.whiteBackground) .padding(.horizontal, 8) @@ -107,57 +96,20 @@ struct SessionRequestView: View { .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") + ScrollView { + Text(presenter.message) .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) + .padding(.vertical, 10) + .frame(height: 250) } .background(Color.whiteBackground) .cornerRadius(20, corners: .allCorners) .padding(.horizontal, 5) .padding(.bottom, 5) + } .background(.thinMaterial) .cornerRadius(25, corners: .allCorners) diff --git a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletInteractor.swift index e17234aa5..b79c6b255 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletInteractor.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletInteractor.swift @@ -11,6 +11,10 @@ final class WalletInteractor { return Web3Wallet.instance.sessionProposalPublisher } + var sessionRequestPublisher: AnyPublisher { + return Web3Wallet.instance.sessionRequestPublisher + } + var sessionsPublisher: AnyPublisher<[Session], Never> { return Web3Wallet.instance.sessionsPublisher } @@ -22,4 +26,8 @@ final class WalletInteractor { 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/Wallet/WalletPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletPresenter.swift index 24a540b3a..e6e677d8e 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletPresenter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletPresenter.swift @@ -59,20 +59,32 @@ final class WalletPresenter: ObservableObject { // MARK: - Private functions extension WalletPresenter { private func setupInitialState() { - interactor.requestPublisher.sink { [weak self] request in - self?.router.present(request: request) - } - .store(in: &disposeBag) + interactor.requestPublisher + .receive(on: DispatchQueue.main) + .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.sessionRequestPublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] sessionRequest in + self?.router.present(sessionRequest: sessionRequest) + }.store(in: &disposeBag) + + interactor.sessionProposalPublisher + .receive(on: DispatchQueue.main) + .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) + interactor.sessionsPublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] sessions in + self?.sessions = sessions + } + .store(in: &disposeBag) sessions = interactor.getSessions() @@ -93,6 +105,12 @@ extension WalletPresenter { } pair(uri: walletConnectUri) } + + func removeSession(at indexSet: IndexSet) async { + if let index = indexSet.first { + try? await interactor.disconnectSession(session: sessions[index]) + } + } } // MARK: - SceneViewModel diff --git a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletRouter.swift index 221f328ce..c32bfd8d3 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletRouter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletRouter.swift @@ -17,7 +17,12 @@ final class WalletRouter { } func present(proposal: Session.Proposal) { - SessionRequestModule.create(app: app, proposal: proposal) + SessionProposalModule.create(app: app, proposal: proposal) + .presentFullScreen(from: viewController, transparentBackground: true) + } + + func present(sessionRequest: Request) { + SessionRequestModule.create(app: app, sessionRequest: sessionRequest) .presentFullScreen(from: viewController, transparentBackground: true) } diff --git a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletView.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletView.swift index 6cd276a1c..a465e86d3 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletView.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletView.swift @@ -21,15 +21,24 @@ struct WalletView: View { .multilineTextAlignment(.center) .lineSpacing(4) } + .padding(20) } VStack { if !presenter.sessions.isEmpty { - ScrollView { + List { ForEach(presenter.sessions, id: \.peer.name) { session in connectionView(session: session) + .listRowSeparator(.hidden) + .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 16, trailing: 0)) + } + .onDelete { indexSet in + Task(priority: .high) { + await presenter.removeSession(at: indexSet) + } } } + .listStyle(PlainListStyle()) } Spacer() @@ -55,10 +64,11 @@ struct WalletView: View { } .shadow(color: .black.opacity(0.25), radius: 8, y: 4) } + .padding(.horizontal, 20) } } } - .padding(20) + .padding(.vertical, 20) } } @@ -81,6 +91,7 @@ struct WalletView: View { .cornerRadius(30, corners: .allCorners) } } + .padding(.leading, 20) VStack(alignment: .leading, spacing: 2) { Text(session.peer.name) @@ -96,6 +107,7 @@ struct WalletView: View { Image("forward-shevron") .foregroundColor(.grey8) + .padding(.trailing, 20) } } } diff --git a/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeView.swift b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeView.swift index 42c65d8e8..a0c8ab63a 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeView.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeView.swift @@ -1,6 +1,8 @@ import SwiftUI struct WelcomeView: View { + @Environment(\.colorScheme) var colorScheme + @EnvironmentObject var presenter: WelcomePresenter @State private var presentWallet = false @@ -10,6 +12,14 @@ struct WelcomeView: View { Color.grey100 .edgesIgnoringSafeArea(.all) + VStack { + Spacer() + + Image((colorScheme == .light) ? "welcome-light" : "welcome-dark") + .scaledToFill() + } + .edgesIgnoringSafeArea(.all) + VStack(spacing: 0) { Text("Welcome") .foregroundColor(.grey8) @@ -47,6 +57,7 @@ struct WelcomeView: View { .fullScreenCover(isPresented: $presentWallet, content: WalletView.init) } .padding([.horizontal, .vertical], 20) + .padding(.top, 20) } } } diff --git a/PNTest.apns b/PNTest.apns new file mode 100644 index 000000000..e89bc685e --- /dev/null +++ b/PNTest.apns @@ -0,0 +1,13 @@ +{ + "Simulator Target Bundle": "com.walletconnect.example", + + "aps": { + "badge": 0, + "alert": { + "title": "Push Notification Test", + "subtitle": "Hey! 👋", + "body": "Is this working?", + }, + "sound":"default" + } +} diff --git a/Sources/WalletConnectEcho/DecryptionService.swift b/Sources/WalletConnectEcho/DecryptionService.swift deleted file mode 100644 index f2297f84e..000000000 --- a/Sources/WalletConnectEcho/DecryptionService.swift +++ /dev/null @@ -1,13 +0,0 @@ -import WalletConnectKMS - -class DecryptionService { - private let serializer: Serializing - - init(serializer: Serializing) { - self.serializer = serializer - } - - public func decryptMessage(topic: String, ciphertext: String) throws -> String { - try serializer.deserialize(topic: topic, encodedEnvelope: ciphertext) - } -} diff --git a/Sources/WalletConnectEcho/Echo.swift b/Sources/WalletConnectEcho/Echo.swift index b876ef135..3921ffebc 100644 --- a/Sources/WalletConnectEcho/Echo.swift +++ b/Sources/WalletConnectEcho/Echo.swift @@ -1,4 +1,5 @@ import Foundation +import WalletConnectNetworking public class Echo { @@ -8,7 +9,7 @@ public class Echo { } return EchoClientFactory.create( - projectId: config.projectId, + projectId: Networking.projectId, clientId: config.clientId) }() @@ -17,9 +18,8 @@ public class Echo { private init() { } /// Echo instance config method - /// - Parameters: - /// - tenantId: - static public func configure(projectId: String, clientId: String) { - Echo.config = Echo.Config(clientId: clientId, projectId: projectId) + /// - Parameter clientId: https://github.com/WalletConnect/walletconnect-docs/blob/main/docs/specs/clients/core/relay/relay-client-auth.md#overview + static public func configure(clientId: String) { + Echo.config = Echo.Config(clientId: clientId) } } diff --git a/Sources/WalletConnectEcho/EchoClient.swift b/Sources/WalletConnectEcho/EchoClient.swift index 6f8dd022d..495b19939 100644 --- a/Sources/WalletConnectEcho/EchoClient.swift +++ b/Sources/WalletConnectEcho/EchoClient.swift @@ -3,19 +3,20 @@ import WalletConnectNetworking public class EchoClient { private let registerService: EchoRegisterService - private let decryptionService: DecryptionService - init(registerService: EchoRegisterService, - decryptionService: DecryptionService) { + init(registerService: EchoRegisterService) { self.registerService = registerService - self.decryptionService = decryptionService } public func register(deviceToken: Data) async throws { try await registerService.register(deviceToken: deviceToken) } - public func decryptMessage(topic: String, ciphertext: String) throws -> String { - try decryptionService.decryptMessage(topic: topic, ciphertext: ciphertext) +#if DEBUG + public func register(deviceToken: String) async throws { + try await registerService.register(deviceToken: deviceToken) } +#endif + + } diff --git a/Sources/WalletConnectEcho/EchoClientFactory.swift b/Sources/WalletConnectEcho/EchoClientFactory.swift index 0cda812cd..859b0d37f 100644 --- a/Sources/WalletConnectEcho/EchoClientFactory.swift +++ b/Sources/WalletConnectEcho/EchoClientFactory.swift @@ -4,30 +4,22 @@ import WalletConnectNetworking public struct EchoClientFactory { public static func create(projectId: String, clientId: String) -> EchoClient { - let keychainStorage = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk") + let httpClient = HTTPNetworkClient(host: "echo.walletconnect.com") return EchoClientFactory.create( projectId: projectId, clientId: clientId, - keychainStorage: keychainStorage) + httpClient: httpClient) } static func create(projectId: String, - clientId: String, - keychainStorage: KeychainStorageProtocol) -> EchoClient { - - let httpClient = HTTPNetworkClient(host: "echo.walletconnect.com") - - let registerService = EchoRegisterService(httpClient: httpClient, projectId: projectId, clientId: clientId) - - let kms = KeyManagementService(keychain: keychainStorage) - - let serializer = Serializer(kms: kms) + clientId: String, + httpClient: HTTPClient) -> EchoClient { - let decryptionService = DecryptionService(serializer: serializer) + let logger = ConsoleLogger(loggingLevel: .debug) + let registerService = EchoRegisterService(httpClient: httpClient, projectId: projectId, clientId: clientId, logger: logger) return EchoClient( - registerService: registerService, - decryptionService: decryptionService) + registerService: registerService) } } diff --git a/Sources/WalletConnectEcho/EchoConfig.swift b/Sources/WalletConnectEcho/EchoConfig.swift index e0a0cecbc..acd6ade9f 100644 --- a/Sources/WalletConnectEcho/EchoConfig.swift +++ b/Sources/WalletConnectEcho/EchoConfig.swift @@ -3,6 +3,5 @@ import Foundation extension Echo { struct Config { let clientId: String - let projectId: String } } diff --git a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift index d907656fd..c3e507af2 100644 --- a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift +++ b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift @@ -5,26 +5,48 @@ actor EchoRegisterService { private let httpClient: HTTPClient private let projectId: String private let clientId: String + private let logger: ConsoleLogging + // DID method specific identifier + private var clientIdMutlibase: String { + return clientId.replacingOccurrences(of: "did:key:", with: "") + } enum Errors: Error { case registrationFailed } - init(httpClient: HTTPClient, projectId: String, clientId: String) { + init(httpClient: HTTPClient, + projectId: String, + clientId: String, + logger: ConsoleLogging) { self.httpClient = httpClient self.clientId = clientId self.projectId = projectId + self.logger = logger } func register(deviceToken: Data) async throws { let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) } let token = tokenParts.joined() + logger.debug("APNS device token: \(token)") + let response = try await httpClient.request( + EchoResponse.self, + at: EchoAPI.register(clientId: clientIdMutlibase, token: token, projectId: projectId) + ) + guard response.status == .ok else { + throw Errors.registrationFailed + } + } + +#if DEBUG + public func register(deviceToken: String) async throws { let response = try await httpClient.request( EchoResponse.self, - at: EchoAPI.register(clientId: clientId, token: token, projectId: projectId) + at: EchoAPI.register(clientId: clientIdMutlibase, token: deviceToken, projectId: projectId) ) guard response.status == .ok else { throw Errors.registrationFailed } } +#endif } diff --git a/Sources/WalletConnectKMS/Keychain/GroupKeychainStorage.swift b/Sources/WalletConnectKMS/Keychain/GroupKeychainStorage.swift new file mode 100644 index 000000000..43c552c87 --- /dev/null +++ b/Sources/WalletConnectKMS/Keychain/GroupKeychainStorage.swift @@ -0,0 +1,104 @@ + +import Foundation + +public final class GroupKeychainStorage: KeychainStorageProtocol { + + private let accessGroup: String + + private let secItem: KeychainServiceProtocol + + public init(keychainService: KeychainServiceProtocol = KeychainServiceWrapper(), serviceIdentifier: String) { + self.secItem = keychainService + accessGroup = serviceIdentifier + } + + public func add(_ item: T, forKey key: String) throws where T: GenericPasswordConvertible { + try add(data: item.rawRepresentation, forKey: key) + } + + public func add(data: Data, forKey key: String) throws { + var query = buildBaseServiceQuery(for: key) + query[kSecValueData] = data + + let status = secItem.add(query as CFDictionary, nil) + + guard status != errSecDuplicateItem else { + return try update(data: data, forKey: key) + } + + guard status == errSecSuccess else { + throw KeychainError(status) + } + } + + public func read(key: String) throws -> T where T: GenericPasswordConvertible { + guard let data = try readData(key: key) else { + throw KeychainError(errSecItemNotFound) + } + return try T(rawRepresentation: data) + } + + public func readData(key: String) throws -> Data? { + var query = buildBaseServiceQuery(for: key) + query[kSecReturnData] = true + + var item: CFTypeRef? + let status = secItem.copyMatching(query as CFDictionary, &item) + + switch status { + case errSecSuccess: + return item as? Data + case errSecItemNotFound: + return nil + default: + throw KeychainError(status) + } + } + + public func update(_ item: T, forKey key: String) throws where T: GenericPasswordConvertible { + try update(data: item.rawRepresentation, forKey: key) + } + + public func update(data: Data, forKey key: String) throws { + let query = buildBaseServiceQuery(for: key) + let attributes = [kSecValueData: data] + + let status = secItem.update(query as CFDictionary, attributes as CFDictionary) + + guard status == errSecSuccess else { + throw KeychainError(status) + } + } + + public func delete(key: String) throws { + let query = buildBaseServiceQuery(for: key) + + let status = secItem.delete(query as CFDictionary) + + guard status == errSecSuccess || status == errSecItemNotFound else { + throw KeychainError(status) + } + } + + public func deleteAll() throws { + let query = [ + kSecClass: kSecClassGenericPassword, + kSecAttrService: accessGroup + ] as [String: Any] + let status = secItem.delete(query as CFDictionary) + guard status == errSecSuccess else { + throw KeychainError(status) + } + } + + private func buildBaseServiceQuery(for key: String) -> [CFString: Any] { + return [ + kSecClass: kSecClassGenericPassword, + kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly, + kSecAttrIsInvisible: true, + kSecUseDataProtectionKeychain: true, + kSecAttrAccessGroup: accessGroup, + kSecAttrAccount: key + ] + } +} diff --git a/Sources/WalletConnectNetworking/NetworkingInteractor.swift b/Sources/WalletConnectNetworking/NetworkingInteractor.swift index 9e72ba110..0b0e0f37e 100644 --- a/Sources/WalletConnectNetworking/NetworkingInteractor.swift +++ b/Sources/WalletConnectNetworking/NetworkingInteractor.swift @@ -1,6 +1,7 @@ import Foundation import Combine + public class NetworkingInteractor: NetworkInteracting { private var publishers = Set() private let relayClient: RelayClient diff --git a/Sources/WalletConnectPairing/PairingClient.swift b/Sources/WalletConnectPairing/PairingClient.swift index 41aabf244..389c11354 100644 --- a/Sources/WalletConnectPairing/PairingClient.swift +++ b/Sources/WalletConnectPairing/PairingClient.swift @@ -17,7 +17,7 @@ public class PairingClient: PairingRegisterer, PairingInteracting, PairingClient private let pairingRequestsSubscriber: PairingRequestsSubscriber private let pairingsProvider: PairingsProvider private let deletePairingService: DeletePairingService - private let resubscribeService: ResubscribeService + private let resubscribeService: PairingResubscribeService private let expirationService: ExpirationService private let cleanupService: PairingCleanupService @@ -27,7 +27,7 @@ public class PairingClient: PairingRegisterer, PairingInteracting, PairingClient logger: ConsoleLogging, walletPairService: WalletPairService, deletePairingService: DeletePairingService, - resubscribeService: ResubscribeService, + resubscribeService: PairingResubscribeService, expirationService: ExpirationService, pairingRequestsSubscriber: PairingRequestsSubscriber, appPairActivateService: AppPairActivationService, diff --git a/Sources/WalletConnectPairing/PairingClientFactory.swift b/Sources/WalletConnectPairing/PairingClientFactory.swift index 4efb67249..8666747ac 100644 --- a/Sources/WalletConnectPairing/PairingClientFactory.swift +++ b/Sources/WalletConnectPairing/PairingClientFactory.swift @@ -21,7 +21,7 @@ public struct PairingClientFactory { let pingService = PairingPingService(pairingStorage: pairingStore, networkingInteractor: networkingClient, logger: logger) let appPairActivateService = AppPairActivationService(pairingStorage: pairingStore, logger: logger) let expirationService = ExpirationService(pairingStorage: pairingStore, networkInteractor: networkingClient, kms: kms) - let resubscribeService = ResubscribeService(networkInteractor: networkingClient, pairingStorage: pairingStore) + let resubscribeService = PairingResubscribeService(networkInteractor: networkingClient, pairingStorage: pairingStore) return PairingClient( appPairService: appPairService, diff --git a/Sources/WalletConnectPairing/Services/Common/ResubscribeService.swift b/Sources/WalletConnectPairing/Services/Common/PairingResubscribeService.swift similarity index 95% rename from Sources/WalletConnectPairing/Services/Common/ResubscribeService.swift rename to Sources/WalletConnectPairing/Services/Common/PairingResubscribeService.swift index 6e51cad1d..32b139124 100644 --- a/Sources/WalletConnectPairing/Services/Common/ResubscribeService.swift +++ b/Sources/WalletConnectPairing/Services/Common/PairingResubscribeService.swift @@ -1,7 +1,7 @@ import Foundation import Combine -final class ResubscribeService { +final class PairingResubscribeService { private var publishers = Set() diff --git a/Sources/WalletConnectPush/Client/Common/PushDecryptionService.swift b/Sources/WalletConnectPush/Client/Common/PushDecryptionService.swift new file mode 100644 index 000000000..d77c906bb --- /dev/null +++ b/Sources/WalletConnectPush/Client/Common/PushDecryptionService.swift @@ -0,0 +1,24 @@ +import WalletConnectKMS + +public class PushDecryptionService { + enum Errors: Error { + case malformedPushMessage + } + private let serializer: Serializing + + init(serializer: Serializing) { + self.serializer = serializer + } + + public init() { + let keychainStorage = GroupKeychainStorage(serviceIdentifier: "group.com.walletconnect.sdk") + let kms = KeyManagementService(keychain: keychainStorage) + self.serializer = Serializer(kms: kms) + } + + public func decryptMessage(topic: String, ciphertext: String) throws -> PushMessage { + let rpcRequest: RPCRequest = try serializer.deserialize(topic: topic, encodedEnvelope: ciphertext) + guard let params = rpcRequest.params else { throw Errors.malformedPushMessage } + return try params.get(PushMessage.self) + } +} diff --git a/Sources/WalletConnectPush/Client/Common/PushResubscribeService.swift b/Sources/WalletConnectPush/Client/Common/PushResubscribeService.swift new file mode 100644 index 000000000..459b6057b --- /dev/null +++ b/Sources/WalletConnectPush/Client/Common/PushResubscribeService.swift @@ -0,0 +1,29 @@ +import Foundation +import WalletConnectNetworking +import Combine + +final class PushResubscribeService { + + private var publishers = Set() + + private let networkInteractor: NetworkInteracting + private let subscriptionsStorage: CodableStore + + init(networkInteractor: NetworkInteracting, subscriptionsStorage: CodableStore) { + self.networkInteractor = networkInteractor + self.subscriptionsStorage = subscriptionsStorage + setUpResubscription() + } + + func setUpResubscription() { + networkInteractor.socketConnectionStatusPublisher + .sink { [unowned self] status in + guard status == .connected else { return } + subscriptionsStorage.getAll() + .forEach { subscription in + Task(priority: .high) { try await networkInteractor.subscribe(topic: subscription.topic) } + } + } + .store(in: &publishers) + } +} diff --git a/Sources/WalletConnectPush/Client/Dapp/DappPushClient.swift b/Sources/WalletConnectPush/Client/Dapp/DappPushClient.swift index 819b27120..f95235373 100644 --- a/Sources/WalletConnectPush/Client/Dapp/DappPushClient.swift +++ b/Sources/WalletConnectPush/Client/Dapp/DappPushClient.swift @@ -24,6 +24,7 @@ public class DappPushClient { private let subscriptionsProvider: SubscriptionsProvider private let deletePushSubscriptionService: DeletePushSubscriptionService private let deletePushSubscriptionSubscriber: DeletePushSubscriptionSubscriber + private let resubscribeService: PushResubscribeService init(logger: ConsoleLogging, kms: KeyManagementServiceProtocol, @@ -32,7 +33,8 @@ public class DappPushClient { pushMessageSender: PushMessageSender, subscriptionsProvider: SubscriptionsProvider, deletePushSubscriptionService: DeletePushSubscriptionService, - deletePushSubscriptionSubscriber: DeletePushSubscriptionSubscriber) { + deletePushSubscriptionSubscriber: DeletePushSubscriptionSubscriber, + resubscribeService: PushResubscribeService) { self.logger = logger self.pushProposer = pushProposer self.proposalResponseSubscriber = proposalResponseSubscriber @@ -40,6 +42,7 @@ public class DappPushClient { self.subscriptionsProvider = subscriptionsProvider self.deletePushSubscriptionService = deletePushSubscriptionService self.deletePushSubscriptionSubscriber = deletePushSubscriptionSubscriber + self.resubscribeService = resubscribeService setupSubscriptions() } diff --git a/Sources/WalletConnectPush/Client/Dapp/DappPushClientFactory.swift b/Sources/WalletConnectPush/Client/Dapp/DappPushClientFactory.swift index 37a029646..e6f9e2c71 100644 --- a/Sources/WalletConnectPush/Client/Dapp/DappPushClientFactory.swift +++ b/Sources/WalletConnectPush/Client/Dapp/DappPushClientFactory.swift @@ -25,6 +25,7 @@ public struct DappPushClientFactory { let subscriptionProvider = SubscriptionsProvider(store: subscriptionStore) let deletePushSubscriptionService = DeletePushSubscriptionService(networkingInteractor: networkInteractor, kms: kms, logger: logger, pushSubscriptionStore: subscriptionStore) let deletePushSubscriptionSubscriber = DeletePushSubscriptionSubscriber(networkingInteractor: networkInteractor, kms: kms, logger: logger, pushSubscriptionStore: subscriptionStore) + let resubscribeService = PushResubscribeService(networkInteractor: networkInteractor, subscriptionsStorage: subscriptionStore) return DappPushClient( logger: logger, kms: kms, @@ -33,7 +34,8 @@ public struct DappPushClientFactory { pushMessageSender: pushMessageSender, subscriptionsProvider: subscriptionProvider, deletePushSubscriptionService: deletePushSubscriptionService, - deletePushSubscriptionSubscriber: deletePushSubscriptionSubscriber + deletePushSubscriptionSubscriber: deletePushSubscriptionSubscriber, + resubscribeService: resubscribeService ) } } diff --git a/Sources/WalletConnectPush/Client/Dapp/ProposalResponseSubscriber.swift b/Sources/WalletConnectPush/Client/Dapp/ProposalResponseSubscriber.swift index b1a97d158..4afa24002 100644 --- a/Sources/WalletConnectPush/Client/Dapp/ProposalResponseSubscriber.swift +++ b/Sources/WalletConnectPush/Client/Dapp/ProposalResponseSubscriber.swift @@ -48,6 +48,7 @@ class ProposalResponseSubscriber { let pushSubscription = PushSubscription(topic: topic, relay: relay, metadata: metadata) subscriptionsStore.set(pushSubscription, forKey: topic) + kms.deletePrivateKey(for: selfpublicKeyHex) try await networkingInteractor.subscribe(topic: topic) return pushSubscription } @@ -64,6 +65,7 @@ class ProposalResponseSubscriber { let protocolMethod = PushRequestProtocolMethod() networkingInteractor.responseErrorSubscription(on: protocolMethod) .sink { [unowned self] (payload: ResponseSubscriptionErrorPayload) in + kms.deletePrivateKey(for: payload.request.publicKey) guard let error = PushError(code: payload.error.code) else { return } onResponse?(payload.id, .failure(error)) }.store(in: &publishers) diff --git a/Sources/WalletConnectPush/Client/Wallet/PushMessageSubscriber.swift b/Sources/WalletConnectPush/Client/Wallet/PushMessageSubscriber.swift index 8c61a0efd..c1ea0a2b4 100644 --- a/Sources/WalletConnectPush/Client/Wallet/PushMessageSubscriber.swift +++ b/Sources/WalletConnectPush/Client/Wallet/PushMessageSubscriber.swift @@ -5,16 +5,13 @@ import WalletConnectPairing class PushMessageSubscriber { private let networkingInteractor: NetworkInteracting - private let kms: KeyManagementServiceProtocol private let logger: ConsoleLogging private var publishers = [AnyCancellable]() var onPushMessage: ((_ message: PushMessage) -> Void)? init(networkingInteractor: NetworkInteracting, - kms: KeyManagementServiceProtocol, logger: ConsoleLogging) { self.networkingInteractor = networkingInteractor - self.kms = kms self.logger = logger subscribeForPushMessages() } diff --git a/Sources/WalletConnectPush/Client/Wallet/PushRequestResponder.swift b/Sources/WalletConnectPush/Client/Wallet/PushRequestResponder.swift index 397366995..840e85cfa 100644 --- a/Sources/WalletConnectPush/Client/Wallet/PushRequestResponder.swift +++ b/Sources/WalletConnectPush/Client/Wallet/PushRequestResponder.swift @@ -11,17 +11,21 @@ class PushRequestResponder { private let rpcHistory: RPCHistory private let logger: ConsoleLogging private let subscriptionsStore: CodableStore + // Keychain shared with UNNotificationServiceExtension in order to decrypt PNs + private let groupKeychainStorage: KeychainStorageProtocol init(networkingInteractor: NetworkInteracting, logger: ConsoleLogging, kms: KeyManagementService, + groupKeychainStorage: KeychainStorageProtocol, rpcHistory: RPCHistory, subscriptionsStore: CodableStore ) { self.networkingInteractor = networkingInteractor self.logger = logger self.kms = kms + self.groupKeychainStorage = groupKeychainStorage self.rpcHistory = rpcHistory self.subscriptionsStore = subscriptionsStore } @@ -37,6 +41,9 @@ class PushRequestResponder { let pushTopic = keys.derivedTopic() try kms.setAgreementSecret(keys, topic: pushTopic) + + try groupKeychainStorage.add(keys, forKey: pushTopic) + try await networkingInteractor.subscribe(topic: pushTopic) let responseParams = PushResponseParams(publicKey: keys.publicKey.hexRepresentation) @@ -48,6 +55,8 @@ class PushRequestResponder { subscriptionsStore.set(pushSubscription, forKey: pushTopic) try await networkingInteractor.respond(topic: pairingTopic, response: response, protocolMethod: PushRequestProtocolMethod()) + + kms.deletePrivateKey(for: keys.publicKey.hexRepresentation) } func respondError(requestId: RPCID) async throws { diff --git a/Sources/WalletConnectPush/Client/Wallet/WalletPushClient.swift b/Sources/WalletConnectPush/Client/Wallet/WalletPushClient.swift index 7caa7b680..18c7c30b3 100644 --- a/Sources/WalletConnectPush/Client/Wallet/WalletPushClient.swift +++ b/Sources/WalletConnectPush/Client/Wallet/WalletPushClient.swift @@ -8,9 +8,9 @@ public class WalletPushClient { private var publishers = Set() - private let requestPublisherSubject = PassthroughSubject<(id: RPCID, metadata: AppMetadata), Never>() + private let requestPublisherSubject = PassthroughSubject<(id: RPCID, account: Account, metadata: AppMetadata), Never>() - public var requestPublisher: AnyPublisher<(id: RPCID, metadata: AppMetadata), Never> { + public var requestPublisher: AnyPublisher<(id: RPCID, account: Account, metadata: AppMetadata), Never> { requestPublisherSubject.eraseToAnyPublisher() } @@ -36,6 +36,7 @@ public class WalletPushClient { private let proposeResponder: PushRequestResponder private let pushMessageSubscriber: PushMessageSubscriber private let subscriptionsProvider: SubscriptionsProvider + private let resubscribeService: PushResubscribeService init(logger: ConsoleLogging, kms: KeyManagementServiceProtocol, @@ -45,7 +46,8 @@ public class WalletPushClient { pushMessageSubscriber: PushMessageSubscriber, subscriptionsProvider: SubscriptionsProvider, deletePushSubscriptionService: DeletePushSubscriptionService, - deletePushSubscriptionSubscriber: DeletePushSubscriptionSubscriber) { + deletePushSubscriptionSubscriber: DeletePushSubscriptionSubscriber, + resubscribeService: PushResubscribeService) { self.logger = logger self.pairingRegisterer = pairingRegisterer self.proposeResponder = proposeResponder @@ -54,6 +56,7 @@ public class WalletPushClient { self.subscriptionsProvider = subscriptionsProvider self.deletePushSubscriptionService = deletePushSubscriptionService self.deletePushSubscriptionSubscriber = deletePushSubscriptionSubscriber + self.resubscribeService = resubscribeService setupSubscriptions() } @@ -73,10 +76,6 @@ public class WalletPushClient { try await deletePushSubscriptionService.delete(topic: topic) } - public func decryptMessage(topic: String, ciphertext: String) throws -> String { - try echoClient.decryptMessage(topic: topic, ciphertext: ciphertext) - } - public func register(deviceToken: Data) async throws { try await echoClient.register(deviceToken: deviceToken) } @@ -89,7 +88,7 @@ private extension WalletPushClient { pairingRegisterer.register(method: protocolMethod) .sink { [unowned self] (payload: RequestSubscriptionPayload) in - requestPublisherSubject.send((id: payload.id, metadata: payload.request.metadata)) + requestPublisherSubject.send((id: payload.id, account: payload.request.account, metadata: payload.request.metadata)) }.store(in: &publishers) pushMessageSubscriber.onPushMessage = { [unowned self] pushMessage in @@ -100,3 +99,11 @@ private extension WalletPushClient { } } } + +#if targetEnvironment(simulator) +extension WalletPushClient { + public func register(deviceToken: String) async throws { + try await echoClient.register(deviceToken: deviceToken) + } +} +#endif diff --git a/Sources/WalletConnectPush/Client/Wallet/WalletPushClientFactory.swift b/Sources/WalletConnectPush/Client/Wallet/WalletPushClientFactory.swift index 06bea0555..7d11f4ade 100644 --- a/Sources/WalletConnectPush/Client/Wallet/WalletPushClientFactory.swift +++ b/Sources/WalletConnectPush/Client/Wallet/WalletPushClientFactory.swift @@ -7,31 +7,35 @@ public struct WalletPushClientFactory { public static func create(networkInteractor: NetworkInteracting, pairingRegisterer: PairingRegisterer, echoClient: EchoClient) -> WalletPushClient { let logger = ConsoleLogger(loggingLevel: .off) let keyValueStorage = UserDefaults.standard + let keychainStorage = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk") + let groupKeychainService = GroupKeychainStorage(serviceIdentifier: "group.com.walletconnect.sdk") + return WalletPushClientFactory.create( logger: logger, keyValueStorage: keyValueStorage, keychainStorage: keychainStorage, + groupKeychainStorage: groupKeychainService, networkInteractor: networkInteractor, pairingRegisterer: pairingRegisterer, echoClient: echoClient ) } - static func create(logger: ConsoleLogging, keyValueStorage: KeyValueStorage, keychainStorage: KeychainStorageProtocol, networkInteractor: NetworkInteracting, pairingRegisterer: PairingRegisterer, echoClient: EchoClient) -> WalletPushClient { + static func create(logger: ConsoleLogging, keyValueStorage: KeyValueStorage, keychainStorage: KeychainStorageProtocol, groupKeychainStorage: KeychainStorageProtocol, networkInteractor: NetworkInteracting, pairingRegisterer: PairingRegisterer, echoClient: EchoClient) -> WalletPushClient { let kms = KeyManagementService(keychain: keychainStorage) let history = RPCHistoryFactory.createForNetwork(keyValueStorage: keyValueStorage) let subscriptionStore = CodableStore(defaults: keyValueStorage, identifier: PushStorageIdntifiers.pushSubscription) - let proposeResponder = PushRequestResponder(networkingInteractor: networkInteractor, logger: logger, kms: kms, rpcHistory: history, subscriptionsStore: subscriptionStore) + let proposeResponder = PushRequestResponder(networkingInteractor: networkInteractor, logger: logger, kms: kms, groupKeychainStorage: groupKeychainStorage, rpcHistory: history, subscriptionsStore: subscriptionStore) - let pushMessageSubscriber = PushMessageSubscriber(networkingInteractor: networkInteractor, kms: kms, logger: logger) + let pushMessageSubscriber = PushMessageSubscriber(networkingInteractor: networkInteractor, logger: logger) let subscriptionProvider = SubscriptionsProvider(store: subscriptionStore) let deletePushSubscriptionService = DeletePushSubscriptionService(networkingInteractor: networkInteractor, kms: kms, logger: logger, pushSubscriptionStore: subscriptionStore) let deletePushSubscriptionSubscriber = DeletePushSubscriptionSubscriber(networkingInteractor: networkInteractor, kms: kms, logger: logger, pushSubscriptionStore: subscriptionStore) - + let resubscribeService = PushResubscribeService(networkInteractor: networkInteractor, subscriptionsStorage: subscriptionStore) return WalletPushClient( logger: logger, kms: kms, @@ -41,7 +45,8 @@ public struct WalletPushClientFactory { pushMessageSubscriber: pushMessageSubscriber, subscriptionsProvider: subscriptionProvider, deletePushSubscriptionService: deletePushSubscriptionService, - deletePushSubscriptionSubscriber: deletePushSubscriptionSubscriber + deletePushSubscriptionSubscriber: deletePushSubscriptionSubscriber, + resubscribeService: resubscribeService ) } } diff --git a/Sources/WalletConnectPush/Push.swift b/Sources/WalletConnectPush/Push.swift index 4d2b4fcf7..eea9a582c 100644 --- a/Sources/WalletConnectPush/Push.swift +++ b/Sources/WalletConnectPush/Push.swift @@ -13,6 +13,10 @@ public class Push { }() public static var wallet: WalletPushClient = { + guard let config = Push.config else { + fatalError("Error - you must call Push.configure(_:) before accessing the shared wallet instance.") + } + Echo.configure(clientId: config.clientId) return WalletPushClientFactory.create( networkInteractor: Networking.interactor, pairingRegisterer: Pair.registerer, @@ -20,5 +24,14 @@ public class Push { ) }() + private static var config: Config? + private init() { } + + /// Wallet's configuration method + static public func configure() { + let clientId = try! Networking.interactor.getClientId() + Push.config = Push.Config(clientId: clientId) + } + } diff --git a/Sources/WalletConnectPush/PushConfig.swift b/Sources/WalletConnectPush/PushConfig.swift new file mode 100644 index 000000000..bf0f083d1 --- /dev/null +++ b/Sources/WalletConnectPush/PushConfig.swift @@ -0,0 +1,7 @@ +import Foundation + +extension Push { + struct Config { + let clientId: String + } +} diff --git a/Sources/WalletConnectPush/Types/PushMessage.swift b/Sources/WalletConnectPush/Types/PushMessage.swift index a5823401b..eb32df560 100644 --- a/Sources/WalletConnectPush/Types/PushMessage.swift +++ b/Sources/WalletConnectPush/Types/PushMessage.swift @@ -1,10 +1,10 @@ import Foundation public struct PushMessage: Codable, Equatable { - let title: String - let body: String - let icon: String - let url: String + public let title: String + public let body: String + public let icon: String + public let url: String public init(title: String, body: String, icon: String, url: String) { self.title = title diff --git a/Sources/WalletConnectRelay/PackageConfig.json b/Sources/WalletConnectRelay/PackageConfig.json index 5d6fcfcfb..c712e32f1 100644 --- a/Sources/WalletConnectRelay/PackageConfig.json +++ b/Sources/WalletConnectRelay/PackageConfig.json @@ -1 +1 @@ -{"version": "1.2.1"} +{"version": "1.3.0"} diff --git a/Sources/WalletConnectRelay/RelayClient.swift b/Sources/WalletConnectRelay/RelayClient.swift index 1a618bda3..ca9f9b649 100644 --- a/Sources/WalletConnectRelay/RelayClient.swift +++ b/Sources/WalletConnectRelay/RelayClient.swift @@ -267,6 +267,8 @@ public final class RelayClient { do { try acknowledgeRequest(request) try rpcHistory.set(request, forTopic: params.data.topic, emmitedBy: .remote) + logger.debug("topic \(params.data.topic)") + logger.debug("message: \(params.data.message)") messagePublisherSubject.send((params.data.topic, params.data.message)) } catch { logger.error("[RelayClient] RPC History 'set()' error: \(error)") diff --git a/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift b/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift index bab3b0f4b..a3624466a 100644 --- a/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift +++ b/Sources/WalletConnectSign/Engine/Common/ApproveEngine.swift @@ -242,7 +242,7 @@ private extension ApproveEngine { kms.deletePrivateKey(for: payload.request.proposer.publicKey) onSessionRejected?( - payload.request.publicRepresentation(), + payload.request.publicRepresentation(pairingTopic: payload.topic), SessionType.Reason(code: payload.error.code, message: payload.error.message) ) } @@ -280,7 +280,7 @@ private extension ApproveEngine { return respondError(payload: payload, reason: .invalidUpdateRequest, protocolMethod: SessionProposeProtocolMethod()) } proposalPayloadsStore.set(payload, forKey: proposal.proposer.publicKey) - onSessionProposal?(proposal.publicRepresentation()) + onSessionProposal?(proposal.publicRepresentation(pairingTopic: payload.topic)) } // MARK: SessionSettleRequest diff --git a/Sources/WalletConnectSign/Services/App/AppProposeService.swift b/Sources/WalletConnectSign/Services/App/AppProposeService.swift index 5c59d8369..ce9a8da82 100644 --- a/Sources/WalletConnectSign/Services/App/AppProposeService.swift +++ b/Sources/WalletConnectSign/Services/App/AppProposeService.swift @@ -26,11 +26,12 @@ final class AppProposeService { let proposer = Participant( publicKey: publicKey.hexRepresentation, metadata: metadata) + let proposal = SessionProposal( relays: [relay], proposer: proposer, requiredNamespaces: namespaces) - + let request = RPCRequest(method: protocolMethod.method, params: proposal) try await networkingInteractor.requestNetworkAck(request, topic: pairingTopic, protocolMethod: protocolMethod) } diff --git a/Sources/WalletConnectSign/Session.swift b/Sources/WalletConnectSign/Session.swift index 5884e65d2..99e981591 100644 --- a/Sources/WalletConnectSign/Session.swift +++ b/Sources/WalletConnectSign/Session.swift @@ -17,6 +17,7 @@ extension Session { public struct Proposal: Equatable { public var id: String + public let pairingTopic: String public let proposer: AppMetadata public let requiredNamespaces: [String: ProposalNamespace] diff --git a/Sources/WalletConnectSign/Types/Session/SessionProposal.swift b/Sources/WalletConnectSign/Types/Session/SessionProposal.swift index ae26cc810..d185b20dd 100644 --- a/Sources/WalletConnectSign/Types/Session/SessionProposal.swift +++ b/Sources/WalletConnectSign/Types/Session/SessionProposal.swift @@ -5,7 +5,13 @@ struct SessionProposal: Codable, Equatable { let proposer: Participant let requiredNamespaces: [String: ProposalNamespace] - func publicRepresentation() -> Session.Proposal { - return Session.Proposal(id: proposer.publicKey, proposer: proposer.metadata, requiredNamespaces: requiredNamespaces, proposal: self) + func publicRepresentation(pairingTopic: String) -> Session.Proposal { + return Session.Proposal( + id: proposer.publicKey, + pairingTopic: pairingTopic, + proposer: proposer.metadata, + requiredNamespaces: requiredNamespaces, + proposal: self + ) } } diff --git a/Tests/WalletConnectSignTests/Stub/Stubs.swift b/Tests/WalletConnectSignTests/Stub/Stubs.swift index 3789cdb3e..c83298a20 100644 --- a/Tests/WalletConnectSignTests/Stub/Stubs.swift +++ b/Tests/WalletConnectSignTests/Stub/Stubs.swift @@ -81,8 +81,7 @@ extension SessionProposal { let relayOptions = RelayProtocolOptions(protocol: "irn", data: nil) return SessionType.ProposeParams( relays: [relayOptions], - proposer: Participant(publicKey: proposerPubKey, metadata: AppMetadata.stub()), - requiredNamespaces: ProposalNamespace.stubDictionary()) + proposer: Participant(publicKey: proposerPubKey, metadata: AppMetadata.stub()), requiredNamespaces: ProposalNamespace.stubDictionary()) } } diff --git a/WalletConnectSwiftV2.podspec b/WalletConnectSwiftV2.podspec index 881bfe09c..51446a7c5 100644 --- a/WalletConnectSwiftV2.podspec +++ b/WalletConnectSwiftV2.podspec @@ -75,47 +75,48 @@ Pod::Spec.new do |spec| spec.default_subspecs = 'WalletConnect' spec.subspec 'WalletConnect' do |ss| - ss.source_files = 'Sources/WalletConnectSign/**/*' + ss.source_files = 'Sources/WalletConnectSign/**/*.{h,m,swift}' ss.dependency 'WalletConnectSwiftV2/WalletConnectPairing' end spec.subspec 'WalletConnectAuth' do |ss| - ss.source_files = 'Sources/Auth/**/*' + ss.source_files = 'Sources/Auth/**/*.{h,m,swift}' ss.dependency 'WalletConnectSwiftV2/WalletConnectPairing' end + spec.subspec 'Web3Wallet' do |ss| + ss.source_files = 'Sources/Web3Wallet/**/*.{h,m,swift}' + ss.dependency 'WalletConnectSwiftV2/WalletConnect' + ss.dependency 'WalletConnectSwiftV2/WalletConnectAuth' + end + spec.subspec 'WalletConnectChat' do |ss| - ss.source_files = 'Sources/Chat/**/*' + ss.source_files = 'Sources/Chat/**/*.{h,m,swift}' ss.dependency 'WalletConnectSwiftV2/WalletConnectNetworking' end spec.subspec 'WalletConnectNetworking' do |ss| - ss.source_files = 'Sources/WalletConnectNetworking/**/*' + ss.source_files = 'Sources/WalletConnectNetworking/**/*.{h,m,swift}' ss.dependency 'WalletConnectSwiftV2/WalletConnectRelay' end spec.subspec 'WalletConnectPairing' do |ss| - ss.source_files = 'Sources/WalletConnectPairing/**/*' + ss.source_files = 'Sources/WalletConnectPairing/**/*.{h,m,swift}' ss.dependency 'WalletConnectSwiftV2/WalletConnectNetworking' end - spec.subspec 'WalletConnectPush' do |ss| - ss.source_files = 'Sources/WalletConnectPush/**/*' - ss.dependency 'WalletConnectSwiftV2/WalletConnectPairing' - end - spec.subspec 'WalletConnectRouter' do |ss| - ss.source_files = 'Sources/WalletConnectRouter/**/*' + ss.source_files = 'Sources/WalletConnectRouter/**/*.{h,m,swift}' ss.platform = :ios end spec.subspec 'WalletConnectNetworking' do |ss| - ss.source_files = 'Sources/WalletConnectNetworking/**/*' + ss.source_files = 'Sources/WalletConnectNetworking/**/*.{h,m,swift}' ss.dependency 'WalletConnectSwiftV2/WalletConnectRelay' end spec.subspec 'WalletConnectRelay' do |ss| - ss.source_files = 'Sources/WalletConnectRelay/**/*' + ss.source_files = 'Sources/WalletConnectRelay/**/*.{h,m,swift}' ss.dependency 'WalletConnectSwiftV2/WalletConnectKMS' ss.resource_bundles = { 'WalletConnect_WalletConnectRelay' => [