Skip to content

Commit

Permalink
Merge pull request #1052 from WalletConnect/kms-logger
Browse files Browse the repository at this point in the history
  • Loading branch information
flypaper0 committed Aug 25, 2023
1 parent 631262c commit 3cb3ff0
Show file tree
Hide file tree
Showing 27 changed files with 228 additions and 137 deletions.
2 changes: 1 addition & 1 deletion Example/IntegrationTests/Auth/AuthTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final class AuthTests: XCTestCase {
}

func makeClients(prefix: String, iatProvider: IATProvider) -> (PairingClient, AuthClient) {
let logger = ConsoleLogger(suffix: prefix, loggingLevel: .debug)
let logger = ConsoleLogger(prefix: prefix, loggingLevel: .debug)
let keyValueStorage = RuntimeKeyValueStorage()
let keychain = KeychainStorageMock()
let relayClient = RelayClientFactory.create(
Expand Down
2 changes: 1 addition & 1 deletion Example/IntegrationTests/Chat/ChatTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ final class ChatTests: XCTestCase {

func makeClient(prefix: String, account: Account) -> ChatClient {
let keyserverURL = URL(string: "https://keys.walletconnect.com")!
let logger = ConsoleLogger(suffix: prefix, loggingLevel: .debug)
let logger = ConsoleLogger(prefix: prefix, loggingLevel: .debug)
let keyValueStorage = RuntimeKeyValueStorage()
let keychain = KeychainStorageMock()
let relayClient = RelayClientFactory.create(
Expand Down
2 changes: 1 addition & 1 deletion Example/IntegrationTests/History/HistoryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class HistoryTests: XCTestCase {
keyValueStorage: RuntimeKeyValueStorage(),
keychainStorage: keychain,
socketFactory: DefaultSocketFactory(),
logger: ConsoleLogger(suffix: prefix + " [Relay]", loggingLevel: .debug))
logger: ConsoleLogger(prefix: prefix + " [Relay]", loggingLevel: .debug))
}

private func makeHistoryClient(keychain: KeychainStorageProtocol) -> HistoryNetworkService {
Expand Down
10 changes: 5 additions & 5 deletions Example/IntegrationTests/Pairing/PairingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ final class PairingTests: XCTestCase {
let keychain = KeychainStorageMock()
let keyValueStorage = RuntimeKeyValueStorage()

let relayLogger = ConsoleLogger(suffix: prefix + " [Relay]", loggingLevel: .debug)
let pairingLogger = ConsoleLogger(suffix: prefix + " [Pairing]", loggingLevel: .debug)
let networkingLogger = ConsoleLogger(suffix: prefix + " [Networking]", loggingLevel: .debug)
let relayLogger = ConsoleLogger(prefix: prefix + " [Relay]", loggingLevel: .debug)
let pairingLogger = ConsoleLogger(prefix: prefix + " [Pairing]", loggingLevel: .debug)
let networkingLogger = ConsoleLogger(prefix: prefix + " [Networking]", loggingLevel: .debug)

let relayClient = RelayClientFactory.create(
relayHost: InputConfig.relayHost,
Expand Down Expand Up @@ -59,7 +59,7 @@ final class PairingTests: XCTestCase {
func makeDappClients() {
let prefix = "🤖 Dapp: "
let (pairingClient, networkingInteractor, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let notifyLogger = ConsoleLogger(suffix: prefix + " [Notify]", loggingLevel: .debug)
let notifyLogger = ConsoleLogger(prefix: prefix + " [Notify]", loggingLevel: .debug)
appPairingClient = pairingClient

appAuthClient = AuthClientFactory.create(
Expand All @@ -77,7 +77,7 @@ final class PairingTests: XCTestCase {
func makeWalletClients() {
let prefix = "🐶 Wallet: "
let (pairingClient, networkingInteractor, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let notifyLogger = ConsoleLogger(suffix: prefix + " [Notify]", loggingLevel: .debug)
let notifyLogger = ConsoleLogger(prefix: prefix + " [Notify]", loggingLevel: .debug)
walletPairingClient = pairingClient
let historyClient = HistoryClientFactory.create(
historyUrl: "https://history.walletconnect.com",
Expand Down
64 changes: 32 additions & 32 deletions Example/IntegrationTests/Push/NotifyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ final class NotifyTests: XCTestCase {
let keychain = KeychainStorageMock()
let keyValueStorage = RuntimeKeyValueStorage()

let relayLogger = ConsoleLogger(suffix: prefix + " [Relay]", loggingLevel: .debug)
let pairingLogger = ConsoleLogger(suffix: prefix + " [Pairing]", loggingLevel: .debug)
let networkingLogger = ConsoleLogger(suffix: prefix + " [Networking]", loggingLevel: .debug)
let relayLogger = ConsoleLogger(prefix: prefix + " [Relay]", loggingLevel: .debug)
let pairingLogger = ConsoleLogger(prefix: prefix + " [Pairing]", loggingLevel: .debug)
let networkingLogger = ConsoleLogger(prefix: prefix + " [Networking]", loggingLevel: .debug)

let relayClient = RelayClientFactory.create(
relayHost: InputConfig.relayHost,
Expand Down Expand Up @@ -74,7 +74,7 @@ final class NotifyTests: XCTestCase {
func makeWalletClients() {
let prefix = "🦋 Wallet: "
let (pairingClient, networkingInteractor, syncClient, keychain, keyValueStorage) = makeClientDependencies(prefix: prefix)
let notifyLogger = ConsoleLogger(suffix: prefix + " [Notify]", loggingLevel: .debug)
let notifyLogger = ConsoleLogger(prefix: prefix + " [Notify]", loggingLevel: .debug)
walletPairingClient = pairingClient
let pushClient = PushClientFactory.create(projectId: "",
pushHost: "echo.walletconnect.com",
Expand Down Expand Up @@ -144,34 +144,34 @@ final class NotifyTests: XCTestCase {
wait(for: [expectation], timeout: InputConfig.defaultTimeout)
}

// func testNotifyServerSubscribeAndNotifies() async throws {
// let subscribeExpectation = expectation(description: "creates notify subscription")
// let messageExpectation = expectation(description: "receives a notify message")
// let notifyMessage = NotifyMessage.stub()
//
// let metadata = AppMetadata(name: "GM Dapp", description: "", url: gmDappUrl, icons: [])
// try! await walletNotifyClient.register(account: account, onSign: sign)
// try! await walletNotifyClient.subscribe(metadata: metadata, account: account, onSign: sign)
// var subscription: NotifySubscription!
// walletNotifyClient.subscriptionsPublisher
// .first()
// .sink { subscriptions in
// XCTAssertNotNil(subscriptions.first)
// subscribeExpectation.fulfill()
// subscription = subscriptions.first!
// let notifier = Publisher()
// sleep(1)
// Task(priority: .high) { try await notifier.notify(topic: subscriptions.first!.topic, account: subscriptions.first!.account, message: notifyMessage) }
// }.store(in: &publishers)
// walletNotifyClient.notifyMessagePublisher
// .sink { notifyMessageRecord in
// XCTAssertEqual(notifyMessage, notifyMessageRecord.message)
// messageExpectation.fulfill()
// }.store(in: &publishers)
//
// wait(for: [subscribeExpectation, messageExpectation], timeout: 200)
// try await walletNotifyClient.deleteSubscription(topic: subscription.topic)
// }
func testNotifyServerSubscribeAndNotifies() async throws {
let subscribeExpectation = expectation(description: "creates notify subscription")
let messageExpectation = expectation(description: "receives a notify message")
let notifyMessage = NotifyMessage.stub()

let metadata = AppMetadata(name: "GM Dapp", description: "", url: gmDappUrl, icons: [])
try! await walletNotifyClient.register(account: account, onSign: sign)
try! await walletNotifyClient.subscribe(metadata: metadata, account: account, onSign: sign)
var subscription: NotifySubscription!
walletNotifyClient.subscriptionsPublisher
.first()
.sink { subscriptions in
XCTAssertNotNil(subscriptions.first)
subscribeExpectation.fulfill()
subscription = subscriptions.first!
let notifier = Publisher()
sleep(1)
Task(priority: .high) { try await notifier.notify(topic: subscriptions.first!.topic, account: subscriptions.first!.account, message: notifyMessage) }
}.store(in: &publishers)
walletNotifyClient.notifyMessagePublisher
.sink { notifyMessageRecord in
XCTAssertEqual(notifyMessage, notifyMessageRecord.message)
messageExpectation.fulfill()
}.store(in: &publishers)

wait(for: [subscribeExpectation, messageExpectation], timeout: 200)
try await walletNotifyClient.deleteSubscription(topic: subscription.topic)
}

}

Expand Down
2 changes: 1 addition & 1 deletion Example/IntegrationTests/Sign/SignClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ final class SignClientTests: XCTestCase {
var wallet: ClientDelegate!

static private func makeClientDelegate(name: String) -> ClientDelegate {
let logger = ConsoleLogger(suffix: name, loggingLevel: .debug)
let logger = ConsoleLogger(prefix: name, loggingLevel: .debug)
let keychain = KeychainStorageMock()
let keyValueStorage = RuntimeKeyValueStorage()
let relayClient = RelayClientFactory.create(
Expand Down
2 changes: 1 addition & 1 deletion Example/IntegrationTests/Sync/SyncTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ final class SyncTests: XCTestCase {
let keychain = KeychainStorageMock()
let kms = KeyManagementService(keychain: keychain)
let derivationService = SyncDerivationService(syncStorage: syncSignatureStore, bip44: DefaultBIP44Provider(), kms: kms)
let logger = ConsoleLogger(suffix: suffix, loggingLevel: .debug)
let logger = ConsoleLogger(prefix: suffix, loggingLevel: .debug)
let relayClient = RelayClientFactory.create(
relayHost: InputConfig.relayHost,
projectId: InputConfig.projectId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ final class XPlatformW3WTests: XCTestCase {
let keychain = KeychainStorageMock()
let keyValueStorage = RuntimeKeyValueStorage()

let relayLogger = ConsoleLogger(suffix: "🚄" + " [Relay]", loggingLevel: .debug)
let pairingLogger = ConsoleLogger(suffix: "👩‍❤️‍💋‍👩" + " [Pairing]", loggingLevel: .debug)
let networkingLogger = ConsoleLogger(suffix: "🕸️" + " [Networking]", loggingLevel: .debug)
let authLogger = ConsoleLogger(suffix: "🪪", loggingLevel: .debug)
let relayLogger = ConsoleLogger(prefix: "🚄" + " [Relay]", loggingLevel: .debug)
let pairingLogger = ConsoleLogger(prefix: "👩‍❤️‍💋‍👩" + " [Pairing]", loggingLevel: .debug)
let networkingLogger = ConsoleLogger(prefix: "🕸️" + " [Networking]", loggingLevel: .debug)
let authLogger = ConsoleLogger(prefix: "🪪", loggingLevel: .debug)

let signLogger = ConsoleLogger(suffix: "✍🏿", loggingLevel: .debug)
let signLogger = ConsoleLogger(prefix: "✍🏿", loggingLevel: .debug)

let relayClient = RelayClientFactory.create(
relayHost: InputConfig.relayHost,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ final class RelayClientEndToEndTests: XCTestCase {
)
let socket = WebSocket(url: urlFactory.create(fallback: false))
let webSocketFactory = WebSocketFactoryMock(webSocket: socket)
let logger = ConsoleLogger(suffix: prefix, loggingLevel: .debug)
let logger = ConsoleLogger(prefix: prefix, loggingLevel: .debug)
let dispatcher = Dispatcher(
socketFactory: webSocketFactory,
relayUrlFactory: urlFactory,
Expand Down
4 changes: 4 additions & 0 deletions Example/WalletApp/ApplicationLayer/ConfigurationService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ final class ConfigurationService {

func configure(importAccount: ImportAccount) {
Networking.configure(projectId: InputConfig.projectId, socketFactory: DefaultSocketFactory())
Networking.instance.setLogging(level: .debug)

let metadata = AppMetadata(
name: "Example Wallet",
Expand All @@ -26,6 +27,9 @@ final class ConfigurationService {
onSign: importAccount.onSign
)

if let clientId = try? Networking.interactor.getClientId() {
LoggingService.instance.setUpUser(account: importAccount.account.absoluteString, clientId: clientId)
}
LoggingService.instance.startLogging()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ struct ThirdPartyConfigurator: Configurator {
}

func configureLogging() {
guard let sentryDsn = InputConfig.sentryDsn else { return }
guard let sentryDsn = InputConfig.sentryDsn, !sentryDsn.isEmpty else { return }
SentrySDK.start { options in
options.dsn = "https://\(sentryDsn)"
// Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
Expand Down
7 changes: 7 additions & 0 deletions Example/WalletApp/ApplicationLayer/LoggingService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ final class LoggingService {
private var isLogging = false
private let queue = DispatchQueue(label: "com.walletApp.loggingService")

func setUpUser(account: String, clientId: String) {
let user = User()
user.userId = clientId
user.data = ["account": account]
SentrySDK.setUser(user)
}

func startLogging() {
queue.sync {
guard isLogging == false else { return }
Expand Down
2 changes: 1 addition & 1 deletion Sources/Chat/ChatClientFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public struct ChatClientFactory {
historyClient: HistoryClient
) -> ChatClient {
let kms = KeyManagementService(keychain: keychain)
let serializer = Serializer(kms: kms)
let serializer = Serializer(kms: kms, logger: logger)
let historyService = HistoryService(historyClient: historyClient, seiralizer: serializer)
let messageStore = KeyedDatabase<Message>(storage: storage, identifier: ChatStorageIdentifiers.messages.rawValue)
let receivedInviteStore = KeyedDatabase<ReceivedInvite>(storage: storage, identifier: ChatStorageIdentifiers.receivedInvites.rawValue)
Expand Down
2 changes: 1 addition & 1 deletion Sources/WalletConnectHistory/HistoryClientFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class HistoryClientFactory {
static func create(historyUrl: String, relayUrl: String, keychain: KeychainStorageProtocol) -> HistoryClient {
let clientIdStorage = ClientIdStorage(keychain: keychain)
let kms = KeyManagementService(keychain: keychain)
let serializer = Serializer(kms: kms)
let serializer = Serializer(kms: kms, logger: ConsoleLogger(prefix: "🔐", loggingLevel: .off))
let historyNetworkService = HistoryNetworkService(clientIdStorage: clientIdStorage)
return HistoryClient(
historyUrl: historyUrl,
Expand Down
64 changes: 52 additions & 12 deletions Sources/WalletConnectKMS/Serialiser/Serializer.swift
Original file line number Diff line number Diff line change
@@ -1,23 +1,43 @@
import Foundation
import Combine

public class Serializer: Serializing {

enum Errors: String, Error {
case symmetricKeyForTopicNotFound
enum Errors: Error, CustomStringConvertible {
case symmetricKeyForTopicNotFound(String)
case publicKeyForTopicNotFound

var description: String {
switch self {
case .symmetricKeyForTopicNotFound(let topic):
return "Error: Symmetric key for topic '\(topic)' was not found."
case .publicKeyForTopicNotFound:
return "Error: Public key for topic was not found."
}
}
}

private let kms: KeyManagementServiceProtocol
private let codec: Codec
private let logger: ConsoleLogging
public var logsPublisher: AnyPublisher<Log, Never> {
logger.logsPublisher.eraseToAnyPublisher()
}

init(kms: KeyManagementServiceProtocol, codec: Codec = ChaChaPolyCodec()) {
init(kms: KeyManagementServiceProtocol, codec: Codec = ChaChaPolyCodec(), logger: ConsoleLogging) {
self.kms = kms
self.codec = codec
self.logger = logger
}

public init(kms: KeyManagementServiceProtocol) {
public init(kms: KeyManagementServiceProtocol, logger: ConsoleLogging) {
self.kms = kms
self.codec = ChaChaPolyCodec()
self.logger = logger
}

public func setLogging(level: LoggingLevel) {
logger.setLogging(level: level)
}

/// Encrypts and serializes an object
Expand All @@ -29,7 +49,9 @@ public class Serializer: Serializing {
public func serialize(topic: String, encodable: Encodable, envelopeType: Envelope.EnvelopeType) throws -> String {
let messageJson = try encodable.json()
guard let symmetricKey = kms.getSymmetricKeyRepresentable(for: topic) else {
throw Errors.symmetricKeyForTopicNotFound
let error = Errors.symmetricKeyForTopicNotFound(topic)
logger.error("\(error)")
throw error
}
let sealbox = try codec.encode(plaintext: messageJson, symmetricKey: symmetricKey)
return Envelope(type: envelopeType, sealbox: sealbox).serialised()
Expand All @@ -53,16 +75,29 @@ public class Serializer: Serializing {

private func handleType0Envelope<T: Codable>(_ topic: String, _ envelope: Envelope) throws -> (T, Data) {
if let symmetricKey = kms.getSymmetricKeyRepresentable(for: topic) {
let decoded: (T, Data) = try decode(sealbox: envelope.sealbox, symmetricKey: symmetricKey)
return decoded
do {
let decoded: (T, Data) = try decode(sealbox: envelope.sealbox, symmetricKey: symmetricKey)
logger.debug("Decoded: \(decoded.0)")
return decoded
}
catch {
logger.error("\(error)")
throw error
}
} else {
throw Errors.symmetricKeyForTopicNotFound
let error = Errors.symmetricKeyForTopicNotFound(topic)
logger.error("\(error)")
throw error
}
}

private func handleType1Envelope<T: Codable>(_ topic: String, peerPubKey: Data, sealbox: Data) throws -> (T, String, Data) {
guard let selfPubKey = kms.getPublicKey(for: topic)
else { throw Errors.publicKeyForTopicNotFound }
else {
let error = Errors.publicKeyForTopicNotFound
logger.error("\(error)")
throw error
}

let agreementKeys = try kms.performKeyAgreement(selfPublicKey: selfPubKey, peerPublicKey: peerPubKey.toHexString())
let decodedType: (object: T, data: Data) = try decode(sealbox: sealbox, symmetricKey: agreementKeys.sharedKey.rawRepresentation)
Expand All @@ -72,8 +107,13 @@ public class Serializer: Serializing {
}

private func decode<T: Codable>(sealbox: Data, symmetricKey: Data) throws -> (T, Data) {
let decryptedData = try codec.decode(sealbox: sealbox, symmetricKey: symmetricKey)
let decoded = try JSONDecoder().decode(T.self, from: decryptedData)
return (decoded, decryptedData)
do {
let decryptedData = try codec.decode(sealbox: sealbox, symmetricKey: symmetricKey)
let decodedType = try JSONDecoder().decode(T.self, from: decryptedData)
return (decodedType, decryptedData)
} catch {
logger.error("Failed to decode with error: \(error)")
throw error
}
}
}
3 changes: 3 additions & 0 deletions Sources/WalletConnectKMS/Serialiser/Serializing.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import Foundation
import Combine

public protocol Serializing {
var logsPublisher: AnyPublisher<Log, Never> {get}
func setLogging(level: LoggingLevel)
func serialize(topic: String, encodable: Encodable, envelopeType: Envelope.EnvelopeType) throws -> String
/// - derivedTopic: topic derived from symmetric key as a result of key exchange if peers has sent envelope(type1) prefixed with it's public key
func deserialize<T: Codable>(topic: String, encodedEnvelope: String) throws -> (T, derivedTopic: String?, decryptedPayload: Data)
Expand Down
1 change: 1 addition & 0 deletions Sources/WalletConnectNetworking/NetworkingClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Combine
public protocol NetworkingClient {
var socketConnectionStatusPublisher: AnyPublisher<SocketConnectionStatus, Never> { get }
var logsPublisher: AnyPublisher<Log, Never> {get}
func setLogging(level: LoggingLevel)
func connect() throws
func disconnect(closeCode: URLSessionWebSocketTask.CloseCode) throws
}
Loading

0 comments on commit 3cb3ff0

Please sign in to comment.