Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Chat] Approve event + JWT verification #735

Merged
merged 18 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions Example/ExampleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2812,8 +2812,8 @@
INFOPLIST_KEY_NSCameraUsageDescription = "Allow the app to scan for QR codes";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand Down Expand Up @@ -2846,8 +2846,8 @@
INFOPLIST_KEY_NSCameraUsageDescription = "Allow the app to scan for QR codes";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand Down Expand Up @@ -2958,7 +2958,9 @@
INFOPLIST_KEY_NSCameraUsageDescription = "Camera access for scanning QR code";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UIRequiresFullScreen = NO;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 15.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand Down Expand Up @@ -2995,7 +2997,9 @@
INFOPLIST_KEY_NSCameraUsageDescription = "Camera access for scanning QR code";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UIRequiresFullScreen = NO;
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 15.4;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1420"
LastUpgradeVersion = "1410"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand All @@ -14,10 +14,10 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "WalletConnectEcho"
BuildableName = "WalletConnectEcho"
BlueprintName = "WalletConnectEcho"
ReferencedContainer = "container:">
BlueprintIdentifier = "WalletConnectIdentity"
BuildableName = "WalletConnectIdentity"
BlueprintName = "WalletConnectIdentity"
ReferencedContainer = "container:..">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
Expand Down Expand Up @@ -50,10 +50,10 @@
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "WalletConnectEcho"
BuildableName = "WalletConnectEcho"
BlueprintName = "WalletConnectEcho"
ReferencedContainer = "container:">
BlueprintIdentifier = "WalletConnectIdentity"
BuildableName = "WalletConnectIdentity"
BlueprintName = "WalletConnectIdentity"
ReferencedContainer = "container:..">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
Expand Down
10 changes: 8 additions & 2 deletions Example/IntegrationTests/Chat/ChatTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,17 @@ final class ChatTests: XCTestCase {
}

func makeClient(prefix: String, account: Account) -> ChatClient {
let keyserverURL = URL(string: "https://staging.keys.walletconnect.com")!
let keyserverURL = URL(string: "https://keys.walletconnect.com")!
let logger = ConsoleLogger(suffix: prefix, loggingLevel: .debug)
let keychain = KeychainStorageMock()
let relayClient = RelayClient(relayHost: InputConfig.relayHost, projectId: InputConfig.projectId, keychainStorage: keychain, socketFactory: DefaultSocketFactory(), logger: logger)
return ChatClientFactory.create(account: account, keyserverURL: keyserverURL, relayClient: relayClient, keychain: keychain, logger: logger, keyValueStorage: RuntimeKeyValueStorage())
let keyValueStorage = RuntimeKeyValueStorage()
let networkingInteractor = NetworkingClientFactory.create(
relayClient: relayClient,
logger: logger,
keychainStorage: keychain,
keyValueStorage: keyValueStorage)
return ChatClientFactory.create(account: account, keyserverURL: keyserverURL, relayClient: relayClient, networkingInteractor: networkingInteractor, keychain: keychain, logger: logger, keyValueStorage: keyValueStorage)
}

