diff --git a/.github/actions/ci/action.yml b/.github/actions/ci/action.yml index 1c105f783..cf03c7a7d 100644 --- a/.github/actions/ci/action.yml +++ b/.github/actions/ci/action.yml @@ -30,6 +30,25 @@ runs: PROJECT_ID: ${{ inputs.project-id }} run: make integration_tests RELAY_HOST=$RELAY_ENDPOINT PROJECT_ID=$PROJECT_ID + # Relay Integration tests + - name: Run integration tests + if: inputs.type == 'relay-tests' + shell: bash + env: + RELAY_ENDPOINT: ${{ inputs.relay-endpoint }} + PROJECT_ID: ${{ inputs.project-id }} + run: make relay_tests RELAY_HOST=$RELAY_ENDPOINT PROJECT_ID=$PROJECT_ID + + # Smoke tests + - name: Run smoke tests + if: inputs.type == 'smoke-tests' + shell: bash + env: + RELAY_ENDPOINT: ${{ inputs.relay-endpoint }} + PROJECT_ID: ${{ inputs.project-id }} + run: make smoke_tests RELAY_HOST=$RELAY_ENDPOINT PROJECT_ID=$PROJECT_ID + + # Wallet build - name: Build Example Wallet if: inputs.type == 'build-example-wallet' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e1846f591..2be3cc7c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,7 +20,7 @@ jobs: runs-on: macos-12 strategy: matrix: - test-type: [unit-tests, integration-tests, build-example-wallet, build-example-dapp] + test-type: [unit-tests, integration-tests, build-example-wallet, build-example-dapp, relay-tests] steps: - uses: actions/checkout@v2 diff --git a/Example/ExampleApp.xcodeproj/IntegrationTests.xctestplan b/Example/ExampleApp.xcodeproj/IntegrationTests.xctestplan new file mode 100644 index 000000000..5b274df17 --- /dev/null +++ b/Example/ExampleApp.xcodeproj/IntegrationTests.xctestplan @@ -0,0 +1,39 @@ +{ + "configurations" : [ + { + "id" : "BAABD63B-F7E2-4928-AD6F-325C999C17BB", + "name" : "Configuration 1", + "options" : { + + } + } + ], + "defaultOptions" : { + "codeCoverage" : false, + "environmentVariableEntries" : [ + { + "key" : "RELAY_HOST", + "value" : "$(RELAY_HOST)" + }, + { + "key" : "PROJECT_ID", + "value" : "$(PROJECT_ID)" + } + ], + "targetForVariableExpansion" : { + "containerPath" : "container:ExampleApp.xcodeproj", + "identifier" : "A5E03DEC286464DB00888481", + "name" : "IntegrationTests" + } + }, + "testTargets" : [ + { + "target" : { + "containerPath" : "container:ExampleApp.xcodeproj", + "identifier" : "A5E03DEC286464DB00888481", + "name" : "IntegrationTests" + } + } + ], + "version" : 1 +} diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 4348df5e6..8cccc1637 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -30,6 +30,12 @@ 840BCF142949B9F900CB0655 /* WalletConnectPush in Frameworks */ = {isa = PBXBuildFile; productRef = 840BCF132949B9F900CB0655 /* WalletConnectPush */; }; 84310D05298BC980000C15B6 /* MainInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84310D04298BC980000C15B6 /* MainInteractor.swift */; }; 8439CB89293F658E00F2F2E2 /* PushMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8439CB88293F658E00F2F2E2 /* PushMessage.swift */; }; + 844749F629B9E5B9005F520B /* RelayClientEndToEndTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844749F529B9E5B9005F520B /* RelayClientEndToEndTests.swift */; }; + 844749FD29B9E6B2005F520B /* WalletConnectNetworking in Frameworks */ = {isa = PBXBuildFile; productRef = 844749FC29B9E6B2005F520B /* WalletConnectNetworking */; }; + 844749FE29B9EB1B005F520B /* InputConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = A518B31328E33A6500A2CE93 /* InputConfig.swift */; }; + 844749FF29B9EB3B005F520B /* KeychainStorageMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E03E1028646F8000888481 /* KeychainStorageMock.swift */; }; + 84474A0129B9EB74005F520B /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = 84474A0029B9EB74005F520B /* Starscream */; }; + 84474A0229B9ECA2005F520B /* DefaultSocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */; }; 8448F1D427E4726F0000B866 /* WalletConnect in Frameworks */ = {isa = PBXBuildFile; productRef = 8448F1D327E4726F0000B866 /* WalletConnect */; }; 84494388278D9C1B00CC26BB /* UIAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84494387278D9C1B00CC26BB /* UIAlertController.swift */; }; 845B8D8C2934B36C0084A966 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845B8D8B2934B36C0084A966 /* Account.swift */; }; @@ -208,7 +214,6 @@ A5E03DFF2864662500888481 /* WalletConnect in Frameworks */ = {isa = PBXBuildFile; productRef = A5E03DFE2864662500888481 /* WalletConnect */; }; A5E03E01286466EA00888481 /* WalletConnectChat in Frameworks */ = {isa = PBXBuildFile; productRef = A5E03E00286466EA00888481 /* WalletConnectChat */; }; A5E03E03286466F400888481 /* ChatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E03E02286466F400888481 /* ChatTests.swift */; }; - A5E03E0D28646AD200888481 /* RelayClientEndToEndTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E03E0C28646AD200888481 /* RelayClientEndToEndTests.swift */; }; A5E03E1128646F8000888481 /* KeychainStorageMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E03E1028646F8000888481 /* KeychainStorageMock.swift */; }; A5E22D1A2840C62A00E36487 /* Engine.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D192840C62A00E36487 /* Engine.swift */; }; A5E22D1C2840C85D00E36487 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5E22D1B2840C85D00E36487 /* App.swift */; }; @@ -236,7 +241,6 @@ C55D3497295DFA750004314A /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D3492295DFA750004314A /* WelcomeView.swift */; }; C55D349929630D440004314A /* Web3Wallet in Frameworks */ = {isa = PBXBuildFile; productRef = C55D349829630D440004314A /* Web3Wallet */; }; C55D349B2965BC2F0004314A /* TagsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D349A2965BC2F0004314A /* TagsView.swift */; }; - C55D349D2965F8D40004314A /* Proposal.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D349C2965F8D30004314A /* Proposal.swift */; }; C55D34AE2965FB750004314A /* 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 */; }; @@ -382,7 +386,11 @@ 8414FC832962F3D9007E20C9 /* PushDecryptionService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PushDecryptionService.entitlements; sourceTree = ""; }; 84310D04298BC980000C15B6 /* MainInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainInteractor.swift; sourceTree = ""; }; 8439CB88293F658E00F2F2E2 /* PushMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushMessage.swift; sourceTree = ""; }; + 844749F329B9E5B9005F520B /* RelayIntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RelayIntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 844749F529B9E5B9005F520B /* RelayClientEndToEndTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayClientEndToEndTests.swift; sourceTree = ""; }; 84494387278D9C1B00CC26BB /* UIAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAlertController.swift; sourceTree = ""; }; + 845AA7D929BA1EBA00F33739 /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = IntegrationTests.xctestplan; path = ExampleApp.xcodeproj/IntegrationTests.xctestplan; sourceTree = ""; }; + 845AA7DC29BB424800F33739 /* SmokeTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = SmokeTests.xctestplan; 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 = ""; }; 847BD1D12989492500076C90 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; @@ -540,7 +548,6 @@ A5E03DF9286465C700888481 /* SignClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignClientTests.swift; sourceTree = ""; }; A5E03DFC286465D100888481 /* Stubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stubs.swift; sourceTree = ""; }; A5E03E02286466F400888481 /* ChatTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTests.swift; sourceTree = ""; }; - A5E03E0C28646AD200888481 /* RelayClientEndToEndTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RelayClientEndToEndTests.swift; sourceTree = ""; }; A5E03E1028646F8000888481 /* KeychainStorageMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainStorageMock.swift; sourceTree = ""; }; A5E22D192840C62A00E36487 /* Engine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Engine.swift; sourceTree = ""; }; A5E22D1B2840C85D00E36487 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; }; @@ -566,7 +573,6 @@ C55D3491295DFA750004314A /* WelcomeInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeInteractor.swift; sourceTree = ""; }; C55D3492295DFA750004314A /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = ""; }; C55D349A2965BC2F0004314A /* TagsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsView.swift; sourceTree = ""; }; - C55D349C2965F8D30004314A /* Proposal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Proposal.swift; sourceTree = ""; }; C55D34A92965FB750004314A /* 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 = ""; }; @@ -633,6 +639,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 844749F029B9E5B9005F520B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 844749FD29B9E6B2005F520B /* WalletConnectNetworking in Frameworks */, + 84474A0129B9EB74005F520B /* Starscream in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 84B767732954554A00E92316 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -752,6 +767,8 @@ 764E1D3326F8D3FC00A1FB15 = { isa = PBXGroup; children = ( + 845AA7D929BA1EBA00F33739 /* IntegrationTests.xctestplan */, + 845AA7DC29BB424800F33739 /* SmokeTests.xctestplan */, A5A8E479293A1C4400FEB97D /* Shared */, A5F48A0528E43D3F0034CBFB /* Configuration.xcconfig */, 84CE6453279FFE1100142511 /* Wallet.entitlements */, @@ -763,6 +780,7 @@ 84B767772954554A00E92316 /* PushDecryptionService */, C56EE21C293F55ED004840D1 /* WalletApp */, 84E6B84829787A8000428BAF /* PNDecryptionService */, + 844749F429B9E5B9005F520B /* RelayIntegrationTests */, 764E1D3D26F8D3FC00A1FB15 /* Products */, 764E1D5326F8DAC800A1FB15 /* Frameworks */, 764E1D5626F8DB6000A1FB15 /* WalletConnectSwiftV2 */, @@ -780,6 +798,7 @@ 84B767762954554A00E92316 /* PushDecryptionService.appex */, C56EE21B293F55ED004840D1 /* WalletApp.app */, 84E6B84729787A8000428BAF /* PNDecryptionService.appex */, + 844749F329B9E5B9005F520B /* RelayIntegrationTests.xctest */, ); name = Products; sourceTree = ""; @@ -821,6 +840,14 @@ path = Helpers; sourceTree = ""; }; + 844749F429B9E5B9005F520B /* RelayIntegrationTests */ = { + isa = PBXGroup; + children = ( + 844749F529B9E5B9005F520B /* RelayClientEndToEndTests.swift */, + ); + path = RelayIntegrationTests; + sourceTree = ""; + }; 8460DCFD274F98A90081F94C /* Request */ = { isa = PBXGroup; children = ( @@ -922,6 +949,15 @@ path = Models; sourceTree = ""; }; + 84CB43D429B9FC88004DDA31 /* Tests */ = { + isa = PBXGroup; + children = ( + A5E03E1028646F8000888481 /* KeychainStorageMock.swift */, + A518B31328E33A6500A2CE93 /* InputConfig.swift */, + ); + path = Tests; + sourceTree = ""; + }; 84CE641D27981DED00142511 /* DApp */ = { isa = PBXGroup; children = ( @@ -1342,6 +1378,7 @@ A5A8E479293A1C4400FEB97D /* Shared */ = { isa = PBXGroup; children = ( + 84CB43D429B9FC88004DDA31 /* Tests */, A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */, A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */, ); @@ -1428,7 +1465,6 @@ children = ( 849D7A91292E2115006A2BD4 /* Push */, 84CEC64728D8A98900D081A8 /* Pairing */, - A5E03E0B28646AA500888481 /* Relay */, A5E03E0A28646A8A00888481 /* Stubs */, A5E03E0928646A8100888481 /* Sign */, A5E03E0828646A7B00888481 /* Chat */, @@ -1458,8 +1494,6 @@ A5E03E0A28646A8A00888481 /* Stubs */ = { isa = PBXGroup; children = ( - A518B31328E33A6500A2CE93 /* InputConfig.swift */, - A5E03E1028646F8000888481 /* KeychainStorageMock.swift */, A5E03DFC286465D100888481 /* Stubs.swift */, 84FE684528ACDB4700C893FF /* RequestParams.swift */, 845B8D8B2934B36C0084A966 /* Account.swift */, @@ -1468,14 +1502,6 @@ path = Stubs; sourceTree = ""; }; - A5E03E0B28646AA500888481 /* Relay */ = { - isa = PBXGroup; - children = ( - A5E03E0C28646AD200888481 /* RelayClientEndToEndTests.swift */, - ); - path = Relay; - sourceTree = ""; - }; A5E22D252840D08B00E36487 /* Regression */ = { isa = PBXGroup; children = ( @@ -1532,7 +1558,6 @@ C55D349E2965FAC30004314A /* SessionProposal */ = { isa = PBXGroup; children = ( - C55D34B32965FF750004314A /* Models */, C55D34A92965FB750004314A /* SessionProposalModule.swift */, C55D34AA2965FB750004314A /* SessionProposalPresenter.swift */, C55D34AB2965FB750004314A /* SessionProposalRouter.swift */, @@ -1542,14 +1567,6 @@ path = SessionProposal; sourceTree = ""; }; - C55D34B32965FF750004314A /* Models */ = { - isa = PBXGroup; - children = ( - C55D349C2965F8D30004314A /* Proposal.swift */, - ); - path = Models; - sourceTree = ""; - }; C56EE21C293F55ED004840D1 /* WalletApp */ = { isa = PBXGroup; children = ( @@ -1780,6 +1797,27 @@ productReference = 764E1D3C26F8D3FC00A1FB15 /* WalletConnect Wallet.app */; productType = "com.apple.product-type.application"; }; + 844749F229B9E5B9005F520B /* RelayIntegrationTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 844749FB29B9E5B9005F520B /* Build configuration list for PBXNativeTarget "RelayIntegrationTests" */; + buildPhases = ( + 844749EF29B9E5B9005F520B /* Sources */, + 844749F029B9E5B9005F520B /* Frameworks */, + 844749F129B9E5B9005F520B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RelayIntegrationTests; + packageProductDependencies = ( + 844749FC29B9E6B2005F520B /* WalletConnectNetworking */, + 84474A0029B9EB74005F520B /* Starscream */, + ); + productName = RelayIntegrationTests; + productReference = 844749F329B9E5B9005F520B /* RelayIntegrationTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 84B767752954554A00E92316 /* PushDecryptionService */ = { isa = PBXNativeTarget; buildConfigurationList = 84B767812954554A00E92316 /* Build configuration list for PBXNativeTarget "PushDecryptionService" */; @@ -1954,6 +1992,9 @@ 764E1D3B26F8D3FC00A1FB15 = { CreatedOnToolsVersion = 12.5.1; }; + 844749F229B9E5B9005F520B = { + CreatedOnToolsVersion = 14.2; + }; 84B767752954554A00E92316 = { CreatedOnToolsVersion = 14.2; }; @@ -2004,6 +2045,7 @@ 84B767752954554A00E92316 /* PushDecryptionService */, C56EE21A293F55ED004840D1 /* WalletApp */, 84E6B84629787A8000428BAF /* PNDecryptionService */, + 844749F229B9E5B9005F520B /* RelayIntegrationTests */, ); }; /* End PBXProject section */ @@ -2018,6 +2060,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 844749F129B9E5B9005F520B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 84B767742954554A00E92316 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -2111,6 +2160,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 844749EF29B9E5B9005F520B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 84474A0229B9ECA2005F520B /* DefaultSocketFactory.swift in Sources */, + 844749FF29B9EB3B005F520B /* KeychainStorageMock.swift in Sources */, + 844749FE29B9EB1B005F520B /* InputConfig.swift in Sources */, + 844749F629B9E5B9005F520B /* RelayClientEndToEndTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 84B767722954554A00E92316 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2263,7 +2323,6 @@ 7694A5262874296A0001257E /* RegistryTests.swift in Sources */, A541959F2934BFEF0035AD19 /* SignerTests.swift in Sources */, A50C036528AAD32200FE72D3 /* ClientDelegate.swift in Sources */, - A5E03E0D28646AD200888481 /* RelayClientEndToEndTests.swift in Sources */, A5E03DFA286465C700888481 /* SignClientTests.swift in Sources */, A54195A02934BFEF0035AD19 /* EIP1271VerifierTests.swift in Sources */, A54195A12934BFEF0035AD19 /* EIP191VerifierTests.swift in Sources */, @@ -2347,7 +2406,6 @@ C5F32A322954816C00A6476E /* ConnectionDetailsPresenter.swift in Sources */, 84B815562991217900FAD54E /* PushMessagesRouter.swift in Sources */, 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 */, @@ -2602,6 +2660,42 @@ }; name = Release; }; + 844749F929B9E5B9005F520B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W5R8AG9K22; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.RelayIntegrationTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 844749FA29B9E5B9005F520B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W5R8AG9K22; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.RelayIntegrationTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 84B7677F2954554A00E92316 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3037,6 +3131,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 844749FB29B9E5B9005F520B /* Build configuration list for PBXNativeTarget "RelayIntegrationTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 844749F929B9E5B9005F520B /* Debug */, + 844749FA29B9E5B9005F520B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 84B767812954554A00E92316 /* Build configuration list for PBXNativeTarget "PushDecryptionService" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -3146,6 +3249,15 @@ isa = XCSwiftPackageProductDependency; productName = WalletConnectPush; }; + 844749FC29B9E6B2005F520B /* WalletConnectNetworking */ = { + isa = XCSwiftPackageProductDependency; + productName = WalletConnectNetworking; + }; + 84474A0029B9EB74005F520B /* Starscream */ = { + isa = XCSwiftPackageProductDependency; + package = A5D85224286333D500DAF5C3 /* XCRemoteSwiftPackageReference "Starscream" */; + productName = Starscream; + }; 8448F1D327E4726F0000B866 /* WalletConnect */ = { isa = XCSwiftPackageProductDependency; productName = WalletConnect; diff --git a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/IntegrationTests.xcscheme b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/IntegrationTests.xcscheme index 177cd0cec..ddd361a6d 100644 --- a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/IntegrationTests.xcscheme +++ b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/IntegrationTests.xcscheme @@ -1,7 +1,7 @@ + version = "1.7"> @@ -48,6 +48,15 @@ isEnabled = "YES"> + + + + + + diff --git a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/PushDecryptionService.xcscheme b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/PushDecryptionService.xcscheme index 59e2134d6..66122a584 100644 --- a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/PushDecryptionService.xcscheme +++ b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/PushDecryptionService.xcscheme @@ -43,6 +43,17 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/Wallet.xcscheme b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/Wallet.xcscheme index 5c9f393ee..d786c3306 100644 --- a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/Wallet.xcscheme +++ b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/Wallet.xcscheme @@ -48,6 +48,17 @@ ReferencedContainer = "container:ExampleApp.xcodeproj"> + + + + private func showSessionRequest(_ request: Request) { let viewController = RequestViewController(request) viewController.onSign = { [unowned self] in - let result = Signer.sign(request: request) - respondOnSign(request: request, response: result) - reload() + do { + let result = try Signer.sign(request: request) + respondOnSign(request: request, response: result) + reload() + } catch { + fatalError(error.localizedDescription) + } } viewController.onReject = { [unowned self] in respondOnReject(request: request) diff --git a/Example/ExampleApp/Shared/Signer/Signer.swift b/Example/ExampleApp/Shared/Signer/Signer.swift index d22d863da..f7fa459c5 100644 --- a/Example/ExampleApp/Shared/Signer/Signer.swift +++ b/Example/ExampleApp/Shared/Signer/Signer.swift @@ -2,11 +2,14 @@ import Foundation import Commons import WalletConnectSign -class Signer { - +final class Signer { + enum Errors: Error { + case notImplemented + } + private init() {} - static func sign(request: Request) -> AnyCodable { + static func sign(request: Request) throws -> AnyCodable { switch request.method { case "personal_sign": return ETHSigner.personalSign(request.params) @@ -19,8 +22,17 @@ class Signer { case "solana_signTransaction": return SOLSigner.signTransaction(request.params) + default: - fatalError("not implemented") + throw Signer.Errors.notImplemented + } + } +} + +extension Signer.Errors: LocalizedError { + var errorDescription: String? { + switch self { + case .notImplemented: return "Requested method is not implemented" } } } diff --git a/Example/ExampleApp/Wallet/WalletViewController.swift b/Example/ExampleApp/Wallet/WalletViewController.swift index 349ba325e..5879a771a 100644 --- a/Example/ExampleApp/Wallet/WalletViewController.swift +++ b/Example/ExampleApp/Wallet/WalletViewController.swift @@ -82,9 +82,13 @@ final class WalletViewController: UIViewController { private func showSessionRequest(_ request: Request) { let requestVC = RequestViewController(request) requestVC.onSign = { [unowned self] in - let result = Signer.sign(request: request) - respondOnSign(request: request, response: result) - reloadSessionDetailsIfNeeded() + do { + let result = try Signer.sign(request: request) + respondOnSign(request: request, response: result) + reloadSessionDetailsIfNeeded() + } catch { + fatalError(error.localizedDescription) + } } requestVC.onReject = { [unowned self] in respondOnReject(request: request) diff --git a/Example/IntegrationTests/Relay/RelayClientEndToEndTests.swift b/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift similarity index 100% rename from Example/IntegrationTests/Relay/RelayClientEndToEndTests.swift rename to Example/RelayIntegrationTests/RelayClientEndToEndTests.swift diff --git a/Example/IntegrationTests/Stubs/InputConfig.swift b/Example/Shared/Tests/InputConfig.swift similarity index 100% rename from Example/IntegrationTests/Stubs/InputConfig.swift rename to Example/Shared/Tests/InputConfig.swift diff --git a/Example/IntegrationTests/Stubs/KeychainStorageMock.swift b/Example/Shared/Tests/KeychainStorageMock.swift similarity index 100% rename from Example/IntegrationTests/Stubs/KeychainStorageMock.swift rename to Example/Shared/Tests/KeychainStorageMock.swift diff --git a/Example/SmokeTests.xctestplan b/Example/SmokeTests.xctestplan new file mode 100644 index 000000000..d6346a7ba --- /dev/null +++ b/Example/SmokeTests.xctestplan @@ -0,0 +1,74 @@ +{ + "configurations" : [ + { + "id" : "EB662E8C-8DC0-4689-A2FF-B41B80A99F85", + "name" : "Configuration 1", + "options" : { + "targetForVariableExpansion" : { + "containerPath" : "container:ExampleApp.xcodeproj", + "identifier" : "A5E03DEC286464DB00888481", + "name" : "IntegrationTests" + } + } + } + ], + "defaultOptions" : { + "environmentVariableEntries" : [ + { + "key" : "RELAY_HOST", + "value" : "$(RELAY_HOST)" + }, + { + "key" : "PROJECT_ID", + "value" : "$(PROJECT_ID)" + } + ], + "testTimeoutsEnabled" : true + }, + "testTargets" : [ + { + "skippedTests" : [ + "AuthTests\/testEIP1271RespondSuccess()", + "AuthTests\/testEIP191RespondError()", + "AuthTests\/testRequest()", + "AuthTests\/testRespondSignatureVerificationFailed()", + "AuthTests\/testUserRespondError()", + "CacaoSignerTest", + "ChatTests\/testAcceptAndCreateNewThread()", + "ChatTests\/testInvite()", + "EIP1271VerifierTests", + "EIP191VerifierTests", + "PairingTests", + "PushTests\/testDappDeletePushSubscription()", + "PushTests\/testRequestPush()", + "PushTests\/testWalletApprovesPushRequest()", + "PushTests\/testWalletDeletePushSubscription()", + "PushTests\/testWalletRejectsPushRequest()", + "RegistryTests", + "RelayClientEndToEndTests", + "SignClientTests\/testCaip25SatisfyAllRequiredAllOptionalNamespacesSuccessful()", + "SignClientTests\/testCaip25SatisfyAllRequiredNamespacesSuccessful()", + "SignClientTests\/testCaip25SatisfyEmptyRequiredNamespacesExtraOptionalNamespacesSuccessful()", + "SignClientTests\/testCaip25SatisfyPartiallyRequiredNamespacesFails()", + "SignClientTests\/testCaip25SatisfyPartiallyRequiredNamespacesMethodsFails()", + "SignClientTests\/testNewSessionOnExistingPairing()", + "SignClientTests\/testSessionDelete()", + "SignClientTests\/testSessionEventFails()", + "SignClientTests\/testSessionEventSucceeds()", + "SignClientTests\/testSessionPing()", + "SignClientTests\/testSessionPropose()", + "SignClientTests\/testSessionReject()", + "SignClientTests\/testSessionRequestFailureResponse()", + "SignClientTests\/testSuccessfulSessionExtend()", + "SignClientTests\/testSuccessfulSessionUpdateNamespaces()", + "SignerTest" + ], + "target" : { + "containerPath" : "container:ExampleApp.xcodeproj", + "identifier" : "A5E03DEC286464DB00888481", + "name" : "IntegrationTests" + } + } + ], + "version" : 1 +} diff --git a/Example/WalletApp/Other/Colors.xcassets/grey50.colorset/Contents.json b/Example/WalletApp/Other/Colors.xcassets/grey50.colorset/Contents.json index ec37b029c..6d4f9a370 100644 --- a/Example/WalletApp/Other/Colors.xcassets/grey50.colorset/Contents.json +++ b/Example/WalletApp/Other/Colors.xcassets/grey50.colorset/Contents.json @@ -5,9 +5,9 @@ "color-space" : "srgb", "components" : { "alpha" : "1.000", - "blue" : "0x86", - "green" : "0x86", - "red" : "0x79" + "blue" : "134", + "green" : "134", + "red" : "121" } }, "idiom" : "universal" diff --git a/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsView.swift b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsView.swift index a6a6c3593..91f2f6f57 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsView.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/ConnectionDetails/ConnectionDetailsView.swift @@ -34,6 +34,7 @@ struct ConnectionDetailsView: View { .foregroundColor(.grey50) .font(.system(size: 13, weight: .medium, design: .rounded)) } + .padding(.horizontal, 15) ForEach(presenter.session.namespaces.keys.sorted(), id: \.self) { namespace in VStack { diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/Models/Proposal.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/Models/Proposal.swift deleted file mode 100644 index 437feb37b..000000000 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/Models/Proposal.swift +++ /dev/null @@ -1,58 +0,0 @@ -import WalletConnectSign - -struct Proposal { - let proposerName: String - let proposerDescription: String - let proposerURL: String - let iconURL: String - let permissions: [Namespace] - - struct Namespace: Hashable { - let chains: [String] - let methods: [String] - let events: [String] - } - - internal init(proposal: Session.Proposal) { - self.proposerName = proposal.proposer.name - self.proposerDescription = proposal.proposer.description - self.proposerURL = proposal.proposer.url - self.iconURL = proposal.proposer.icons.first ?? "https://avatars.githubusercontent.com/u/37784886" - self.permissions = [ - Namespace( - chains: ["eip155:1"], - methods: ["eth_sendTransaction", "personal_sign", "eth_signTypedData"], - events: ["accountsChanged", "chainChanged"] - ) - ] - } - - internal init(proposerName: String, proposerDescription: String, proposerURL: String, iconURL: String, permissions: [Proposal.Namespace]) { - self.proposerName = proposerName - self.proposerDescription = proposerDescription - self.proposerURL = proposerURL - self.iconURL = iconURL - self.permissions = permissions - } - - static func mock() -> Proposal { - Proposal( - proposerName: "Example name", - proposerDescription: "Example description", - proposerURL: "example.url", - iconURL: "https://avatars.githubusercontent.com/u/37784886", - permissions: [ - Namespace( - chains: ["eip155:1"], - methods: ["eth_sendTransaction", "personal_sign", "eth_signTypedData"], - events: ["accountsChanged", "chainChanged"] - ), - Namespace( - chains: ["cosmos:cosmoshub-2"], - methods: ["cosmos_signDirect", "cosmos_signAmino"], - events: [] - ) - ] - ) - } -} diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalPresenter.swift index 8e8b6b564..3c5eca87f 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalPresenter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalPresenter.swift @@ -7,8 +7,7 @@ final class SessionProposalPresenter: ObservableObject { private let interactor: SessionProposalInteractor private let router: SessionProposalRouter - let proposal: Proposal - private let sessionProposal: Session.Proposal + let sessionProposal: Session.Proposal private var disposeBag = Set() @@ -20,7 +19,6 @@ final class SessionProposalPresenter: ObservableObject { defer { setupInitialState() } self.interactor = interactor self.router = router - self.proposal = Proposal(proposal: proposal) self.sessionProposal = proposal } diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalView.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalView.swift index b8b3fc9e6..9c69a7043 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalView.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionProposal/SessionProposalView.swift @@ -1,4 +1,5 @@ import SwiftUI +import Web3Wallet struct SessionProposalView: View { @EnvironmentObject var presenter: SessionProposalPresenter @@ -17,7 +18,7 @@ struct SessionProposalView: View { .resizable() .scaledToFit() - Text(presenter.proposal.proposerName) + Text(presenter.sessionProposal.proposer.name) .foregroundColor(.grey8) .font(.system(size: 22, weight: .bold, design: .rounded)) .padding(.top, 10) @@ -26,14 +27,50 @@ struct SessionProposalView: View { .foregroundColor(.grey8) .font(.system(size: 22, weight: .medium, design: .rounded)) - Text(presenter.proposal.proposerName) + Text(presenter.sessionProposal.proposer.name) .foregroundColor(.grey50) .font(.system(size: 13, weight: .semibold, design: .rounded)) .multilineTextAlignment(.center) .lineSpacing(4) .padding(.top, 8) - sessionProposalView() + Divider() + .padding(.top, 12) + .padding(.horizontal, -18) + + ScrollView { + Text("Required namespaces".uppercased()) + .foregroundColor(.grey50) + .font(.system(size: 12, weight: .semibold, design: .rounded)) + .multilineTextAlignment(.center) + .lineSpacing(4) + .padding(.vertical, 12) + + ForEach(presenter.sessionProposal.requiredNamespaces.keys.sorted(), id: \.self) { chain in + if let namespaces = presenter.sessionProposal.requiredNamespaces[chain] { + sessionProposalView(namespaces: namespaces) + } + } + + if let optionalNamespaces = presenter.sessionProposal.optionalNamespaces { + if !optionalNamespaces.isEmpty { + Text("Optional namespaces".uppercased()) + .foregroundColor(.grey50) + .font(.system(size: 12, weight: .semibold, design: .rounded)) + .multilineTextAlignment(.center) + .lineSpacing(4) + .padding(.vertical, 12) + } + + ForEach(optionalNamespaces.keys.sorted(), id: \.self) { chain in + if let namespaces = optionalNamespaces[chain] { + sessionProposalView(namespaces: namespaces) + } + } + } + } + .frame(height: 250) + .padding(.top, 12) HStack(spacing: 20) { Button { @@ -92,19 +129,21 @@ struct SessionProposalView: View { } .edgesIgnoringSafeArea(.all) } - - private func sessionProposalView() -> some View { + //private func sessionProposalView(chain: String) -> some View { + private func sessionProposalView(namespaces: ProposalNamespace) -> 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) + TagsView(items: Array(namespaces.chains ?? Set())) { + Text($0.absoluteString.uppercased()) + .font(.system(size: 15, weight: .semibold, design: .rounded)) + .foregroundColor(.whiteBackground) + .padding(.horizontal, 8) + .padding(.vertical, 3) + .background(Color.grey70) + .cornerRadius(28, corners: .allCorners) + } + .padding(.horizontal, 15) + .padding(.top, 9) VStack(spacing: 0) { HStack { @@ -117,7 +156,7 @@ struct SessionProposalView: View { .padding(.horizontal, 18) .padding(.top, 10) - TagsView(items: presenter.proposal.permissions.first?.methods ?? []) { + TagsView(items: Array(namespaces.methods)) { Text($0) .foregroundColor(.cyanBackround) .font(.system(size: 13, weight: .semibold, design: .rounded)) @@ -132,37 +171,41 @@ struct SessionProposalView: View { .cornerRadius(20, corners: .allCorners) .padding(.horizontal, 5) - VStack(spacing: 0) { - HStack { - Text("Events") - .foregroundColor(.grey50) - .font(.system(size: 13, weight: .semibold, design: .rounded)) + if !namespaces.events.isEmpty { + VStack(spacing: 0) { + HStack { + Text("Events") + .foregroundColor(.grey50) + .font(.system(size: 13, weight: .semibold, design: .rounded)) + + Spacer() + } + .padding(.horizontal, 18) + .padding(.top, 10) - 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) + TagsView(items: Array(namespaces.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(10) + .background(Color.whiteBackground) + .cornerRadius(20, corners: .allCorners) + .padding(.horizontal, 5) + .padding(.bottom, 5) + } else { + Spacer(minLength: 5) } - .background(Color.whiteBackground) - .cornerRadius(20, corners: .allCorners) - .padding(.horizontal, 5) - .padding(.bottom, 5) } .background(.thinMaterial) .cornerRadius(25, corners: .allCorners) } - .padding(.top, 30) + .padding(.bottom, 15) } } diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestInteractor.swift index dce7d5fca..11aa20ce8 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestInteractor.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestInteractor.swift @@ -3,12 +3,16 @@ import Web3Wallet final class SessionRequestInteractor { 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) - ) + do { + let result = try Signer.sign(request: sessionRequest) + try await Web3Wallet.instance.respond( + topic: sessionRequest.topic, + requestId: sessionRequest.id, + response: .response(result) + ) + } catch { + throw error + } } func reject(sessionRequest: Request) async throws { diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestPresenter.swift index bdff02f2b..c811d9f77 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestPresenter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestPresenter.swift @@ -7,6 +7,9 @@ final class SessionRequestPresenter: ObservableObject { private let interactor: SessionRequestInteractor private let router: SessionRequestRouter + @Published var showError = false + @Published var errorMessage = "Error" + let sessionRequest: Request var message: String { @@ -28,8 +31,13 @@ final class SessionRequestPresenter: ObservableObject { @MainActor func onApprove() async throws { - try await interactor.approve(sessionRequest: sessionRequest) - router.dismiss() + do { + try await interactor.approve(sessionRequest: sessionRequest) + router.dismiss() + } catch { + errorMessage = error.localizedDescription + showError.toggle() + } } @MainActor diff --git a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestView.swift b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestView.swift index 053cb34c2..e6a719606 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestView.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/SessionRequest/SessionRequestView.swift @@ -22,7 +22,9 @@ struct SessionRequestView: View { .font(.system(size: 22, weight: .bold, design: .rounded)) .padding(.top, 10) - authRequestView() + if presenter.message != "[:]" { + authRequestView() + } HStack(spacing: 20) { Button { @@ -78,6 +80,9 @@ struct SessionRequestView: View { Spacer() } + .alert(presenter.errorMessage, isPresented: $presenter.showError) { + Button("OK", role: .cancel) {} + } } .edgesIgnoringSafeArea(.all) } diff --git a/Makefile b/Makefile index fa43c4abf..04ea64890 100755 --- a/Makefile +++ b/Makefile @@ -29,7 +29,22 @@ unit_tests: fastlane tests scheme:WalletConnect integration_tests: - fastlane tests scheme:IntegrationTests relay_host:$(RELAY_HOST) project_id:$(PROJECT_ID) + fastlane tests scheme:IntegrationTests testplan:IntegrationTests relay_host:$(RELAY_HOST) project_id:$(PROJECT_ID) + +relay_tests: + fastlane tests scheme:RelayIntegrationTests relay_host:$(RELAY_HOST) project_id:$(PROJECT_ID) + +smoke_tests: + xcodebuild \ + -project Example/ExampleApp.xcodeproj \ + -scheme IntegrationTests \ + -testPlan SmokeTests \ + -clonedSourcePackagesDirPath SourcePackagesCache \ + -destination 'platform=iOS Simulator,name=iPhone 14' \ + -derivedDataPath DerivedDataCache \ + RELAY_HOST=$(RELAY_HOST) \ + PROJECT_ID=$(PROJECT_ID) \ + test resolve_packages: fastlane resolve scheme:WalletApp diff --git a/Sources/WalletConnectRelay/AppStateObserving.swift b/Sources/WalletConnectRelay/AppStateObserving.swift index 3db4ff629..9626d463e 100644 --- a/Sources/WalletConnectRelay/AppStateObserving.swift +++ b/Sources/WalletConnectRelay/AppStateObserving.swift @@ -11,7 +11,7 @@ enum ApplicationState { } protocol AppStateObserving: AnyObject { - var currentState: ApplicationState { get } + var currentState: ApplicationState { get async } var onWillEnterForeground: (() -> Void)? {get set} var onWillEnterBackground: (() -> Void)? {get set} } @@ -26,14 +26,17 @@ class AppStateObserver: AppStateObserving { subscribeNotificationCenter() } - var currentState: ApplicationState { + @MainActor + var currentState: ApplicationState{ + get async { #if canImport(UIKit) - let isActive = UIApplication.shared.applicationState == .active - return isActive ? .foreground : .background + let isActive = UIApplication.shared.applicationState == .active + return isActive ? .foreground : .background #elseif canImport(AppKit) - let isActive = NSApplication.shared.isActive - return isActive ? .foreground : .background + let isActive = NSApplication.shared.isActive + return isActive ? .foreground : .background #endif + } } private func subscribeNotificationCenter() { diff --git a/Sources/WalletConnectRelay/Dispatching.swift b/Sources/WalletConnectRelay/Dispatching.swift index dd32df37b..73fa3c5b2 100644 --- a/Sources/WalletConnectRelay/Dispatching.swift +++ b/Sources/WalletConnectRelay/Dispatching.swift @@ -103,7 +103,10 @@ final class Dispatcher: NSObject, Dispatching { } socket.onDisconnect = { [unowned self] _ in self.socketConnectionStatusPublisherSubject.send(.disconnected) - self.socketConnectionHandler.handleDisconnection() + + Task(priority: .high) { + await self.socketConnectionHandler.handleDisconnection() + } } } } diff --git a/Sources/WalletConnectRelay/PackageConfig.json b/Sources/WalletConnectRelay/PackageConfig.json index b4f543928..818e3430c 100644 --- a/Sources/WalletConnectRelay/PackageConfig.json +++ b/Sources/WalletConnectRelay/PackageConfig.json @@ -1 +1 @@ -{"version": "1.5.0"} +{"version": "1.5.1"} diff --git a/Sources/WalletConnectRelay/SocketConnectionHandler/AutomaticSocketConnectionHandler.swift b/Sources/WalletConnectRelay/SocketConnectionHandler/AutomaticSocketConnectionHandler.swift index 5e95f79b8..804ee14f0 100644 --- a/Sources/WalletConnectRelay/SocketConnectionHandler/AutomaticSocketConnectionHandler.swift +++ b/Sources/WalletConnectRelay/SocketConnectionHandler/AutomaticSocketConnectionHandler.swift @@ -80,9 +80,8 @@ extension AutomaticSocketConnectionHandler: SocketConnectionHandler { throw Errors.manualSocketDisconnectionForbidden } - func handleDisconnection() { - if appStateObserver.currentState == .foreground { - reconnectIfNeeded() - } + func handleDisconnection() async { + guard await appStateObserver.currentState == .foreground else { return } + reconnectIfNeeded() } } diff --git a/Sources/WalletConnectRelay/SocketConnectionHandler/ManualSocketConnectionHandler.swift b/Sources/WalletConnectRelay/SocketConnectionHandler/ManualSocketConnectionHandler.swift index bed340e44..7f145d1c5 100644 --- a/Sources/WalletConnectRelay/SocketConnectionHandler/ManualSocketConnectionHandler.swift +++ b/Sources/WalletConnectRelay/SocketConnectionHandler/ManualSocketConnectionHandler.swift @@ -15,7 +15,7 @@ class ManualSocketConnectionHandler: SocketConnectionHandler { socket.disconnect() } - func handleDisconnection() { + func handleDisconnection() async { // No operation // ManualSocketConnectionHandler does not support reconnection logic } diff --git a/Sources/WalletConnectRelay/SocketConnectionHandler/SocketConnectionHandler.swift b/Sources/WalletConnectRelay/SocketConnectionHandler/SocketConnectionHandler.swift index 035d1d1df..4ac3046dd 100644 --- a/Sources/WalletConnectRelay/SocketConnectionHandler/SocketConnectionHandler.swift +++ b/Sources/WalletConnectRelay/SocketConnectionHandler/SocketConnectionHandler.swift @@ -3,5 +3,5 @@ import Foundation protocol SocketConnectionHandler { func handleConnect() throws func handleDisconnect(closeCode: URLSessionWebSocketTask.CloseCode) throws - func handleDisconnection() + func handleDisconnection() async } diff --git a/Tests/RelayerTests/AutomaticSocketConnectionHandlerTests.swift b/Tests/RelayerTests/AutomaticSocketConnectionHandlerTests.swift index 1207b4335..92c0895af 100644 --- a/Tests/RelayerTests/AutomaticSocketConnectionHandlerTests.swift +++ b/Tests/RelayerTests/AutomaticSocketConnectionHandlerTests.swift @@ -55,19 +55,19 @@ final class AutomaticSocketConnectionHandlerTests: XCTestCase { XCTAssertFalse(webSocketSession.isConnected) } - func testReconnectOnDisconnectForeground() { + func testReconnectOnDisconnectForeground() async { appStateObserver.currentState = .foreground XCTAssertTrue(webSocketSession.isConnected) webSocketSession.disconnect() - sut.handleDisconnection() + await sut.handleDisconnection() XCTAssertTrue(webSocketSession.isConnected) } - func testReconnectOnDisconnectBackground() { + func testReconnectOnDisconnectBackground() async { appStateObserver.currentState = .background XCTAssertTrue(webSocketSession.isConnected) webSocketSession.disconnect() - sut.handleDisconnection() + await sut.handleDisconnection() XCTAssertFalse(webSocketSession.isConnected) } } diff --git a/fastlane/Fastfile b/fastlane/Fastfile index b32acd249..3c19c1be9 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -23,6 +23,7 @@ platform :ios do run_tests( project: 'Example/ExampleApp.xcodeproj', scheme: options[:scheme], + testplan: options[:testplan], cloned_source_packages_path: 'SourcePackagesCache', destination: 'platform=iOS Simulator,name=iPhone 13', derived_data_path: 'DerivedDataCache',