Skip to content

Commit

Permalink
Merge pull request #1234 from WalletConnect/feature/apns-mixpanel
Browse files Browse the repository at this point in the history
[Sample] APNS Mixpanel logs
  • Loading branch information
flypaper0 authored Nov 20, 2023
2 parents 162b841 + 823adea commit 3628405
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 32 deletions.
22 changes: 16 additions & 6 deletions Example/ExampleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand All @@ -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 */; };
Expand Down Expand Up @@ -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 */; };
Expand Down Expand Up @@ -389,7 +391,7 @@
/* Begin PBXCopyFilesBuildPhase section */
84E6B85229787A8000428BAF /* Embed Foundation Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
buildActionMask = 12;
dstPath = "";
dstSubfolderSpec = 13;
files = (
Expand Down Expand Up @@ -427,7 +429,6 @@
847F08002A25DBFF00B2A5A4 /* XPlatformW3WTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XPlatformW3WTests.swift; sourceTree = "<group>"; };
8487A92E2A7BD2F30003D5AF /* XPlatformProtocolTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; name = XPlatformProtocolTests.xctestplan; path = ../XPlatformProtocolTests.xctestplan; sourceTree = "<group>"; };
8487A9472A83AD680003D5AF /* LoggingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingService.swift; sourceTree = "<group>"; };
84943C7E2A9BA48C007EBAC2 /* ProfilingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilingService.swift; sourceTree = "<group>"; };
849A4F18298281E300E61ACE /* WalletAppRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WalletAppRelease.entitlements; sourceTree = "<group>"; };
849A4F19298281F100E61ACE /* PNDecryptionServiceRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PNDecryptionServiceRelease.entitlements; sourceTree = "<group>"; };
849D7A92292E2169006A2BD4 /* NotifyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotifyTests.swift; sourceTree = "<group>"; };
Expand All @@ -454,6 +455,7 @@
84F568C32795832A00D0A289 /* EthereumTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumTransaction.swift; sourceTree = "<group>"; };
84FE684528ACDB4700C893FF /* RequestParams.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestParams.swift; sourceTree = "<group>"; };
A507BE1929E8032E0038EF70 /* EIP55Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EIP55Tests.swift; sourceTree = "<group>"; };
A50B6A372B06697B00162B01 /* ProfilingService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProfilingService.swift; sourceTree = "<group>"; };
A50C036428AAD32200FE72D3 /* ClientDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClientDelegate.swift; sourceTree = "<group>"; };
A50D53BC2ABA055700A4FD8B /* NotifyPreferencesModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotifyPreferencesModule.swift; sourceTree = "<group>"; };
A50D53BD2ABA055700A4FD8B /* NotifyPreferencesPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotifyPreferencesPresenter.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -731,6 +733,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A5A650CA2B062A1400F9AD4B /* Mixpanel in Frameworks */,
A5B6C0F72A6EAB3200927332 /* WalletConnectNotify in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -1408,6 +1411,7 @@
A51606F72A2F47BD00CACB92 /* DefaultBIP44Provider.swift */,
A5417BBD299BFC3E00B469F3 /* ImportAccount.swift */,
A5C20228287EB34C007E3188 /* AccountStorage.swift */,
C56EE25D293F56D6004840D1 /* InputConfig.swift */,
);
path = Shared;
sourceTree = "<group>";
Expand Down Expand Up @@ -1658,7 +1662,6 @@
isa = PBXGroup;
children = (
C579FEB82AFCDF83008855EB /* Views */,
C56EE25D293F56D6004840D1 /* InputConfig.swift */,
84B8154D2991099000FAD54E /* BuildConfiguration.swift */,
C56EE267293F56D6004840D1 /* Style */,
C56EE2A1293F6B9E004840D1 /* Helpers */,
Expand Down Expand Up @@ -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 = "<group>";
Expand Down Expand Up @@ -2031,6 +2034,7 @@
name = PNDecryptionService;
packageProductDependencies = (
A5B6C0F62A6EAB3200927332 /* WalletConnectNotify */,
A5A650C92B062A1400F9AD4B /* Mixpanel */,
);
productName = PNDecryptionService;
productReference = 84E6B84729787A8000428BAF /* PNDecryptionService.appex */;
Expand Down Expand Up @@ -2364,6 +2368,7 @@
buildActionMask = 2147483647;
files = (
84E6B84A29787A8000428BAF /* NotificationService.swift in Sources */,
A50B6A362B06683800162B01 /* InputConfig.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -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 */,
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Scheme
LastUpgradeVersion = "1410"
wasCreatedForAppExtension = "YES"
version = "2.0">
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
Expand Down Expand Up @@ -58,26 +58,33 @@
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
askForAppToLaunch = "Yes"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "2">
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C56EE21A293F55ED004840D1"
BuildableName = "WalletApp.app"
BlueprintName = "WalletApp"
ReferencedContainer = "container:ExampleApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "764E1D3B26F8D3FC00A1FB15"
BuildableName = "WalletConnect Wallet.app"
BlueprintName = "Wallet"
ReferencedContainer = "container:ExampleApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</MacroExpansion>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand All @@ -97,6 +104,15 @@
ReferencedContainer = "container:ExampleApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "764E1D3B26F8D3FC00A1FB15"
BuildableName = "WalletConnect Wallet.app"
BlueprintName = "Wallet"
ReferencedContainer = "container:ExampleApp.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
Expand Down
34 changes: 18 additions & 16 deletions Example/PNDecryptionService/Info.plist
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>IntentsSupported</key>
<array>
<string>INSendMessageIntent</string>
</array>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.usernotifications.service</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
</dict>
</dict>
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>IntentsSupported</key>
<array>
<string>INSendMessageIntent</string>
</array>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.usernotifications.service</string>
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).NotificationService</string>
</dict>
<key>MIXPANEL_TOKEN</key>
<string>$(MIXPANEL_TOKEN)</string>
</dict>
</plist>
48 changes: 47 additions & 1 deletion Example/PNDecryptionService/NotificationService.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import UserNotifications
import WalletConnectNotify
import Intents
import Mixpanel

class NotificationService: UNNotificationServiceExtension {

Expand All @@ -11,23 +12,36 @@ 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
mutableContent.title = pushMessage.title
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
Expand Down Expand Up @@ -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"
]
)
}
}
File renamed without changes.
2 changes: 2 additions & 0 deletions Example/WalletApp/ApplicationLayer/ConfigurationService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

0 comments on commit 3628405

Please sign in to comment.