diff --git a/Example/IntegrationTests/Auth/AuthTests.swift b/Example/IntegrationTests/Auth/AuthTests.swift index 8d9d3edf7..90f110912 100644 --- a/Example/IntegrationTests/Auth/AuthTests.swift +++ b/Example/IntegrationTests/Auth/AuthTests.swift @@ -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( diff --git a/Example/IntegrationTests/Chat/ChatTests.swift b/Example/IntegrationTests/Chat/ChatTests.swift index fb71cbd2b..54d2381c8 100644 --- a/Example/IntegrationTests/Chat/ChatTests.swift +++ b/Example/IntegrationTests/Chat/ChatTests.swift @@ -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( diff --git a/Example/IntegrationTests/History/HistoryTests.swift b/Example/IntegrationTests/History/HistoryTests.swift index 8667a9224..40d52f5c0 100644 --- a/Example/IntegrationTests/History/HistoryTests.swift +++ b/Example/IntegrationTests/History/HistoryTests.swift @@ -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 { diff --git a/Example/IntegrationTests/Pairing/PairingTests.swift b/Example/IntegrationTests/Pairing/PairingTests.swift index e1c9b344d..6d8005a6c 100644 --- a/Example/IntegrationTests/Pairing/PairingTests.swift +++ b/Example/IntegrationTests/Pairing/PairingTests.swift @@ -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, @@ -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( @@ -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", diff --git a/Example/IntegrationTests/Push/NotifyTests.swift b/Example/IntegrationTests/Push/NotifyTests.swift index 60d672cf8..bce3b8bcd 100644 --- a/Example/IntegrationTests/Push/NotifyTests.swift +++ b/Example/IntegrationTests/Push/NotifyTests.swift @@ -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, @@ -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", @@ -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) + } } diff --git a/Example/IntegrationTests/Sign/SignClientTests.swift b/Example/IntegrationTests/Sign/SignClientTests.swift index 96383d0fc..d28ae7c11 100644 --- a/Example/IntegrationTests/Sign/SignClientTests.swift +++ b/Example/IntegrationTests/Sign/SignClientTests.swift @@ -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( diff --git a/Example/IntegrationTests/Sync/SyncTests.swift b/Example/IntegrationTests/Sync/SyncTests.swift index 62103b757..adcfdc532 100644 --- a/Example/IntegrationTests/Sync/SyncTests.swift +++ b/Example/IntegrationTests/Sync/SyncTests.swift @@ -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, diff --git a/Example/IntegrationTests/XPlatform/Web3Wallet/XPlatformW3WTests.swift b/Example/IntegrationTests/XPlatform/Web3Wallet/XPlatformW3WTests.swift index 200eae329..e08391021 100644 --- a/Example/IntegrationTests/XPlatform/Web3Wallet/XPlatformW3WTests.swift +++ b/Example/IntegrationTests/XPlatform/Web3Wallet/XPlatformW3WTests.swift @@ -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, diff --git a/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift b/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift index 639a5d85d..9dc595c95 100644 --- a/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift +++ b/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift @@ -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, diff --git a/Example/WalletApp/ApplicationLayer/ConfigurationService.swift b/Example/WalletApp/ApplicationLayer/ConfigurationService.swift index e58e8321f..58054aa20 100644 --- a/Example/WalletApp/ApplicationLayer/ConfigurationService.swift +++ b/Example/WalletApp/ApplicationLayer/ConfigurationService.swift @@ -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", @@ -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() } } diff --git a/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift index aa0c8f745..cea617574 100644 --- a/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift +++ b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift @@ -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. diff --git a/Example/WalletApp/ApplicationLayer/LoggingService.swift b/Example/WalletApp/ApplicationLayer/LoggingService.swift index d44badb82..30c0b484b 100644 --- a/Example/WalletApp/ApplicationLayer/LoggingService.swift +++ b/Example/WalletApp/ApplicationLayer/LoggingService.swift @@ -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 } diff --git a/Sources/Chat/ChatClientFactory.swift b/Sources/Chat/ChatClientFactory.swift index 558b3f7b2..d8f336381 100644 --- a/Sources/Chat/ChatClientFactory.swift +++ b/Sources/Chat/ChatClientFactory.swift @@ -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(storage: storage, identifier: ChatStorageIdentifiers.messages.rawValue) let receivedInviteStore = KeyedDatabase(storage: storage, identifier: ChatStorageIdentifiers.receivedInvites.rawValue) diff --git a/Sources/WalletConnectHistory/HistoryClientFactory.swift b/Sources/WalletConnectHistory/HistoryClientFactory.swift index c328ff4eb..5168430a3 100644 --- a/Sources/WalletConnectHistory/HistoryClientFactory.swift +++ b/Sources/WalletConnectHistory/HistoryClientFactory.swift @@ -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, diff --git a/Sources/WalletConnectKMS/Serialiser/Serializer.swift b/Sources/WalletConnectKMS/Serialiser/Serializer.swift index 16e199c0e..7a3dcf739 100644 --- a/Sources/WalletConnectKMS/Serialiser/Serializer.swift +++ b/Sources/WalletConnectKMS/Serialiser/Serializer.swift @@ -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 { + 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 @@ -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() @@ -53,16 +75,29 @@ public class Serializer: Serializing { private func handleType0Envelope(_ 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(_ 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) @@ -72,8 +107,13 @@ public class Serializer: Serializing { } private func decode(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 + } } } diff --git a/Sources/WalletConnectKMS/Serialiser/Serializing.swift b/Sources/WalletConnectKMS/Serialiser/Serializing.swift index 5982ce660..c9fc25cd2 100644 --- a/Sources/WalletConnectKMS/Serialiser/Serializing.swift +++ b/Sources/WalletConnectKMS/Serialiser/Serializing.swift @@ -1,6 +1,9 @@ import Foundation +import Combine public protocol Serializing { + var logsPublisher: AnyPublisher {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(topic: String, encodedEnvelope: String) throws -> (T, derivedTopic: String?, decryptedPayload: Data) diff --git a/Sources/WalletConnectNetworking/NetworkingClient.swift b/Sources/WalletConnectNetworking/NetworkingClient.swift index 6c38700e4..e7c7fcd76 100644 --- a/Sources/WalletConnectNetworking/NetworkingClient.swift +++ b/Sources/WalletConnectNetworking/NetworkingClient.swift @@ -4,6 +4,7 @@ import Combine public protocol NetworkingClient { var socketConnectionStatusPublisher: AnyPublisher { get } var logsPublisher: AnyPublisher {get} + func setLogging(level: LoggingLevel) func connect() throws func disconnect(closeCode: URLSessionWebSocketTask.CloseCode) throws } diff --git a/Sources/WalletConnectNetworking/NetworkingClientFactory.swift b/Sources/WalletConnectNetworking/NetworkingClientFactory.swift index 6b5e39a2c..4470087d1 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: .debug) + let logger = ConsoleLogger(prefix: "πŸ•ΈοΈ", loggingLevel: .off) let keyValueStorage = UserDefaults.standard let keychainStorage = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk") return NetworkingClientFactory.create(relayClient: relayClient, logger: logger, keychainStorage: keychainStorage, keyValueStorage: keyValueStorage) @@ -12,7 +12,7 @@ public struct NetworkingClientFactory { public static func create(relayClient: RelayClient, logger: ConsoleLogging, keychainStorage: KeychainStorageProtocol, keyValueStorage: KeyValueStorage) -> NetworkingInteractor { let kms = KeyManagementService(keychain: keychainStorage) - let serializer = Serializer(kms: kms) + let serializer = Serializer(kms: kms, logger: ConsoleLogger(prefix: "πŸ”", loggingLevel: .off)) let rpcHistory = RPCHistoryFactory.createForNetwork(keyValueStorage: keyValueStorage) diff --git a/Sources/WalletConnectNetworking/NetworkingInteractor.swift b/Sources/WalletConnectNetworking/NetworkingInteractor.swift index 76135c8fa..a07f0b81b 100644 --- a/Sources/WalletConnectNetworking/NetworkingInteractor.swift +++ b/Sources/WalletConnectNetworking/NetworkingInteractor.swift @@ -20,7 +20,9 @@ public class NetworkingInteractor: NetworkInteracting { } public var logsPublisher: AnyPublisher { - logger.logsPublisher.eraseToAnyPublisher() + logger.logsPublisher + .merge(with: serializer.logsPublisher) + .eraseToAnyPublisher() } public var networkConnectionStatusPublisher: AnyPublisher @@ -51,6 +53,13 @@ public class NetworkingInteractor: NetworkInteracting { }.store(in: &publishers) } + public func setLogging(level: LoggingLevel) { + logger.setLogging(level: level) + serializer.setLogging(level: level) + relayClient.setLogging(level: level) + } + + public func subscribe(topic: String) async throws { try await relayClient.subscribe(topic: topic) } diff --git a/Sources/WalletConnectNotify/Client/Common/NotifyDecryptionService.swift b/Sources/WalletConnectNotify/Client/Common/NotifyDecryptionService.swift index 4078ef87e..5fe116af5 100644 --- a/Sources/WalletConnectNotify/Client/Common/NotifyDecryptionService.swift +++ b/Sources/WalletConnectNotify/Client/Common/NotifyDecryptionService.swift @@ -13,7 +13,7 @@ public class NotifyDecryptionService { public init() { let keychainStorage = GroupKeychainStorage(serviceIdentifier: "group.com.walletconnect.sdk") let kms = KeyManagementService(keychain: keychainStorage) - self.serializer = Serializer(kms: kms) + self.serializer = Serializer(kms: kms, logger: ConsoleLogger(prefix: "πŸ”", loggingLevel: .off)) } public func decryptMessage(topic: String, ciphertext: String) throws -> NotifyMessage { diff --git a/Sources/WalletConnectNotify/Client/Wallet/NotifyClientFactory.swift b/Sources/WalletConnectNotify/Client/Wallet/NotifyClientFactory.swift index c051044da..2e15e4266 100644 --- a/Sources/WalletConnectNotify/Client/Wallet/NotifyClientFactory.swift +++ b/Sources/WalletConnectNotify/Client/Wallet/NotifyClientFactory.swift @@ -3,7 +3,7 @@ import Foundation public struct NotifyClientFactory { public static func create(networkInteractor: NetworkInteracting, pairingRegisterer: PairingRegisterer, pushClient: PushClient, syncClient: SyncClient, historyClient: HistoryClient, crypto: CryptoProvider) -> NotifyClient { - let logger = ConsoleLogger(suffix: "πŸ””",loggingLevel: .debug) + let logger = ConsoleLogger(prefix: "πŸ””",loggingLevel: .debug) let keyValueStorage = UserDefaults.standard let keyserverURL = URL(string: "https://keys.walletconnect.com")! let keychainStorage = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk") diff --git a/Sources/WalletConnectPush/PushClientFactory.swift b/Sources/WalletConnectPush/PushClientFactory.swift index ef91dea4f..50a0145f9 100644 --- a/Sources/WalletConnectPush/PushClientFactory.swift +++ b/Sources/WalletConnectPush/PushClientFactory.swift @@ -25,7 +25,7 @@ public struct PushClientFactory { sessionConfiguration.timeoutIntervalForResource = 5.0 let session = URLSession(configuration: sessionConfiguration) - let logger = ConsoleLogger(suffix: "πŸ‘‚πŸ»", loggingLevel: .debug) + let logger = ConsoleLogger(prefix: "πŸ‘‚πŸ»", loggingLevel: .off) let httpClient = HTTPNetworkClient(host: pushHost, session: session) let clientIdStorage = ClientIdStorage(keychain: keychainStorage) diff --git a/Sources/WalletConnectRelay/RelayClient.swift b/Sources/WalletConnectRelay/RelayClient.swift index ddb9cf91b..60eb6aa06 100644 --- a/Sources/WalletConnectRelay/RelayClient.swift +++ b/Sources/WalletConnectRelay/RelayClient.swift @@ -63,6 +63,10 @@ public final class RelayClient { } } + public func setLogging(level: LoggingLevel) { + logger.setLogging(level: level) + } + /// Connects web socket /// /// Use this method for manual socket connection only @@ -82,12 +86,12 @@ public final class RelayClient { let request = Publish(params: .init(topic: topic, message: payload, ttl: ttl, prompt: prompt, tag: tag)) .asRPCRequest() let message = try request.asJSONEncodedString() - logger.debug("[RelayClient]: Publishing payload on topic: \(topic)") + logger.debug("Publishing payload on topic: \(topic)") try await dispatcher.protectedSend(message) } public func subscribe(topic: String) async throws { - logger.debug("[RelayClient]: Subscribing to topic: \(topic)") + logger.debug("Subscribing to topic: \(topic)") let rpc = Subscribe(params: .init(topic: topic)) let request = rpc .asRPCRequest() @@ -98,7 +102,7 @@ public final class RelayClient { public func batchSubscribe(topics: [String]) async throws { guard !topics.isEmpty else { return } - logger.debug("[RelayClient]: Subscribing to topics: \(topics)") + logger.debug("Subscribing to topics: \(topics)") let rpc = BatchSubscribe(params: .init(topics: topics)) let request = rpc .asRPCRequest() @@ -134,7 +138,7 @@ public final class RelayClient { completion(Errors.subscriptionIdNotFound) return } - logger.debug("[RelayClient]: Unsubscribing from topic: \(topic)") + logger.debug("Unsubscribing from topic: \(topic)") let rpc = Unsubscribe(params: .init(id: subscriptionId, topic: topic)) let request = rpc .asRPCRequest() @@ -142,7 +146,7 @@ public final class RelayClient { rpcHistory.deleteAll(forTopic: topic) dispatcher.protectedSend(message) { [weak self] error in if let error = error { - self?.logger.debug("[RelayClient]:Failed to unsubscribe from topic") + self?.logger.debug("Failed to unsubscribe from topic") completion(error) } else { self?.concurrentQueue.async(flags: .barrier) { @@ -161,9 +165,9 @@ public final class RelayClient { .sink { [unowned self] (_, subscriptionIds) in cancellable?.cancel() concurrentQueue.async(flags: .barrier) { [unowned self] in - logger.debug("[RelayClient]: Subscribed to topics: \(topics)") + logger.debug("Subscribed to topics: \(topics)") guard topics.count == subscriptionIds.count else { - logger.warn("RelayClient: Number of topics in (batch)subscribe does not match number of subscriptions") + logger.warn("Number of topics in (batch)subscribe does not match number of subscriptions") return } for i in 0.. { get } - /// Writes a debug message to the log. - func debug(_ items: Any...) - - /// Writes an informative message to the log. - func info(_ items: Any...) - - /// Writes information about a warning to the log. - func warn(_ items: Any...) - - /// Writes information about an error to the log. - func error(_ items: Any...) - + func debug(_ items: Any..., file: String, function: String, line: Int) + func info(_ items: Any..., file: String, function: String, line: Int) + func warn(_ items: Any..., file: String, function: String, line: Int) + func error(_ items: Any..., file: String, function: String, line: Int) func setLogging(level: LoggingLevel) } -public class ConsoleLogger: ConsoleLogging { +public extension ConsoleLogging { + func debug(_ items: Any..., file: String = #file, function: String = #function, line: Int = #line) { + debug(items, file: file, function: function, line: line) + } + func info(_ items: Any..., file: String = #file, function: String = #function, line: Int = #line) { + info(items, file: file, function: function, line: line) + } + func warn(_ items: Any..., file: String = #file, function: String = #function, line: Int = #line) { + warn(items, file: file, function: function, line: line) + } + func error(_ items: Any..., file: String = #file, function: String = #function, line: Int = #line) { + error(items, file: file, function: function, line: line) + } +} + +public class ConsoleLogger { private var loggingLevel: LoggingLevel - private var suffix: String + private var prefix: String private var logsPublisherSubject = PassthroughSubject() public var logsPublisher: AnyPublisher { return logsPublisherSubject.eraseToAnyPublisher() @@ -31,57 +37,70 @@ public class ConsoleLogger: ConsoleLogging { self.loggingLevel = level } - public init(suffix: String? = nil, loggingLevel: LoggingLevel = .warn) { - self.suffix = suffix ?? "" + public init(prefix: String? = nil, loggingLevel: LoggingLevel = .warn) { + self.prefix = prefix ?? "" self.loggingLevel = loggingLevel } - public func debug(_ items: Any...) { - if loggingLevel >= .debug { - items.forEach { - let log = "\(suffix) \($0) - \(logFormattedDate(Date()))" - Swift.print(log) + private func logMessage(_ items: Any..., logType: LoggingLevel, file: String = #file, function: String = #function, line: Int = #line) { + let fileName = (file as NSString).lastPathComponent + items.forEach { + var log = "[\(fileName)]: \($0) - \(function) - line: \(line) - \(logFormattedDate(Date()))" + + switch logType { + case .debug: + log = "\(prefix) \(log)" logsPublisherSubject.send(.debug(log)) + case .info: + log = "\(prefix) ℹ️ \(log)" + logsPublisherSubject.send(.info(log)) + case .warn: + log = "\(prefix) ⚠️ \(log)" + logsPublisherSubject.send(.warn(log)) + case .error: + log = "\(prefix) ‼️ \(log)" + logsPublisherSubject.send(.error(log)) + case .off: + return } + + Swift.print(log) } } - public func info(_ items: Any...) { + private func logFormattedDate(_ date: Date) -> String { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" + return formatter.string(from: date) + } +} + + +extension ConsoleLogger: ConsoleLogging { + public func debug(_ items: Any..., file: String, function: String, line: Int) { + if loggingLevel >= .debug { + logMessage(items, logType: .debug, file: file, function: function, line: line) + } + } + + public func info(_ items: Any..., file: String, function: String, line: Int) { if loggingLevel >= .info { - items.forEach { - let log = "\(suffix) \($0) - \(logFormattedDate(Date()))" - Swift.print(log) - logsPublisherSubject.send(.info(log)) } + logMessage(items, logType: .info, file: file, function: function, line: line) } } - public func warn(_ items: Any...) { + public func warn(_ items: Any..., file: String, function: String, line: Int) { if loggingLevel >= .warn { - items.forEach { - let log = "\(suffix) ⚠️ \($0) - \(logFormattedDate(Date()))" - Swift.print(log) - logsPublisherSubject.send(.warn(log)) - } + logMessage(items, logType: .warn, file: file, function: function, line: line) } } - public func error(_ items: Any...) { + public func error(_ items: Any..., file: String, function: String, line: Int) { if loggingLevel >= .error { - items.forEach { - let log = "\(suffix) ‼️ \($0) - \(logFormattedDate(Date()))" - Swift.print(log) - logsPublisherSubject.send(.error(log)) - } + logMessage(items, logType: .error, file: file, function: function, line: line) } } -} - -fileprivate func logFormattedDate(_ date: Date) -> String { - let dateFormatter = DateFormatter() - dateFormatter.locale = NSLocale.current - dateFormatter.dateFormat = "HH:mm:ss.SSSS" - return dateFormatter.string(from: date) } @@ -90,11 +109,15 @@ public struct ConsoleLoggerMock: ConsoleLogging { public var logsPublisher: AnyPublisher { return PassthroughSubject().eraseToAnyPublisher() } + public init() {} - public func error(_ items: Any...) { } - public func debug(_ items: Any...) { } - public func info(_ items: Any...) { } - public func warn(_ items: Any...) { } + + public func debug(_ items: Any..., file: String, function: String, line: Int) { } + public func info(_ items: Any..., file: String, function: String, line: Int) { } + public func warn(_ items: Any..., file: String, function: String, line: Int) { } + public func error(_ items: Any..., file: String, function: String, line: Int) { } + public func setLogging(level: LoggingLevel) { } } #endif + diff --git a/Sources/Web3Inbox/Web3InboxClientFactory.swift b/Sources/Web3Inbox/Web3InboxClientFactory.swift index 5713870da..3257b4b7b 100644 --- a/Sources/Web3Inbox/Web3InboxClientFactory.swift +++ b/Sources/Web3Inbox/Web3InboxClientFactory.swift @@ -12,7 +12,7 @@ final class Web3InboxClientFactory { ) -> Web3InboxClient { let url = buildUrl(account: account, config: config) - let logger = ConsoleLogger(suffix: "πŸ“¬", loggingLevel: .debug) + let logger = ConsoleLogger(prefix: "πŸ“¬", loggingLevel: .debug) let webviewSubscriber = WebViewRequestSubscriber(url: url, logger: logger) let webView = WebViewFactory(url: url, webviewSubscriber: webviewSubscriber).create() let chatWebViewProxy = WebViewProxy(webView: webView, scriptFormatter: ChatWebViewScriptFormatter(), logger: logger) diff --git a/Tests/WalletConnectKMSTests/SerialiserTests.swift b/Tests/WalletConnectKMSTests/SerialiserTests.swift index 627171b5a..bf36da69d 100644 --- a/Tests/WalletConnectKMSTests/SerialiserTests.swift +++ b/Tests/WalletConnectKMSTests/SerialiserTests.swift @@ -12,10 +12,10 @@ final class SerializerTests: XCTestCase { override func setUp() { self.myKms = KeyManagementServiceMock() - self.mySerializer = Serializer(kms: myKms) + self.mySerializer = Serializer(kms: myKms, logger: ConsoleLoggerMock()) self.peerKms = KeyManagementServiceMock() - self.peerSerializer = Serializer(kms: peerKms) + self.peerSerializer = Serializer(kms: peerKms, logger: ConsoleLoggerMock()) } func testSerializeDeserializeType0Envelope() {