diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 12c15b83b..c9ffb9c62 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -36,7 +36,6 @@ 8487A9482A83AD680003D5AF /* LoggingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8487A9472A83AD680003D5AF /* LoggingService.swift */; }; 84943C7B2A9BA206007EBAC2 /* Mixpanel in Frameworks */ = {isa = PBXBuildFile; productRef = 84943C7A2A9BA206007EBAC2 /* Mixpanel */; }; 84943C7D2A9BA328007EBAC2 /* Mixpanel in Frameworks */ = {isa = PBXBuildFile; productRef = 84943C7C2A9BA328007EBAC2 /* Mixpanel */; }; - 84943C7F2A9BA48C007EBAC2 /* ProfilingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84943C7E2A9BA48C007EBAC2 /* ProfilingService.swift */; }; 849D7A93292E2169006A2BD4 /* NotifyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849D7A92292E2169006A2BD4 /* NotifyTests.swift */; }; 84A6E3C32A386BBC008A0571 /* Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A6E3C22A386BBC008A0571 /* Publisher.swift */; }; 84AA01DB28CF0CD7005D48D8 /* XCTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84AA01DA28CF0CD7005D48D8 /* XCTest.swift */; }; @@ -54,6 +53,8 @@ 84E6B84E29787A8000428BAF /* PNDecryptionService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 84E6B84729787A8000428BAF /* PNDecryptionService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 84FE684628ACDB4700C893FF /* RequestParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FE684528ACDB4700C893FF /* RequestParams.swift */; }; A507BE1A29E8032E0038EF70 /* EIP55Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A507BE1929E8032E0038EF70 /* EIP55Tests.swift */; }; + A50B6A362B06683800162B01 /* InputConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE25D293F56D6004840D1 /* InputConfig.swift */; }; + A50B6A382B06697B00162B01 /* ProfilingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50B6A372B06697B00162B01 /* ProfilingService.swift */; }; A50C036528AAD32200FE72D3 /* ClientDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50C036428AAD32200FE72D3 /* ClientDelegate.swift */; }; A50D53C12ABA055700A4FD8B /* NotifyPreferencesModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50D53BC2ABA055700A4FD8B /* NotifyPreferencesModule.swift */; }; A50D53C22ABA055700A4FD8B /* NotifyPreferencesPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50D53BD2ABA055700A4FD8B /* NotifyPreferencesPresenter.swift */; }; @@ -160,6 +161,7 @@ A5A0843F29D2F625000B9B17 /* DefaultCryptoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A0843B29D2F60A000B9B17 /* DefaultCryptoProvider.swift */; }; A5A0844029D2F626000B9B17 /* DefaultCryptoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A0843B29D2F60A000B9B17 /* DefaultCryptoProvider.swift */; }; A5A4FC772840C12C00BBEC1E /* RegressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A4FC762840C12C00BBEC1E /* RegressionTests.swift */; }; + A5A650CA2B062A1400F9AD4B /* Mixpanel in Frameworks */ = {isa = PBXBuildFile; productRef = A5A650C92B062A1400F9AD4B /* Mixpanel */; }; A5A8E47A293A1C9B00FEB97D /* DefaultSocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */; }; A5A8E47D293A1CFE00FEB97D /* DefaultSocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */; }; A5A8E47E293A1CFE00FEB97D /* DefaultSignerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */; }; @@ -389,7 +391,7 @@ /* Begin PBXCopyFilesBuildPhase section */ 84E6B85229787A8000428BAF /* Embed Foundation Extensions */ = { isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; + buildActionMask = 12; dstPath = ""; dstSubfolderSpec = 13; files = ( @@ -427,7 +429,6 @@ 847F08002A25DBFF00B2A5A4 /* XPlatformW3WTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XPlatformW3WTests.swift; sourceTree = ""; }; 8487A92E2A7BD2F30003D5AF /* XPlatformProtocolTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = XPlatformProtocolTests.xctestplan; path = ../XPlatformProtocolTests.xctestplan; sourceTree = ""; }; 8487A9472A83AD680003D5AF /* LoggingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingService.swift; sourceTree = ""; }; - 84943C7E2A9BA48C007EBAC2 /* ProfilingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilingService.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 = ""; }; 849D7A92292E2169006A2BD4 /* NotifyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotifyTests.swift; sourceTree = ""; }; @@ -454,6 +455,7 @@ 84F568C32795832A00D0A289 /* EthereumTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumTransaction.swift; sourceTree = ""; }; 84FE684528ACDB4700C893FF /* RequestParams.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestParams.swift; sourceTree = ""; }; A507BE1929E8032E0038EF70 /* EIP55Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EIP55Tests.swift; sourceTree = ""; }; + A50B6A372B06697B00162B01 /* ProfilingService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProfilingService.swift; sourceTree = ""; }; A50C036428AAD32200FE72D3 /* ClientDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClientDelegate.swift; sourceTree = ""; }; A50D53BC2ABA055700A4FD8B /* NotifyPreferencesModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotifyPreferencesModule.swift; sourceTree = ""; }; A50D53BD2ABA055700A4FD8B /* NotifyPreferencesPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotifyPreferencesPresenter.swift; sourceTree = ""; }; @@ -731,6 +733,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + A5A650CA2B062A1400F9AD4B /* Mixpanel in Frameworks */, A5B6C0F72A6EAB3200927332 /* WalletConnectNotify in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1408,6 +1411,7 @@ A51606F72A2F47BD00CACB92 /* DefaultBIP44Provider.swift */, A5417BBD299BFC3E00B469F3 /* ImportAccount.swift */, A5C20228287EB34C007E3188 /* AccountStorage.swift */, + C56EE25D293F56D6004840D1 /* InputConfig.swift */, ); path = Shared; sourceTree = ""; @@ -1658,7 +1662,6 @@ isa = PBXGroup; children = ( C579FEB82AFCDF83008855EB /* Views */, - C56EE25D293F56D6004840D1 /* InputConfig.swift */, 84B8154D2991099000FAD54E /* BuildConfiguration.swift */, C56EE267293F56D6004840D1 /* Style */, C56EE2A1293F6B9E004840D1 /* Helpers */, @@ -1721,10 +1724,10 @@ C56EE280293F5757004840D1 /* Application.swift */, C56EE27F293F5757004840D1 /* AppDelegate.swift */, C56EE281293F5757004840D1 /* SceneDelegate.swift */, + A50B6A372B06697B00162B01 /* ProfilingService.swift */, 84DB38F22983CDAE00BFEE37 /* PushRegisterer.swift */, A51811972A52E21A00A52B15 /* ConfigurationService.swift */, 8487A9472A83AD680003D5AF /* LoggingService.swift */, - 84943C7E2A9BA48C007EBAC2 /* ProfilingService.swift */, ); path = ApplicationLayer; sourceTree = ""; @@ -2031,6 +2034,7 @@ name = PNDecryptionService; packageProductDependencies = ( A5B6C0F62A6EAB3200927332 /* WalletConnectNotify */, + A5A650C92B062A1400F9AD4B /* Mixpanel */, ); productName = PNDecryptionService; productReference = 84E6B84729787A8000428BAF /* PNDecryptionService.appex */; @@ -2364,6 +2368,7 @@ buildActionMask = 2147483647; files = ( 84E6B84A29787A8000428BAF /* NotificationService.swift in Sources */, + A50B6A362B06683800162B01 /* InputConfig.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2597,13 +2602,13 @@ A5D610CA2AB3249100C20083 /* ListingViewModel.swift in Sources */, 84DB38F32983CDAE00BFEE37 /* PushRegisterer.swift in Sources */, A5D610CE2AB3594100C20083 /* ListingsAPI.swift in Sources */, - 84943C7F2A9BA48C007EBAC2 /* ProfilingService.swift in Sources */, C5B2F6FB297055B0000DBA0E /* ETHSigner.swift in Sources */, C56EE274293F56D7004840D1 /* SceneViewController.swift in Sources */, A5D610D42AB35BED00C20083 /* FailableDecodable.swift in Sources */, A56AC8F22AD88A5A001C8FAA /* Sequence.swift in Sources */, 847BD1E5298A806800076C90 /* NotificationsPresenter.swift in Sources */, A50D53C12ABA055700A4FD8B /* NotifyPreferencesModule.swift in Sources */, + A50B6A382B06697B00162B01 /* ProfilingService.swift in Sources */, A5B4F7C52ABB20AE0099AF7C /* SubscriptionRouter.swift in Sources */, C55D3496295DFA750004314A /* WelcomeInteractor.swift in Sources */, C5B2F6FC297055B0000DBA0E /* SOLSigner.swift in Sources */, @@ -3500,6 +3505,11 @@ package = A5AE354528A1A2AC0059AE8A /* XCRemoteSwiftPackageReference "Web3" */; productName = Web3; }; + A5A650C92B062A1400F9AD4B /* Mixpanel */ = { + isa = XCSwiftPackageProductDependency; + package = 84943C792A9BA206007EBAC2 /* XCRemoteSwiftPackageReference "mixpanel-swift" */; + productName = Mixpanel; + }; A5B6C0F02A6EAB0800927332 /* WalletConnectNotify */ = { isa = XCSwiftPackageProductDependency; productName = WalletConnectNotify; diff --git a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/PushDecryptionService.xcscheme b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/PushDecryptionService.xcscheme index 66122a584..07e071581 100644 --- a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/PushDecryptionService.xcscheme +++ b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/PushDecryptionService.xcscheme @@ -2,7 +2,7 @@ + version = "1.3"> @@ -58,18 +58,25 @@ + allowLocationSimulation = "YES"> + + + + - + + + + + diff --git a/Example/PNDecryptionService/Info.plist b/Example/PNDecryptionService/Info.plist index cb9e830fd..82ce6e8c5 100644 --- a/Example/PNDecryptionService/Info.plist +++ b/Example/PNDecryptionService/Info.plist @@ -1,20 +1,22 @@ - - NSExtension - - NSExtensionAttributes - - IntentsSupported - - INSendMessageIntent - - - NSExtensionPointIdentifier - com.apple.usernotifications.service - NSExtensionPrincipalClass - $(PRODUCT_MODULE_NAME).NotificationService - - + + NSExtension + + NSExtensionAttributes + + IntentsSupported + + INSendMessageIntent + + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).NotificationService + + MIXPANEL_TOKEN + $(MIXPANEL_TOKEN) + diff --git a/Example/PNDecryptionService/NotificationService.swift b/Example/PNDecryptionService/NotificationService.swift index cd2830ef2..b9ffb65d8 100644 --- a/Example/PNDecryptionService/NotificationService.swift +++ b/Example/PNDecryptionService/NotificationService.swift @@ -1,6 +1,7 @@ import UserNotifications import WalletConnectNotify import Intents +import Mixpanel class NotificationService: UNNotificationServiceExtension { @@ -11,13 +12,20 @@ class NotificationService: UNNotificationServiceExtension { self.contentHandler = contentHandler self.bestAttemptContent = request.content + log("didReceive(_:) fired") + if let content = bestAttemptContent, let topic = content.userInfo["topic"] as? String, let ciphertext = content.userInfo["blob"] as? String { + log("topic and blob found") + do { let service = NotifyDecryptionService(groupIdentifier: "group.com.walletconnect.sdk") - let pushMessage = try service.decryptMessage(topic: topic, ciphertext: ciphertext) + let (pushMessage, account) = try service.decryptMessage(topic: topic, ciphertext: ciphertext) + + log("message decrypted", account: account, topic: topic, message: pushMessage) + let updatedContent = try handle(content: content, pushMessage: pushMessage, topic: topic) let mutableContent = updatedContent.mutableCopy() as! UNMutableNotificationContent @@ -25,9 +33,15 @@ class NotificationService: UNNotificationServiceExtension { mutableContent.subtitle = pushMessage.url mutableContent.body = pushMessage.body + log("message handled", account: account, topic: topic, message: pushMessage) + contentHandler(mutableContent) + + log("content handled", account: account, topic: topic, message: pushMessage) } catch { + log("error: \(error.localizedDescription)") + let mutableContent = content.mutableCopy() as! UNMutableNotificationContent mutableContent.title = "Error" mutableContent.body = error.localizedDescription @@ -113,4 +127,36 @@ private extension NotificationService { return fileURL } + + func log(_ event: String, account: Account? = nil, topic: String? = nil, message: NotifyMessage? = nil) { + let keychain = GroupKeychainStorage(serviceIdentifier: "group.com.walletconnect.sdk") + + guard let clientId: String = try? keychain.read(key: "clientId") else { + return + } + + guard let token = InputConfig.mixpanelToken, !token.isEmpty else { return } + + Mixpanel.initialize(token: token, trackAutomaticEvents: true) + + if let account { + let mixpanel = Mixpanel.mainInstance() + mixpanel.alias = account.absoluteString + mixpanel.identify(distinctId: clientId) + mixpanel.people.set(properties: ["$name": account.absoluteString, "account": account.absoluteString]) + } + + Mixpanel.mainInstance().track( + event: "💬 APNS: " + event, + properties: [ + "title": message?.title, + "body": message?.body, + "icon": message?.icon, + "url": message?.url, + "type": message?.type, + "topic": topic, + "source": "NotificationService" + ] + ) + } } diff --git a/Example/WalletApp/Common/InputConfig.swift b/Example/Shared/InputConfig.swift similarity index 100% rename from Example/WalletApp/Common/InputConfig.swift rename to Example/Shared/InputConfig.swift diff --git a/Example/WalletApp/ApplicationLayer/ConfigurationService.swift b/Example/WalletApp/ApplicationLayer/ConfigurationService.swift index 4e5f57c3e..01fe59d9c 100644 --- a/Example/WalletApp/ApplicationLayer/ConfigurationService.swift +++ b/Example/WalletApp/ApplicationLayer/ConfigurationService.swift @@ -30,6 +30,8 @@ final class ConfigurationService { if let clientId = try? Networking.interactor.getClientId() { LoggingService.instance.setUpUser(account: importAccount.account.absoluteString, clientId: clientId) ProfilingService.instance.setUpProfiling(account: importAccount.account.absoluteString, clientId: clientId) + let groupKeychain = GroupKeychainStorage(serviceIdentifier: "group.com.walletconnect.sdk") + try! groupKeychain.add(clientId, forKey: "clientId") } LoggingService.instance.startLogging() diff --git a/Sources/WalletConnectNotify/Client/Wallet/NotifyDecryptionService.swift b/Sources/WalletConnectNotify/Client/Wallet/NotifyDecryptionService.swift index 7931911ed..296e515e9 100644 --- a/Sources/WalletConnectNotify/Client/Wallet/NotifyDecryptionService.swift +++ b/Sources/WalletConnectNotify/Client/Wallet/NotifyDecryptionService.swift @@ -16,11 +16,11 @@ public class NotifyDecryptionService { self.serializer = Serializer(kms: kms, logger: ConsoleLogger(prefix: "🔐", loggingLevel: .off)) } - public func decryptMessage(topic: String, ciphertext: String) throws -> NotifyMessage { + public func decryptMessage(topic: String, ciphertext: String) throws -> (NotifyMessage, Account) { let (rpcRequest, _, _): (RPCRequest, String?, Data) = try serializer.deserialize(topic: topic, encodedEnvelope: ciphertext) guard let params = rpcRequest.params else { throw Errors.malformedNotifyMessage } let wrapper = try params.get(NotifyMessagePayload.Wrapper.self) let (messagePayload, _) = try NotifyMessagePayload.decodeAndVerify(from: wrapper) - return messagePayload.message + return (messagePayload.message, messagePayload.account) } }