diff --git a/.env.Showcase b/.env.Showcase
index c08277921..d15a1ba0e 100644
--- a/.env.Showcase
+++ b/.env.Showcase
@@ -1,3 +1,4 @@
SCHEME = "Showcase"
APP_IDENTIFIER = "com.walletconnect.chat"
+MATCH_IDENTIFIERS = "com.walletconnect.chat"
APPLE_ID = "1634760092"
\ No newline at end of file
diff --git a/.env.WalletApp b/.env.WalletApp
index 5ac0d15e7..9396014a6 100644
--- a/.env.WalletApp
+++ b/.env.WalletApp
@@ -1,3 +1,4 @@
SCHEME = "WalletApp"
APP_IDENTIFIER = "com.walletconnect.walletapp"
+MATCH_IDENTIFIERS = "com.walletconnect.walletapp,com.walletconnect.walletapp.PNDecryptionService"
APPLE_ID = "1667351690"
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 000000000..5246d94d9
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,42 @@
+name: release
+
+on:
+ schedule:
+ # Runs "Every Monday 10am CET"
+ - cron: '0 10 * * 1'
+
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: macos-12
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Setup Xcode Version
+ uses: maxim-lobanov/setup-xcode@v1
+ with:
+ xcode-version: 14.1
+
+ - uses: actions/cache@v2
+ with:
+ path: |
+ .build
+ SourcePackagesCache
+ DerivedDataCache
+ key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
+ restore-keys: |
+ ${{ runner.os }}-spm-
+
+ - name: Release
+ shell: bash
+ env:
+ MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
+ GH_TOKEN: ${{ secrets.GH_TOKEN }}
+ GH_USER: ${{ secrets.GH_USER }}
+ APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
+ APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
+ APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
+ run: |
+ make release_all APPLE_ID=${{ secrets.APPLE_ID }} TOKEN=$(echo -n $GH_USER:$GH_TOKEN | base64)
diff --git a/.gitignore b/.gitignore
index 64e06f6b1..cdf6e24d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@ fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output
fastlane/README.md
+.env
# Configuration
Configuration.xcconfig
@@ -28,4 +29,5 @@ SourcePackagesCache
DerivedDataCache
# Artifacts
-*.ipa
\ No newline at end of file
+*.ipa
+*.zip
\ No newline at end of file
diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/WalletConnectEcho.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/WalletConnectEcho.xcscheme
new file mode 100644
index 000000000..f788c492b
--- /dev/null
+++ b/.swiftpm/xcode/xcshareddata/xcschemes/WalletConnectEcho.xcscheme
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj
index dd044d0bc..54f6bdddd 100644
--- a/Example/ExampleApp.xcodeproj/project.pbxproj
+++ b/Example/ExampleApp.xcodeproj/project.pbxproj
@@ -28,11 +28,23 @@
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 */; };
+ 84310D05298BC980000C15B6 /* MainInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84310D04298BC980000C15B6 /* MainInteractor.swift */; };
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 */; };
845B8D8C2934B36C0084A966 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845B8D8B2934B36C0084A966 /* Account.swift */; };
8460DCFC274F98A10081F94C /* RequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8460DCFB274F98A10081F94C /* RequestViewController.swift */; };
+ 847BD1D62989492500076C90 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847BD1D12989492500076C90 /* MainViewController.swift */; };
+ 847BD1D82989492500076C90 /* MainModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847BD1D32989492500076C90 /* MainModule.swift */; };
+ 847BD1D92989492500076C90 /* MainPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847BD1D42989492500076C90 /* MainPresenter.swift */; };
+ 847BD1DA2989492500076C90 /* MainRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847BD1D52989492500076C90 /* MainRouter.swift */; };
+ 847BD1DD2989494F00076C90 /* TabPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847BD1DC2989494F00076C90 /* TabPage.swift */; };
+ 847BD1E4298A806800076C90 /* NotificationsModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847BD1DF298A806800076C90 /* NotificationsModule.swift */; };
+ 847BD1E5298A806800076C90 /* NotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847BD1E0298A806800076C90 /* NotificationsPresenter.swift */; };
+ 847BD1E6298A806800076C90 /* NotificationsRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847BD1E1298A806800076C90 /* NotificationsRouter.swift */; };
+ 847BD1E7298A806800076C90 /* NotificationsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847BD1E2298A806800076C90 /* NotificationsInteractor.swift */; };
+ 847BD1E8298A806800076C90 /* NotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847BD1E3298A806800076C90 /* NotificationsView.swift */; };
+ 847BD1EB298A87AB00076C90 /* SubscriptionsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847BD1EA298A87AB00076C90 /* SubscriptionsViewModel.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 */; };
@@ -42,6 +54,7 @@
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 */; };
+ 84B8154E2991099000FAD54E /* BuildConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B8154D2991099000FAD54E /* BuildConfiguration.swift */; };
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 */; };
@@ -360,10 +373,22 @@
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 = ""; };
+ 84310D04298BC980000C15B6 /* MainInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainInteractor.swift; 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 = ""; };
+ 847BD1D12989492500076C90 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; };
+ 847BD1D32989492500076C90 /* MainModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainModule.swift; sourceTree = ""; };
+ 847BD1D42989492500076C90 /* MainPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainPresenter.swift; sourceTree = ""; };
+ 847BD1D52989492500076C90 /* MainRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainRouter.swift; sourceTree = ""; };
+ 847BD1DC2989494F00076C90 /* TabPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabPage.swift; sourceTree = ""; };
+ 847BD1DF298A806800076C90 /* NotificationsModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsModule.swift; sourceTree = ""; };
+ 847BD1E0298A806800076C90 /* NotificationsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsPresenter.swift; sourceTree = ""; };
+ 847BD1E1298A806800076C90 /* NotificationsRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsRouter.swift; sourceTree = ""; };
+ 847BD1E2298A806800076C90 /* NotificationsInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsInteractor.swift; sourceTree = ""; };
+ 847BD1E3298A806800076C90 /* NotificationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsView.swift; sourceTree = ""; };
+ 847BD1EA298A87AB00076C90 /* SubscriptionsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsViewModel.swift; sourceTree = ""; };
8485617E295307C20064877B /* PushNotificationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationTests.swift; sourceTree = ""; };
849A4F18298281E300E61ACE /* WalletAppRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WalletAppRelease.entitlements; sourceTree = ""; };
849A4F19298281F100E61ACE /* PNDecryptionServiceRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PNDecryptionServiceRelease.entitlements; sourceTree = ""; };
@@ -372,6 +397,7 @@
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 = ""; };
+ 84B8154D2991099000FAD54E /* BuildConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BuildConfiguration.swift; 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 = ""; };
@@ -801,6 +827,48 @@
path = SessionDetails;
sourceTree = "";
};
+ 847BD1DB2989493F00076C90 /* Main */ = {
+ isa = PBXGroup;
+ children = (
+ 847BD1D32989492500076C90 /* MainModule.swift */,
+ 847BD1D42989492500076C90 /* MainPresenter.swift */,
+ 84310D04298BC980000C15B6 /* MainInteractor.swift */,
+ 847BD1D52989492500076C90 /* MainRouter.swift */,
+ 847BD1D12989492500076C90 /* MainViewController.swift */,
+ 847BD1DE2989495C00076C90 /* Model */,
+ );
+ path = Main;
+ sourceTree = "";
+ };
+ 847BD1DE2989495C00076C90 /* Model */ = {
+ isa = PBXGroup;
+ children = (
+ 847BD1DC2989494F00076C90 /* TabPage.swift */,
+ );
+ path = Model;
+ sourceTree = "";
+ };
+ 847BD1E9298A807000076C90 /* Notifications */ = {
+ isa = PBXGroup;
+ children = (
+ 847BD1DF298A806800076C90 /* NotificationsModule.swift */,
+ 847BD1E0298A806800076C90 /* NotificationsPresenter.swift */,
+ 847BD1E1298A806800076C90 /* NotificationsRouter.swift */,
+ 847BD1E2298A806800076C90 /* NotificationsInteractor.swift */,
+ 847BD1E3298A806800076C90 /* NotificationsView.swift */,
+ 847BD1EC298A87C300076C90 /* Models */,
+ );
+ path = Notifications;
+ sourceTree = "";
+ };
+ 847BD1EC298A87C300076C90 /* Models */ = {
+ isa = PBXGroup;
+ children = (
+ 847BD1EA298A87AB00076C90 /* SubscriptionsViewModel.swift */,
+ );
+ path = Models;
+ sourceTree = "";
+ };
849D7A91292E2115006A2BD4 /* Push */ = {
isa = PBXGroup;
children = (
@@ -1463,6 +1531,7 @@
C56EE229293F5668004840D1 /* Wallet */ = {
isa = PBXGroup;
children = (
+ 847BD1DB2989493F00076C90 /* Main */,
C55D3477295DD4AA0004314A /* Welcome */,
C55D3474295DCB850004314A /* AuthRequest */,
C55D349E2965FAC30004314A /* SessionProposal */,
@@ -1472,6 +1541,7 @@
C56EE236293F566A004840D1 /* Scan */,
C56EE22A293F5668004840D1 /* Wallet */,
84E6B8592981625A00428BAF /* PushRequest */,
+ 847BD1E9298A807000076C90 /* Notifications */,
);
path = Wallet;
sourceTree = "";
@@ -1515,6 +1585,7 @@
isa = PBXGroup;
children = (
C56EE25D293F56D6004840D1 /* InputConfig.swift */,
+ 84B8154D2991099000FAD54E /* BuildConfiguration.swift */,
C56EE267293F56D6004840D1 /* Style */,
C56EE2A1293F6B9E004840D1 /* Helpers */,
C56EE262293F56D6004840D1 /* Extensions */,
@@ -2174,19 +2245,25 @@
84E6B8582981624F00428BAF /* PushRequestModule.swift in Sources */,
C55D3480295DD7140004314A /* AuthRequestPresenter.swift in Sources */,
84E6B85B298162EF00428BAF /* PushRequestPresenter.swift in Sources */,
+ 847BD1DA2989492500076C90 /* MainRouter.swift in Sources */,
C5F32A2E2954814A00A6476E /* ConnectionDetailsRouter.swift in Sources */,
C55D3482295DD7140004314A /* AuthRequestInteractor.swift in Sources */,
C55D34B12965FB750004314A /* SessionProposalInteractor.swift in Sources */,
C56EE247293F566D004840D1 /* ScanModule.swift in Sources */,
C56EE28D293F5757004840D1 /* AppearanceConfigurator.swift in Sources */,
+ 847BD1D82989492500076C90 /* MainModule.swift in Sources */,
C5B2F7112970583B000DBA0E /* SessionInfo.swift in Sources */,
+ 847BD1E7298A806800076C90 /* NotificationsInteractor.swift in Sources */,
C56EE241293F566D004840D1 /* WalletModule.swift in Sources */,
C56EE245293F566D004840D1 /* WalletPresenter.swift in Sources */,
C56EE240293F566D004840D1 /* ScanQRView.swift in Sources */,
C56EE250293F566D004840D1 /* ScanTargetView.swift in Sources */,
C56EE28F293F5757004840D1 /* MigrationConfigurator.swift in Sources */,
+ 847BD1DD2989494F00076C90 /* TabPage.swift in Sources */,
C55D348B295DD8CA0004314A /* PasteUriRouter.swift in Sources */,
+ 847BD1E4298A806800076C90 /* NotificationsModule.swift in Sources */,
C55D348C295DD8CA0004314A /* PasteUriInteractor.swift in Sources */,
+ 847BD1D92989492500076C90 /* MainPresenter.swift in Sources */,
C55D3497295DFA750004314A /* WelcomeView.swift in Sources */,
C5B2F71029705827000DBA0E /* EthereumTransaction.swift in Sources */,
C56EE271293F56D7004840D1 /* View.swift in Sources */,
@@ -2203,11 +2280,14 @@
C55D3493295DFA750004314A /* WelcomeModule.swift in Sources */,
C56EE270293F56D7004840D1 /* String.swift in Sources */,
C56EE279293F56D7004840D1 /* Color.swift in Sources */,
+ 847BD1E6298A806800076C90 /* NotificationsRouter.swift in Sources */,
84E6B8612981630C00428BAF /* PushRequestView.swift in Sources */,
84E6B85F2981630000428BAF /* PushRequestInteractor.swift in Sources */,
C55D3483295DD7140004314A /* AuthRequestView.swift in Sources */,
C56EE243293F566D004840D1 /* ScanView.swift in Sources */,
+ 84310D05298BC980000C15B6 /* MainInteractor.swift in Sources */,
C56EE288293F5757004840D1 /* ThirdPartyConfigurator.swift in Sources */,
+ 847BD1D62989492500076C90 /* MainViewController.swift in Sources */,
C5B2F6FA29705293000DBA0E /* SessionRequestInteractor.swift in Sources */,
C55D34AE2965FB750004314A /* SessionProposalModule.swift in Sources */,
C55D34B02965FB750004314A /* SessionProposalRouter.swift in Sources */,
@@ -2216,7 +2296,9 @@
C56EE24F293F566D004840D1 /* WalletView.swift in Sources */,
C55D34B22965FB750004314A /* SessionProposalView.swift in Sources */,
C56EE248293F566D004840D1 /* ScanQR.swift in Sources */,
+ 847BD1EB298A87AB00076C90 /* SubscriptionsViewModel.swift in Sources */,
C55D349B2965BC2F0004314A /* TagsView.swift in Sources */,
+ 84B8154E2991099000FAD54E /* BuildConfiguration.swift in Sources */,
C56EE289293F5757004840D1 /* Application.swift in Sources */,
C56EE273293F56D7004840D1 /* UIColor.swift in Sources */,
C5F32A322954816C00A6476E /* ConnectionDetailsPresenter.swift in Sources */,
@@ -2231,6 +2313,7 @@
84DB38F32983CDAE00BFEE37 /* PushRegisterer.swift in Sources */,
C5B2F6FB297055B0000DBA0E /* ETHSigner.swift in Sources */,
C56EE274293F56D7004840D1 /* SceneViewController.swift in Sources */,
+ 847BD1E5298A806800076C90 /* NotificationsPresenter.swift in Sources */,
C55D3496295DFA750004314A /* WelcomeInteractor.swift in Sources */,
84E6B85D298162F700428BAF /* PushRequestRouter.swift in Sources */,
C5B2F6FC297055B0000DBA0E /* SOLSigner.swift in Sources */,
@@ -2243,6 +2326,7 @@
C56EE24E293F566D004840D1 /* WalletInteractor.swift in Sources */,
C55D34AF2965FB750004314A /* SessionProposalPresenter.swift in Sources */,
C5F32A302954816100A6476E /* ConnectionDetailsInteractor.swift in Sources */,
+ 847BD1E8298A806800076C90 /* NotificationsView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2496,6 +2580,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.example.PushDecryptionService;
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
@@ -2525,6 +2610,7 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.example.PushDecryptionService;
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
@@ -2605,14 +2691,17 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = PNDecryptionService/PNDecryptionService.entitlements;
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- DEVELOPMENT_TEAM = W5R8AG9K22;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ CODE_SIGN_STYLE = Manual;
+ CURRENT_PROJECT_VERSION = 7;
+ DEVELOPMENT_TEAM = "";
+ "DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = PNDecryptionService/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = PNDecryptionService;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
- IPHONEOS_DEPLOYMENT_TARGET = 16.2;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -2621,6 +2710,8 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.walletapp.PNDecryptionService;
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development com.walletconnect.walletapp.PNDecryptionService";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
@@ -2634,14 +2725,16 @@
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = PNDecryptionService/PNDecryptionServiceRelease.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- DEVELOPMENT_TEAM = W5R8AG9K22;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
+ CODE_SIGN_STYLE = Manual;
+ CURRENT_PROJECT_VERSION = 7;
+ DEVELOPMENT_TEAM = "";
+ "DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = PNDecryptionService/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = PNDecryptionService;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
- IPHONEOS_DEPLOYMENT_TARGET = 16.2;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -2651,6 +2744,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.walletapp.PNDecryptionService;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.walletconnect.walletapp.PNDecryptionService";
SKIP_INSTALL = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
@@ -2664,9 +2758,11 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
- CODE_SIGN_STYLE = Automatic;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 7;
- DEVELOPMENT_TEAM = W5R8AG9K22;
+ DEVELOPMENT_TEAM = "";
+ "DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Showcase/Other/Info.plist;
INFOPLIST_KEY_NSCameraUsageDescription = "Allow the app to scan for QR codes";
@@ -2682,6 +2778,8 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.chat;
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development com.walletconnect.chat";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -2694,9 +2792,11 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
- CODE_SIGN_STYLE = Automatic;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
+ CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 7;
- DEVELOPMENT_TEAM = W5R8AG9K22;
+ DEVELOPMENT_TEAM = "";
+ "DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Showcase/Other/Info.plist;
INFOPLIST_KEY_NSCameraUsageDescription = "Allow the app to scan for QR codes";
@@ -2712,6 +2812,8 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.chat;
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.walletconnect.chat";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -2801,12 +2903,15 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = WalletApp/WalletApp.entitlements;
- CODE_SIGN_STYLE = Automatic;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 7;
- DEVELOPMENT_TEAM = W5R8AG9K22;
+ DEVELOPMENT_TEAM = "";
+ "DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WalletApp/Other/Info.plist;
+ INFOPLIST_KEY_NSCameraUsageDescription = "Camera access for scanning QR code";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
@@ -2819,6 +2924,8 @@
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.walletapp;
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development com.walletconnect.walletapp";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -2833,13 +2940,16 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = WalletApp/WalletAppRelease.entitlements;
- CODE_SIGN_IDENTITY = "Apple Development";
- CODE_SIGN_STYLE = Automatic;
+ CODE_SIGN_IDENTITY = "Apple Distribution";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
+ CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 7;
- DEVELOPMENT_TEAM = W5R8AG9K22;
+ DEVELOPMENT_TEAM = "";
+ "DEVELOPMENT_TEAM[sdk=iphoneos*]" = W5R8AG9K22;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = WalletApp/Other/Info.plist;
+ INFOPLIST_KEY_NSCameraUsageDescription = "Camera access for scanning QR code";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
@@ -2853,6 +2963,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.walletapp;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
+ "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match AppStore com.walletconnect.walletapp";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/Example/IntegrationTests/Pairing/PairingTests.swift b/Example/IntegrationTests/Pairing/PairingTests.swift
index b0f51314a..83e44ca16 100644
--- a/Example/IntegrationTests/Pairing/PairingTests.swift
+++ b/Example/IntegrationTests/Pairing/PairingTests.swift
@@ -69,7 +69,7 @@ final class PairingTests: XCTestCase {
let (pairingClient, networkingInteractor, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let pushLogger = ConsoleLogger(suffix: prefix + " [Push]", loggingLevel: .debug)
walletPairingClient = pairingClient
- let echoClient = EchoClientFactory.create(projectId: "", clientId: "", echoHost: "echo.walletconnect.com")
+ let echoClient = EchoClientFactory.create(projectId: "", clientId: "", echoHost: "echo.walletconnect.com", environment: .sandbox)
walletPushClient = WalletPushClientFactory.create(logger: pushLogger,
keyValueStorage: keyValueStorage,
keychainStorage: keychain,
diff --git a/Example/IntegrationTests/Push/PushTests.swift b/Example/IntegrationTests/Push/PushTests.swift
index a8619ba30..6e14ee3ec 100644
--- a/Example/IntegrationTests/Push/PushTests.swift
+++ b/Example/IntegrationTests/Push/PushTests.swift
@@ -69,7 +69,7 @@ final class PushTests: XCTestCase {
let (pairingClient, networkingInteractor, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let pushLogger = ConsoleLogger(suffix: prefix + " [Push]", loggingLevel: .debug)
walletPairingClient = pairingClient
- let echoClient = EchoClientFactory.create(projectId: "", clientId: "", echoHost: "echo.walletconnect.com")
+ let echoClient = EchoClientFactory.create(projectId: "", clientId: "", echoHost: "echo.walletconnect.com", environment: .sandbox)
walletPushClient = WalletPushClientFactory.create(logger: pushLogger,
keyValueStorage: keyValueStorage,
keychainStorage: keychain,
diff --git a/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift
index 298207e2b..f06ba1b35 100644
--- a/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift
+++ b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift
@@ -15,8 +15,7 @@ struct ThirdPartyConfigurator: Configurator {
)
Web3Wallet.configure(metadata: metadata, signerFactory: DefaultSignerFactory())
- Push.configure()
-
+ Push.configure(environment: BuildConfiguration.shared.apnsEnvironment)
}
}
diff --git a/Example/WalletApp/Common/BuildConfiguration.swift b/Example/WalletApp/Common/BuildConfiguration.swift
new file mode 100644
index 000000000..f17d08e73
--- /dev/null
+++ b/Example/WalletApp/Common/BuildConfiguration.swift
@@ -0,0 +1,27 @@
+import Foundation
+import WalletConnectPush
+
+class BuildConfiguration {
+ enum Environment: String {
+ case debug = "Debug"
+ case release = "Release"
+ }
+
+ static let shared = BuildConfiguration()
+
+ var environment: Environment
+
+ var apnsEnvironment: APNSEnvironment {
+ switch environment {
+ case .debug:
+ return .sandbox
+ case .release:
+ return .production
+ }
+ }
+
+ init() {
+ let currentConfiguration = Bundle.main.object(forInfoDictionaryKey: "CONFIGURATION") as! String
+ environment = Environment(rawValue: currentConfiguration)!
+ }
+}
diff --git a/Example/WalletApp/Other/Info.plist b/Example/WalletApp/Other/Info.plist
index 08395f3e9..d1c9f04ea 100644
--- a/Example/WalletApp/Other/Info.plist
+++ b/Example/WalletApp/Other/Info.plist
@@ -28,8 +28,10 @@
PROJECT_ID
$(PROJECT_ID)
- NSCameraUsageDescription
- Camera access for scanning QR code
+ SIMULATOR_IDENTIFIER
+ $(SIMULATOR_IDENTIFIER)
+ CONFIGURATION
+ $(CONFIGURATION)
UIApplicationSceneManifest
UIApplicationSupportsMultipleScenes
@@ -47,7 +49,9 @@
- SIMULATOR_IDENTIFIER
- $(SIMULATOR_IDENTIFIER)
+ UIBackgroundModes
+
+ remote-notification
+
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Main/MainInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/Main/MainInteractor.swift
new file mode 100644
index 000000000..7487db34c
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Main/MainInteractor.swift
@@ -0,0 +1,15 @@
+import Combine
+import Web3Wallet
+import WalletConnectPush
+import Foundation
+
+final class MainInteractor {
+
+ var sessionProposalPublisher: AnyPublisher {
+ return Web3Wallet.instance.sessionProposalPublisher
+ }
+
+ var pushRequestPublisher: AnyPublisher<(id: RPCID, account: Account, metadata: AppMetadata), Never> {
+ return Push.wallet.requestPublisher
+ }
+}
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Main/MainModule.swift b/Example/WalletApp/PresentationLayer/Wallet/Main/MainModule.swift
new file mode 100644
index 000000000..da47d310c
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Main/MainModule.swift
@@ -0,0 +1,17 @@
+import SwiftUI
+
+final class MainModule {
+
+ @discardableResult
+ static func create(app: Application) -> UIViewController {
+ let router = MainRouter(app: app)
+ let interactor = MainInteractor()
+ let presenter = MainPresenter(router: router, interactor: interactor)
+ let viewController = MainViewController(presenter: presenter)
+
+ router.viewController = viewController
+
+ return viewController
+ }
+
+}
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Main/MainPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/Main/MainPresenter.swift
new file mode 100644
index 000000000..d33cd6bf3
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Main/MainPresenter.swift
@@ -0,0 +1,48 @@
+import UIKit
+import Combine
+
+final class MainPresenter {
+
+ private let interactor: MainInteractor
+ private let router: MainRouter
+ private var disposeBag = Set()
+
+ var tabs: [TabPage] {
+ return TabPage.allCases
+ }
+
+ var viewControllers: [UIViewController] {
+ return [
+ router.walletViewController(),
+ router.notificationsViewController(),
+ ]
+ }
+
+ init(router: MainRouter,
+ interactor: MainInteractor) {
+ defer {
+ setupInitialState()
+ }
+ self.router = router
+ self.interactor = interactor
+ }
+}
+
+// MARK: - Private functions
+extension MainPresenter {
+ private func setupInitialState() {
+ interactor.pushRequestPublisher
+ .receive(on: DispatchQueue.main)
+ .sink { [weak self] request in
+ self?.router.present(pushRequest: request)
+ }.store(in: &disposeBag)
+
+ interactor.sessionProposalPublisher
+ .receive(on: DispatchQueue.main)
+ .sink { [weak self] proposal in
+ self?.router.present(proposal: proposal)
+ }
+ .store(in: &disposeBag)
+ }
+}
+
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Main/MainRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/Main/MainRouter.swift
new file mode 100644
index 000000000..75d71e842
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Main/MainRouter.swift
@@ -0,0 +1,33 @@
+import UIKit
+import WalletConnectPush
+import Web3Wallet
+final class MainRouter {
+
+ weak var viewController: UIViewController!
+
+ private let app: Application
+
+ func walletViewController() -> UIViewController {
+ return WalletModule.create(app: app)
+ .wrapToNavigationController()
+ }
+
+ func present(proposal: Session.Proposal) {
+ SessionProposalModule.create(app: app, proposal: proposal)
+ .presentFullScreen(from: viewController, transparentBackground: true)
+ }
+
+ func notificationsViewController() -> UIViewController {
+ return NotificationsModule.create(app: app)
+ .wrapToNavigationController()
+ }
+
+ func present(pushRequest: PushRequest) {
+ PushRequestModule.create(app: app, pushRequest: pushRequest)
+ .presentFullScreen(from: viewController, transparentBackground: true)
+ }
+
+ init(app: Application) {
+ self.app = app
+ }
+}
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Main/MainViewController.swift b/Example/WalletApp/PresentationLayer/Wallet/Main/MainViewController.swift
new file mode 100644
index 000000000..5fd88ac40
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Main/MainViewController.swift
@@ -0,0 +1,38 @@
+import UIKit
+
+final class MainViewController: UITabBarController {
+
+ private let presenter: MainPresenter
+
+ init(presenter: MainPresenter) {
+ self.presenter = presenter
+ super.init(nibName: nil, bundle: nil)
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ setupTabs()
+ }
+
+ private func setupTabs() {
+ let viewControllers = presenter.viewControllers
+
+ for (index, viewController) in viewControllers.enumerated() {
+ let model = presenter.tabs[index]
+ let item = UITabBarItem()
+ item.title = model.title
+ item.image = model.icon
+ item.isEnabled = TabPage.enabledTabs.contains(model)
+ viewController.tabBarItem = item
+ viewController.view.backgroundColor = .w_background
+ }
+
+ self.viewControllers = viewControllers
+ self.selectedIndex = TabPage.selectedIndex
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Main/Model/TabPage.swift b/Example/WalletApp/PresentationLayer/Wallet/Main/Model/TabPage.swift
new file mode 100644
index 000000000..0416f515c
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Main/Model/TabPage.swift
@@ -0,0 +1,32 @@
+import UIKit
+
+enum TabPage: CaseIterable {
+ case wallet
+ case notifications
+
+ var title: String {
+ switch self {
+ case .wallet:
+ return "Apps"
+ case .notifications:
+ return "Notifications"
+ }
+ }
+
+ var icon: UIImage {
+ switch self {
+ case .wallet:
+ return UIImage(systemName: "house.fill")!
+ case .notifications:
+ return UIImage(systemName: "bell.fill")!
+ }
+ }
+
+ static var selectedIndex: Int {
+ return 0
+ }
+
+ static var enabledTabs: [TabPage] {
+ return [.wallet, .notifications]
+ }
+}
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Notifications/Models/SubscriptionsViewModel.swift b/Example/WalletApp/PresentationLayer/Wallet/Notifications/Models/SubscriptionsViewModel.swift
new file mode 100644
index 000000000..caf9826ee
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Notifications/Models/SubscriptionsViewModel.swift
@@ -0,0 +1,22 @@
+import Foundation
+import WalletConnectPush
+
+struct SubscriptionsViewModel: Identifiable {
+ let subscription: WalletConnectPush.PushSubscription
+
+ var id: String {
+ return subscription.topic
+ }
+
+ var imageUrl: String {
+ return subscription.metadata.url
+ }
+
+ var title: String {
+ return subscription.metadata.name
+ }
+
+ var subtitle: String {
+ return subscription.metadata.description
+ }
+}
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsInteractor.swift
new file mode 100644
index 000000000..48077e2a3
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsInteractor.swift
@@ -0,0 +1,21 @@
+import WalletConnectPush
+import Combine
+
+final class NotificationsInteractor {
+
+ var subscriptionsPublisher: AnyPublisher<[PushSubscription], Never> {
+ return Push.wallet.subscriptionsPublisher
+ }
+
+ func getSubscriptions() -> [PushSubscription] {
+ Push.wallet.getActiveSubscriptions()
+ }
+
+ func removeSubscription(_ subscription: PushSubscription) async {
+ do {
+ try await Push.wallet.delete(topic: subscription.topic)
+ } catch {
+ print(error)
+ }
+ }
+}
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsModule.swift b/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsModule.swift
new file mode 100644
index 000000000..f7b2b620c
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsModule.swift
@@ -0,0 +1,18 @@
+import SwiftUI
+
+final class NotificationsModule {
+
+ @discardableResult
+ static func create(app: Application) -> UIViewController {
+ let router = NotificationsRouter(app: app)
+ let interactor = NotificationsInteractor()
+ let presenter = NotificationsPresenter(interactor: interactor, router: router)
+ let view = NotificationsView().environmentObject(presenter)
+ let viewController = SceneViewController(viewModel: presenter, content: view)
+
+ router.viewController = viewController
+
+ return viewController
+ }
+
+}
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsPresenter.swift
new file mode 100644
index 000000000..2a694bfe7
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsPresenter.swift
@@ -0,0 +1,62 @@
+import UIKit
+import Combine
+
+final class NotificationsPresenter: ObservableObject {
+
+ private let interactor: NotificationsInteractor
+ private let router: NotificationsRouter
+ private var disposeBag = Set()
+
+ @Published var subscriptions: [SubscriptionsViewModel] = []
+
+ init(interactor: NotificationsInteractor, router: NotificationsRouter) {
+ defer { setupInitialState() }
+ self.interactor = interactor
+ self.router = router
+
+ }
+
+ func didPress(_ subscription: SubscriptionsViewModel) {
+ router.presentNotifications(subscription: subscription.subscription)
+ }
+
+ func setupInitialState() {
+ setupSubscriptions()
+ }
+
+ func removeSubscribtion(at indexSet: IndexSet) async {
+ if let index = indexSet.first {
+ await interactor.removeSubscription(subscriptions[index].subscription)
+ }
+ }
+}
+
+// MARK: SceneViewModel
+
+extension NotificationsPresenter: SceneViewModel {
+ var sceneTitle: String? {
+ return "Notifications"
+ }
+
+ var largeTitleDisplayMode: UINavigationItem.LargeTitleDisplayMode {
+ return .always
+ }
+}
+
+// MARK: Privates
+
+private extension NotificationsPresenter {
+
+ func setupSubscriptions() {
+ self.subscriptions = interactor.getSubscriptions()
+ .map { SubscriptionsViewModel(subscription: $0) }
+ interactor.subscriptionsPublisher
+ .receive(on: DispatchQueue.main)
+ .sink { [weak self] pushSubscriptions in
+ self?.subscriptions = pushSubscriptions
+ .map { SubscriptionsViewModel(subscription: $0) }
+ }
+ .store(in: &disposeBag)
+ }
+
+}
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsRouter.swift
new file mode 100644
index 000000000..61d90dcfc
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsRouter.swift
@@ -0,0 +1,17 @@
+import UIKit
+import WalletConnectPush
+
+final class NotificationsRouter {
+
+ weak var viewController: UIViewController!
+
+ private let app: Application
+
+ init(app: Application) {
+ self.app = app
+ }
+
+ func presentNotifications(subscription: WalletConnectPush.PushSubscription) {
+
+ }
+}
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsView.swift b/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsView.swift
new file mode 100644
index 000000000..f6596f652
--- /dev/null
+++ b/Example/WalletApp/PresentationLayer/Wallet/Notifications/NotificationsView.swift
@@ -0,0 +1,107 @@
+import SwiftUI
+
+struct NotificationsView: View {
+
+ @EnvironmentObject var presenter: NotificationsPresenter
+
+
+ var body: some View {
+ ZStack {
+ Color.grey100
+ .edgesIgnoringSafeArea(.all)
+
+ VStack(alignment: .leading, spacing: 16) {
+ ZStack {
+ if presenter.subscriptions.isEmpty {
+ VStack(spacing: 10) {
+ Image(systemName: "bell.badge.fill")
+ .resizable()
+ .frame(width: 32, height: 32)
+ .aspectRatio(contentMode: .fit)
+ .foregroundColor(.grey50)
+
+ Text("Notifications from connected apps will appear here. To enable notifications, visit the app in your browser and look for a \(Image(systemName: "bell.fill")) notifications toggle \(Image(systemName: "switch.2"))")
+ .foregroundColor(.grey50)
+ .font(.system(size: 15, weight: .regular, design: .rounded))
+ .multilineTextAlignment(.center)
+ .lineSpacing(4)
+ }
+ .padding(20)
+ }
+
+ VStack {
+ if !presenter.subscriptions.isEmpty {
+ List {
+ ForEach(presenter.subscriptions, id: \.title) { subscription in
+ subscriptionsView(subscription: subscription)
+ .listRowSeparator(.hidden)
+ .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 16, trailing: 0))
+ }
+ .onDelete { indexSet in
+ Task(priority: .high) {
+ await presenter.removeSubscribtion(at: indexSet)
+ }
+ }
+ }
+ .listStyle(PlainListStyle())
+ }
+ }
+ }
+ }
+ .padding(.vertical, 20)
+ }
+ }
+
+
+
+
+
+ private func subscriptionsView(subscription: SubscriptionsViewModel) -> some View {
+ Button {
+ presenter.didPress(subscription)
+ } label: {
+ VStack {
+ HStack(spacing: 10) {
+ AsyncImage(url: URL(string: subscription.imageUrl)) { phase in
+ if let image = phase.image {
+ image
+ .resizable()
+ .frame(width: 60, height: 60)
+ .background(Color.black)
+ .cornerRadius(30, corners: .allCorners)
+ } else {
+ Color.black
+ .frame(width: 60, height: 60)
+ .cornerRadius(30, corners: .allCorners)
+ }
+ }
+ .padding(.leading, 20)
+
+ VStack(alignment: .leading, spacing: 2) {
+ Text(subscription.title)
+ .foregroundColor(.grey8)
+ .font(.system(size: 20, weight: .semibold, design: .rounded))
+
+ Text(subscription.subtitle)
+ .foregroundColor(.grey50)
+ .font(.system(size: 13, weight: .medium, design: .rounded))
+ }
+
+ Spacer()
+
+ Image("forward-shevron")
+ .foregroundColor(.grey8)
+ .padding(.trailing, 20)
+ }
+ }
+ }
+ }
+}
+
+#if DEBUG
+struct NotificationsView_Previews: PreviewProvider {
+ static var previews: some View {
+ NotificationsView()
+ }
+}
+#endif
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletInteractor.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletInteractor.swift
index 3a4e3601e..e709edeae 100644
--- a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletInteractor.swift
+++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletInteractor.swift
@@ -7,18 +7,10 @@ final class WalletInteractor {
var requestPublisher: AnyPublisher {
return Web3Wallet.instance.authRequestPublisher
}
-
- var sessionProposalPublisher: AnyPublisher {
- return Web3Wallet.instance.sessionProposalPublisher
- }
-
+
var sessionRequestPublisher: AnyPublisher {
return Web3Wallet.instance.sessionRequestPublisher
}
-
- var pushRequestPublisher: AnyPublisher<(id: RPCID, account: Account, metadata: AppMetadata), Never> {
- return Push.wallet.requestPublisher
- }
var sessionsPublisher: AnyPublisher<[Session], Never> {
return Web3Wallet.instance.sessionsPublisher
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletPresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletPresenter.swift
index 1e129ae89..7a98087ad 100644
--- a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletPresenter.swift
+++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletPresenter.swift
@@ -72,19 +72,6 @@ extension WalletPresenter {
self?.router.present(sessionRequest: sessionRequest)
}.store(in: &disposeBag)
- interactor.pushRequestPublisher
- .receive(on: DispatchQueue.main)
- .sink { [weak self] request in
- self?.router.present(pushRequest: request)
- }.store(in: &disposeBag)
-
- interactor.sessionProposalPublisher
- .receive(on: DispatchQueue.main)
- .sink { [weak self] proposal in
- self?.router.present(proposal: proposal)
- }
- .store(in: &disposeBag)
-
interactor.sessionsPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] sessions in
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletRouter.swift
index 8cc1c31ed..2eb2fcfd4 100644
--- a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletRouter.swift
+++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletRouter.swift
@@ -1,7 +1,5 @@
import UIKit
-
import Web3Wallet
-import WalletConnectPush
final class WalletRouter {
weak var viewController: UIViewController!
@@ -16,21 +14,11 @@ final class WalletRouter {
AuthRequestModule.create(app: app, request: request)
.presentFullScreen(from: viewController, transparentBackground: true)
}
-
- func present(proposal: Session.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)
}
-
- func present(pushRequest: PushRequest) {
- PushRequestModule.create(app: app, pushRequest: pushRequest)
- .presentFullScreen(from: viewController, transparentBackground: true)
- }
func presentPaste(onValue: @escaping (String) -> Void, onError: @escaping (Error) -> Void) {
PasteUriModule.create(app: app, onValue: onValue, onError: onError)
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletView.swift b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletView.swift
index a465e86d3..b9749aa9c 100644
--- a/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletView.swift
+++ b/Example/WalletApp/PresentationLayer/Wallet/Wallet/WalletView.swift
@@ -27,8 +27,7 @@ struct WalletView: View {
VStack {
if !presenter.sessions.isEmpty {
List {
- ForEach(presenter.sessions, id: \.peer.name) { session in
- connectionView(session: session)
+ ForEach(presenter.sessions, id: \.topic) { session in connectionView(session: session)
.listRowSeparator(.hidden)
.listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 16, trailing: 0))
}
diff --git a/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeRouter.swift b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeRouter.swift
index 9ebd6c7bf..e7c495e62 100644
--- a/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeRouter.swift
+++ b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomeRouter.swift
@@ -10,8 +10,7 @@ final class WelcomeRouter {
}
func presentWallet() {
- WalletModule.create(app: app)
- .wrapToNavigationController()
- .presentFullScreen(from: viewController)
+ MainModule.create(app: app)
+ .present()
}
}
diff --git a/Makefile b/Makefile
old mode 100644
new mode 100755
index 218b88441..806b4f5bf
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,11 @@ resolve_packages:
fastlane resolve scheme:WalletApp
release_wallet:
- fastlane release_testflight username:$(APPLE_ID) --env WalletApp
+ fastlane release_testflight username:$(APPLE_ID) token:$(TOKEN) --env WalletApp
release_showcase:
- fastlane release_testflight username:$(APPLE_ID) --env Showcase
\ No newline at end of file
+ fastlane release_testflight username:$(APPLE_ID) token:$(TOKEN) --env Showcase
+
+release_all:
+ fastlane release_testflight username:$(APPLE_ID) token:$(TOKEN) --env WalletApp
+ fastlane release_testflight username:$(APPLE_ID) token:$(TOKEN) --env Showcase
diff --git a/Sources/WalletConnectEcho/APNSEnvironment.swift b/Sources/WalletConnectEcho/APNSEnvironment.swift
new file mode 100644
index 000000000..2e8b1343d
--- /dev/null
+++ b/Sources/WalletConnectEcho/APNSEnvironment.swift
@@ -0,0 +1,6 @@
+import Foundation
+
+public enum APNSEnvironment: String {
+ case production = "apns"
+ case sandbox = "apns-sandbox"
+}
diff --git a/Sources/WalletConnectEcho/Echo.swift b/Sources/WalletConnectEcho/Echo.swift
index 6ebc721e2..13f91a4b8 100644
--- a/Sources/WalletConnectEcho/Echo.swift
+++ b/Sources/WalletConnectEcho/Echo.swift
@@ -11,7 +11,8 @@ public class Echo {
return EchoClientFactory.create(
projectId: Networking.projectId,
clientId: config.clientId,
- echoHost: config.echoHost)
+ echoHost: config.echoHost,
+ environment: config.environment)
}()
private static var config: Config?
@@ -22,8 +23,9 @@ public class Echo {
/// - 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,
- echoHost: String = echoHost
+ echoHost: String = echoHost,
+ environment: APNSEnvironment
) {
- Echo.config = Echo.Config(clientId: clientId, echoHost: echoHost)
+ Echo.config = Echo.Config(clientId: clientId, echoHost: echoHost, environment: environment)
}
}
diff --git a/Sources/WalletConnectEcho/EchoClientFactory.swift b/Sources/WalletConnectEcho/EchoClientFactory.swift
index ff7b8cbb6..b8beb2c87 100644
--- a/Sources/WalletConnectEcho/EchoClientFactory.swift
+++ b/Sources/WalletConnectEcho/EchoClientFactory.swift
@@ -2,22 +2,24 @@ import Foundation
import WalletConnectNetworking
public struct EchoClientFactory {
- public static func create(projectId: String, clientId: String, echoHost: String) -> EchoClient {
+ public static func create(projectId: String, clientId: String, echoHost: String, environment: APNSEnvironment) -> EchoClient {
let httpClient = HTTPNetworkClient(host: echoHost)
return EchoClientFactory.create(
projectId: projectId,
clientId: clientId,
- httpClient: httpClient)
+ httpClient: httpClient,
+ environment: environment)
}
static func create(projectId: String,
clientId: String,
- httpClient: HTTPClient) -> EchoClient {
+ httpClient: HTTPClient,
+ environment: APNSEnvironment) -> EchoClient {
- let logger = ConsoleLogger(loggingLevel: .off)
- let registerService = EchoRegisterService(httpClient: httpClient, projectId: projectId, clientId: clientId, logger: logger)
+ let logger = ConsoleLogger(loggingLevel: .debug)
+ let registerService = EchoRegisterService(httpClient: httpClient, projectId: projectId, clientId: clientId, logger: logger, environment: environment)
return EchoClient(
registerService: registerService)
diff --git a/Sources/WalletConnectEcho/EchoConfig.swift b/Sources/WalletConnectEcho/EchoConfig.swift
index d1eab366f..6bc29d0f9 100644
--- a/Sources/WalletConnectEcho/EchoConfig.swift
+++ b/Sources/WalletConnectEcho/EchoConfig.swift
@@ -4,5 +4,6 @@ extension Echo {
struct Config {
let clientId: String
let echoHost: String
+ let environment: APNSEnvironment
}
}
diff --git a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift
index 51fbd7560..9a3bbb6d5 100644
--- a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift
+++ b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift
@@ -6,6 +6,7 @@ actor EchoRegisterService {
private let projectId: String
private let clientId: String
private let logger: ConsoleLogging
+ private let environment: APNSEnvironment
// DID method specific identifier
private var clientIdMutlibase: String {
return clientId.replacingOccurrences(of: "did:key:", with: "")
@@ -18,11 +19,13 @@ actor EchoRegisterService {
init(httpClient: HTTPClient,
projectId: String,
clientId: String,
- logger: ConsoleLogging) {
+ logger: ConsoleLogging,
+ environment: APNSEnvironment) {
self.httpClient = httpClient
self.clientId = clientId
self.projectId = projectId
self.logger = logger
+ self.environment = environment
}
func register(deviceToken: Data) async throws {
@@ -31,7 +34,7 @@ actor EchoRegisterService {
logger.debug("APNS device token: \(token)")
let response = try await httpClient.request(
EchoResponse.self,
- at: EchoAPI.register(clientId: clientIdMutlibase, token: token, projectId: projectId)
+ at: EchoAPI.register(clientId: clientIdMutlibase, token: token, projectId: projectId, environment: environment)
)
guard response.status == .success else {
throw Errors.registrationFailed
@@ -43,7 +46,7 @@ actor EchoRegisterService {
public func register(deviceToken: String) async throws {
let response = try await httpClient.request(
EchoResponse.self,
- at: EchoAPI.register(clientId: clientIdMutlibase, token: deviceToken, projectId: projectId)
+ at: EchoAPI.register(clientId: clientIdMutlibase, token: deviceToken, projectId: projectId, environment: environment)
)
guard response.status == .success else {
throw Errors.registrationFailed
diff --git a/Sources/WalletConnectEcho/Register/EchoService.swift b/Sources/WalletConnectEcho/Register/EchoService.swift
index c792cc098..998c81c6c 100644
--- a/Sources/WalletConnectEcho/Register/EchoService.swift
+++ b/Sources/WalletConnectEcho/Register/EchoService.swift
@@ -2,12 +2,12 @@ import Foundation
import WalletConnectNetworking
enum EchoAPI: HTTPService {
- case register(clientId: String, token: String, projectId: String)
+ case register(clientId: String, token: String, projectId: String, environment: APNSEnvironment)
case unregister(clientId: String, projectId: String)
var path: String {
switch self {
- case .register(_, _, let projectId):
+ case .register(_, _, let projectId, _):
return "/\(projectId)/clients"
case .unregister(let clientId, let projectId):
return "/\(projectId)/clients\(clientId)"
@@ -25,10 +25,10 @@ enum EchoAPI: HTTPService {
var body: Data? {
switch self {
- case .register(let clientId, let token, _):
+ case .register(let clientId, let token, _, let environment):
return try? JSONEncoder().encode([
"client_id": clientId,
- "type": "apns",
+ "type": environment.rawValue,
"token": token
])
case .unregister:
diff --git a/Sources/WalletConnectNetworking/NetworkingClientFactory.swift b/Sources/WalletConnectNetworking/NetworkingClientFactory.swift
index b1d249880..6b5e39a2c 100644
--- a/Sources/WalletConnectNetworking/NetworkingClientFactory.swift
+++ b/Sources/WalletConnectNetworking/NetworkingClientFactory.swift
@@ -3,7 +3,7 @@ import Foundation
public struct NetworkingClientFactory {
public static func create(relayClient: RelayClient) -> NetworkingInteractor {
- let logger = ConsoleLogger(loggingLevel: .off)
+ let logger = ConsoleLogger(loggingLevel: .debug)
let keyValueStorage = UserDefaults.standard
let keychainStorage = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk")
return NetworkingClientFactory.create(relayClient: relayClient, logger: logger, keychainStorage: keychainStorage, keyValueStorage: keyValueStorage)
diff --git a/Sources/WalletConnectPush/APNSEnvironment.swift b/Sources/WalletConnectPush/APNSEnvironment.swift
new file mode 100644
index 000000000..567373443
--- /dev/null
+++ b/Sources/WalletConnectPush/APNSEnvironment.swift
@@ -0,0 +1,3 @@
+import WalletConnectEcho
+
+public typealias APNSEnvironment = WalletConnectEcho.APNSEnvironment
diff --git a/Sources/WalletConnectPush/Client/Common/DeletePushSubscriptionService.swift b/Sources/WalletConnectPush/Client/Common/DeletePushSubscriptionService.swift
index 14c3bba6b..cc4e07a23 100644
--- a/Sources/WalletConnectPush/Client/Common/DeletePushSubscriptionService.swift
+++ b/Sources/WalletConnectPush/Client/Common/DeletePushSubscriptionService.swift
@@ -32,6 +32,7 @@ class DeletePushSubscriptionService {
networkingInteractor.unsubscribe(topic: topic)
pushSubscriptionStore.delete(forKey: topic)
+ logger.debug("Subscription removed")
kms.deleteSymmetricKey(for: topic)
}
diff --git a/Sources/WalletConnectPush/Client/Wallet/PushSubscriptionsObserver.swift b/Sources/WalletConnectPush/Client/Wallet/PushSubscriptionsObserver.swift
new file mode 100644
index 000000000..ae1e026a5
--- /dev/null
+++ b/Sources/WalletConnectPush/Client/Wallet/PushSubscriptionsObserver.swift
@@ -0,0 +1,22 @@
+import Combine
+import Foundation
+
+class PushSubscriptionsObserver {
+ public var subscriptionsPublisher: AnyPublisher<[PushSubscription], Never> {
+ subscriptionsPublisherSubject.eraseToAnyPublisher()
+ }
+ private let subscriptionsPublisherSubject = PassthroughSubject<[PushSubscription], Never>()
+
+ private let store: CodableStore
+
+ init(store: CodableStore) {
+ self.store = store
+ setUpSubscription()
+ }
+
+ func setUpSubscription() {
+ store.onStoreUpdate = { [unowned self] in
+ subscriptionsPublisherSubject.send(store.getAll())
+ }
+ }
+}
diff --git a/Sources/WalletConnectPush/Client/Wallet/WalletPushClient.swift b/Sources/WalletConnectPush/Client/Wallet/WalletPushClient.swift
index 65ef69e89..30624d062 100644
--- a/Sources/WalletConnectPush/Client/Wallet/WalletPushClient.swift
+++ b/Sources/WalletConnectPush/Client/Wallet/WalletPushClient.swift
@@ -9,6 +9,12 @@ public class WalletPushClient {
private var publishers = Set()
+ public var subscriptionsPublisher: AnyPublisher<[PushSubscription], Never> {
+ return pushSubscriptionsObserver.subscriptionsPublisher
+ }
+
+ private let pushSubscriptionsObserver: PushSubscriptionsObserver
+
private let requestPublisherSubject = PassthroughSubject()
public var requestPublisher: AnyPublisher {
@@ -50,7 +56,8 @@ public class WalletPushClient {
pushMessagesProvider: PushMessagesProvider,
deletePushSubscriptionService: DeletePushSubscriptionService,
deletePushSubscriptionSubscriber: DeletePushSubscriptionSubscriber,
- resubscribeService: PushResubscribeService) {
+ resubscribeService: PushResubscribeService,
+ pushSubscriptionsObserver: PushSubscriptionsObserver) {
self.logger = logger
self.pairingRegisterer = pairingRegisterer
self.proposeResponder = proposeResponder
@@ -61,6 +68,7 @@ public class WalletPushClient {
self.deletePushSubscriptionService = deletePushSubscriptionService
self.deletePushSubscriptionSubscriber = deletePushSubscriptionSubscriber
self.resubscribeService = resubscribeService
+ self.pushSubscriptionsObserver = pushSubscriptionsObserver
setupSubscriptions()
}
@@ -115,3 +123,4 @@ extension WalletPushClient {
}
}
#endif
+
diff --git a/Sources/WalletConnectPush/Client/Wallet/WalletPushClientFactory.swift b/Sources/WalletConnectPush/Client/Wallet/WalletPushClientFactory.swift
index 2ed976c16..22358f13f 100644
--- a/Sources/WalletConnectPush/Client/Wallet/WalletPushClientFactory.swift
+++ b/Sources/WalletConnectPush/Client/Wallet/WalletPushClientFactory.swift
@@ -5,7 +5,7 @@ import WalletConnectEcho
public struct WalletPushClientFactory {
public static func create(networkInteractor: NetworkInteracting, pairingRegisterer: PairingRegisterer, echoClient: EchoClient) -> WalletPushClient {
- let logger = ConsoleLogger(loggingLevel: .off)
+ let logger = ConsoleLogger(loggingLevel: .debug)
let keyValueStorage = UserDefaults.standard
let keychainStorage = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk")
@@ -37,6 +37,7 @@ public struct WalletPushClientFactory {
let deletePushSubscriptionSubscriber = DeletePushSubscriptionSubscriber(networkingInteractor: networkInteractor, kms: kms, logger: logger, pushSubscriptionStore: subscriptionStore)
let resubscribeService = PushResubscribeService(networkInteractor: networkInteractor, subscriptionsStorage: subscriptionStore)
let pushMessagesProvider = PushMessagesProvider(history: history)
+ let pushSubscriptionsObserver = PushSubscriptionsObserver(store: subscriptionStore)
return WalletPushClient(
logger: logger,
kms: kms,
@@ -48,7 +49,8 @@ public struct WalletPushClientFactory {
pushMessagesProvider: pushMessagesProvider,
deletePushSubscriptionService: deletePushSubscriptionService,
deletePushSubscriptionSubscriber: deletePushSubscriptionSubscriber,
- resubscribeService: resubscribeService
+ resubscribeService: resubscribeService,
+ pushSubscriptionsObserver: pushSubscriptionsObserver
)
}
}
diff --git a/Sources/WalletConnectPush/Push.swift b/Sources/WalletConnectPush/Push.swift
index 5b159bf58..2fafa4fdc 100644
--- a/Sources/WalletConnectPush/Push.swift
+++ b/Sources/WalletConnectPush/Push.swift
@@ -16,7 +16,7 @@ public class Push {
guard let config = Push.config else {
fatalError("Error - you must call Push.configure(_:) before accessing the shared wallet instance.")
}
- Echo.configure(clientId: config.clientId, echoHost: config.echoHost)
+ Echo.configure(clientId: config.clientId, echoHost: config.echoHost, environment: config.environment)
return WalletPushClientFactory.create(
networkInteractor: Networking.interactor,
pairingRegisterer: Pair.registerer,
@@ -29,9 +29,9 @@ public class Push {
private init() { }
/// Wallet's configuration method
- static public func configure(echoHost: String = "echo.walletconnect.com") {
+ static public func configure(echoHost: String = "echo.walletconnect.com", environment: APNSEnvironment) {
let clientId = try! Networking.interactor.getClientId()
- Push.config = Push.Config(clientId: clientId, echoHost: echoHost)
+ Push.config = Push.Config(clientId: clientId, echoHost: echoHost, environment: environment)
}
}
diff --git a/Sources/WalletConnectPush/PushConfig.swift b/Sources/WalletConnectPush/PushConfig.swift
index 8c7445dcc..d4bd4c1af 100644
--- a/Sources/WalletConnectPush/PushConfig.swift
+++ b/Sources/WalletConnectPush/PushConfig.swift
@@ -1,8 +1,10 @@
import Foundation
+import WalletConnectEcho
extension Push {
struct Config {
let clientId: String
let echoHost: String
+ let environment: APNSEnvironment
}
}
diff --git a/Sources/WalletConnectRelay/PackageConfig.json b/Sources/WalletConnectRelay/PackageConfig.json
index 1663b3678..3227f6058 100644
--- a/Sources/WalletConnectRelay/PackageConfig.json
+++ b/Sources/WalletConnectRelay/PackageConfig.json
@@ -1 +1 @@
-{"version": "1.3.1"}
+{"version": "1.3.2"}
diff --git a/Sources/WalletConnectSign/Engine/Common/DeleteSessionService.swift b/Sources/WalletConnectSign/Engine/Common/DeleteSessionService.swift
index d4a40f52a..a1c617e49 100644
--- a/Sources/WalletConnectSign/Engine/Common/DeleteSessionService.swift
+++ b/Sources/WalletConnectSign/Engine/Common/DeleteSessionService.swift
@@ -24,6 +24,7 @@ class DeleteSessionService {
let request = RPCRequest(method: protocolMethod.method, params: reason)
try await networkingInteractor.request(request, topic: topic, protocolMethod: protocolMethod)
sessionStore.delete(topic: topic)
+ logger.debug("Session disconnected")
kms.deleteSymmetricKey(for: topic)
networkingInteractor.unsubscribe(topic: topic)
}
diff --git a/Sources/WalletConnectSign/Sign/SignClientFactory.swift b/Sources/WalletConnectSign/Sign/SignClientFactory.swift
index ef68dd39e..16ff60a7c 100644
--- a/Sources/WalletConnectSign/Sign/SignClientFactory.swift
+++ b/Sources/WalletConnectSign/Sign/SignClientFactory.swift
@@ -12,7 +12,7 @@ public struct SignClientFactory {
///
/// WalletConnect Client is not a singleton but once you create an instance, you should not deinitialize it. Usually only one instance of a client is required in the application.
public static func create(metadata: AppMetadata, pairingClient: PairingClient, networkingClient: NetworkingInteractor) -> SignClient {
- let logger = ConsoleLogger(loggingLevel: .off)
+ let logger = ConsoleLogger(loggingLevel: .debug)
let keyValueStorage = UserDefaults.standard
let keychainStorage = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk")
return SignClientFactory.create(metadata: metadata, logger: logger, keyValueStorage: keyValueStorage, keychainStorage: keychainStorage, pairingClient: pairingClient, networkingClient: networkingClient)
diff --git a/Sources/WalletConnectUtils/CodableStore.swift b/Sources/WalletConnectUtils/CodableStore.swift
index 184988696..00c34fb2c 100644
--- a/Sources/WalletConnectUtils/CodableStore.swift
+++ b/Sources/WalletConnectUtils/CodableStore.swift
@@ -3,6 +3,7 @@ import Foundation
public final class CodableStore where T: Codable {
private let defaults: KeyValueStorage
private let prefix: String
+ public var onStoreUpdate: (() -> Void)?
public init(defaults: KeyValueStorage, identifier: String) {
self.defaults = defaults
@@ -13,6 +14,7 @@ public final class CodableStore where T: Codable {
// This force-unwrap is safe because T are JSON Encodable
let encoded = try! JSONEncoder().encode(item)
defaults.set(encoded, forKey: getContextPrefixedKey(for: key))
+ onStoreUpdate?()
}
public func get(key: String) throws -> T? {
@@ -33,11 +35,13 @@ public final class CodableStore where T: Codable {
public func delete(forKey key: String) {
defaults.removeObject(forKey: getContextPrefixedKey(for: key))
+ onStoreUpdate?()
}
public func deleteAll() {
dictionaryForIdentifier()
.forEach { defaults.removeObject(forKey: $0.key) }
+ onStoreUpdate?()
}
private func getContextPrefixedKey(for key: String) -> String {
diff --git a/fastlane/Appfile b/fastlane/Appfile
index 9fae697da..91ad3f06d 100644
--- a/fastlane/Appfile
+++ b/fastlane/Appfile
@@ -1,3 +1,2 @@
itc_team_id("123564616")
team_id("W5R8AG9K22")
-git_url("https://github.com/WalletConnect/match-swift")
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index ba33be662..aac915608 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -51,12 +51,21 @@ platform :ios do
end
lane :release_testflight do |options|
+ setup_ci
+ api_key = app_store_connect_api_key(
+ key_id: ENV["APPLE_KEY_ID"],
+ issuer_id: ENV["APPLE_ISSUER_ID"],
+ key_content: ENV["APPLE_KEY_CONTENT"],
+ duration: 1200,
+ in_house: false,
+ )
match(
readonly: false,
type: "appstore",
- app_identifier: ENV["APP_IDENTIFIER"],
+ app_identifier: ENV["MATCH_IDENTIFIERS"],
git_url: "https://github.com/WalletConnect/match-swift.git",
- username: options[:username],
+ git_basic_authorization: options[:token],
+ api_key: api_key
)
number = latest_testflight_build_number(
app_identifier: ENV["APP_IDENTIFIER"],
@@ -66,17 +75,22 @@ platform :ios do
build_number: number + 1,
xcodeproj: "Example/ExampleApp.xcodeproj"
)
- build_app(
+ gym(
+ configuration: "Release",
project: "Example/ExampleApp.xcodeproj",
- scheme: ENV["SCHEME"]
+ scheme: ENV["SCHEME"],
+ export_method: "app-store",
)
upload_to_testflight(
- app_identifier: ENV["APP_IDENTIFIER"],
- username: options[:username],
apple_id: ENV["APPLE_ID"],
+ app_identifier: ENV["APP_IDENTIFIER"],
skip_waiting_for_build_processing: true,
+ distribute_external: true,
+ changelog: "#{ENV["SCHEME"]} app weekly build 🚀",
+ notify_external_testers: false,
)
clean_build_artifacts()
end
+
end
\ No newline at end of file