func testInvite() async throws {
Expand Down
12 changes: 6 additions & 6 deletions Example/IntegrationTests/Chat/RegistryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import WalletConnectNetworking
import WalletConnectKMS
import WalletConnectUtils
@testable import WalletConnectChat
@testable import WalletConnectIdentity

final class RegistryTests: XCTestCase {

Expand All @@ -14,14 +15,13 @@ final class RegistryTests: XCTestCase {
var signer: CacaoMessageSigner!

override func setUp() {
let keyserverURL = URL(string: "https://staging.keys.walletconnect.com")!
let keyserverURL = URL(string: "https://keys.walletconnect.com")!
let httpService = HTTPNetworkClient(host: keyserverURL.host!)
let accountService = AccountService(currentAccount: account)
let identityNetworkService = IdentityNetworkService(accountService: accountService, httpService: httpService)
let identityNetworkService = IdentityNetworkService(httpService: httpService)
let keychain = KeychainStorageMock()
let ksm = KeyManagementService(keychain: keychain)
storage = IdentityStorage(keychain: keychain)
sut = IdentityService(
sut = IdentityService (
keyserverURL: keyserverURL,
kms: ksm,
storage: storage,
Expand All @@ -39,12 +39,12 @@ final class RegistryTests: XCTestCase {
let resolvedAccount = try await sut.resolveIdentity(iss: iss)
XCTAssertEqual(resolvedAccount, account)

let recovered = storage.getIdentityKey(for: account)!.publicKey.hexRepresentation
let recovered = try storage.getIdentityKey(for: account).publicKey.hexRepresentation
XCTAssertEqual(publicKey, recovered)

let inviteKey = try await sut.registerInvite(account: account)

let recoveredKey = storage.getInviteKey(for: account)!
let recoveredKey = try storage.getInviteKey(for: account)
XCTAssertEqual(inviteKey, recoveredKey)

let resolvedKey = try await sut.resolveInvite(account: account)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ struct MessageViewModel: Identifiable {
private let message: Message
private let thread: WalletConnectChat.Thread

var id: Int64 {
var id: UInt64 {
return message.timestamp
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ final class Web3InboxViewController: UIViewController {
super.viewDidLoad()

Web3Inbox.configure(account: importAccount.account, onSign: onSing)
view = Web3Inbox.instance.getWebView()

edgesForExtendedLayout = []
navigationItem.title = "Web3Inbox SDK"
navigationItem.largeTitleDisplayMode = .never
view = Web3Inbox.instance.getWebView()
}
}

Expand Down
12 changes: 4 additions & 8 deletions Example/Showcase/Other/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>7</string>
<key>PROJECT_ID</key>
<string>$(PROJECT_ID)</string>
<key>RELAY_HOST</key>
<string>$(RELAY_HOST)</string>
<key>CFBundleIconName</key>
<string>AppIcon</string>
<key>CFBundleURLTypes</key>
Expand All @@ -30,6 +22,10 @@
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>PROJECT_ID</key>
<string>$(PROJECT_ID)</string>
<key>RELAY_HOST</key>
<string>$(RELAY_HOST)</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
Expand Down
8 changes: 2 additions & 6 deletions Example/WalletApp/Other/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>7</string>
<key>CFBundleIconName</key>
<string>AppIcon</string>
<key>CFBundleURLTypes</key>
Expand All @@ -19,6 +15,8 @@
</array>
</dict>
</array>
<key>CONFIGURATION</key>
<string>$(CONFIGURATION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>NSAppTransportSecurity</key>
Expand All @@ -30,8 +28,6 @@
<string>$(PROJECT_ID)</string>
<key>SIMULATOR_IDENTIFIER</key>
<string>$(SIMULATOR_IDENTIFIER)</string>
<key>CONFIGURATION</key>
<string>$(CONFIGURATION)</string>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
Expand Down
5 changes: 4 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ let package = Package(
path: "Sources/WalletConnectSign"),
.target(
name: "WalletConnectChat",
dependencies: ["WalletConnectNetworking", "WalletConnectSigner"],
dependencies: ["WalletConnectIdentity", "WalletConnectSigner"],
path: "Sources/Chat"),
.target(
name: "Auth",
Expand Down Expand Up @@ -91,6 +91,9 @@ let package = Package(
.target(
name: "WalletConnectJWT",
dependencies: ["WalletConnectKMS"]),
.target(
name: "WalletConnectIdentity",
dependencies: ["WalletConnectNetworking"]),
.target(
name: "WalletConnectUtils",
dependencies: ["JSONRPC"]),
Expand Down
6 changes: 5 additions & 1 deletion Sources/Chat/Chat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ public class Chat {
guard let account = account else {
fatalError("Error - you must call Chat.configure(_:) before accessing the shared instance.")
}
return ChatClientFactory.create(account: account)
return ChatClientFactory.create(
account: account,
relayClient: Relay.instance,
networkingInteractor: Networking.interactor
)
}()

private static var account: Account?
Expand Down
33 changes: 18 additions & 15 deletions Sources/Chat/ChatClient.swift
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import Foundation
import Combine

public enum SigningResult {
case signed(CacaoSignature)
case rejected
}

public typealias SigningCallback = (String) async -> SigningResult

public class ChatClient {
private var publishers = [AnyCancellable]()
private let registryService: RegistryService
private let identityClient: IdentityClient
private let messagingService: MessagingService
private let accountService: AccountService
private let resubscriptionService: ResubscriptionService
Expand Down Expand Up @@ -54,9 +47,17 @@ public class ChatClient {
return chatStorage.newThreadPublisher
}

public var acceptPublisher: AnyPublisher<(String, SentInvite), Never> {
return chatStorage.acceptPublisher
}

public var rejectPublisher: AnyPublisher<SentInvite, Never> {
return chatStorage.rejectPublisher
}

// MARK: - Initialization

init(registryService: RegistryService,
init(identityClient: IdentityClient,
messagingService: MessagingService,
accountService: AccountService,
resubscriptionService: ResubscriptionService,
Expand All @@ -67,7 +68,7 @@ public class ChatClient {
chatStorage: ChatStorage,
socketConnectionStatusPublisher: AnyPublisher<SocketConnectionStatus, Never>
) {
self.registryService = registryService
self.identityClient = identityClient
self.messagingService = messagingService
self.accountService = accountService
self.resubscriptionService = resubscriptionService
Expand All @@ -90,7 +91,7 @@ public class ChatClient {
isPrivate: Bool = false,
onSign: @escaping SigningCallback
) async throws -> String {
let publicKey = try await registryService.register(account: account, onSign: onSign)
let publicKey = try await identityClient.register(account: account, onSign: onSign)

accountService.setAccount(account)

Expand All @@ -107,14 +108,14 @@ public class ChatClient {
/// Must not unregister invite key but must stop listening for invites
/// - Parameter onSign: Callback for signing CAIP-122 message to verify blockchain account ownership
public func unregister(account: Account, onSign: @escaping SigningCallback) async throws {
try await registryService.unregister(account: account, onSign: onSign)
try await identityClient.unregister(account: account, onSign: onSign)
}

/// Queries the keyserver with a blockchain account
/// - Parameter account: CAIP10 blockachain account
/// - Returns: Returns the invite key
public func resolve(account: Account) async throws -> String {
try await registryService.resolve(account: account)
try await identityClient.resolveInvite(account: account)
}

/// Sends a chat invite
Expand All @@ -130,15 +131,17 @@ public class ChatClient {
/// Stops listening for invites
/// - Parameter account: CAIP10 blockachain account
public func goPrivate(account: Account) async throws {
try await registryService.goPrivate(account: account)
let inviteKey = try await identityClient.goPrivate(account: account)
resubscriptionService.unsubscribeFromInvites(inviteKey: inviteKey)
}

/// Registers an invite key if not yet registered on this client from keyserver
/// Starts listening for invites
/// - Parameter account: CAIP10 blockachain account
/// - Returns: The public invite key
public func goPublic(account: Account) async throws {
try await registryService.goPublic(account: account)
let inviteKey = try await identityClient.goPublic(account: account)
try await resubscriptionService.subscribeForInvites(inviteKey: inviteKey)
}

/// Accepts a chat invite by id from account specified as inviteeAccount in Invite
Expand Down
Loading