From a05be877ef7a744bcb8dabc96cb573fb0620de76 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 23 Jan 2024 14:06:09 +0300 Subject: [PATCH 01/10] NetworkMonitor in Dispatcher --- .../NetworkingInteractor.swift | 5 +---- Sources/WalletConnectRelay/Dispatching.swift | 16 ++++++++++++---- .../WalletConnectRelay/NetworkMonitoring.swift | 7 ++++++- Sources/WalletConnectRelay/RelayClient.swift | 4 ++++ .../WalletConnectRelay/RelayClientFactory.swift | 8 +++++++- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/Sources/WalletConnectNetworking/NetworkingInteractor.swift b/Sources/WalletConnectNetworking/NetworkingInteractor.swift index 078c8adf7..08ace2bdb 100644 --- a/Sources/WalletConnectNetworking/NetworkingInteractor.swift +++ b/Sources/WalletConnectNetworking/NetworkingInteractor.swift @@ -30,8 +30,6 @@ public class NetworkingInteractor: NetworkInteracting { public var networkConnectionStatusPublisher: AnyPublisher public var socketConnectionStatusPublisher: AnyPublisher - private let networkMonitor: NetworkMonitoring - public init( relayClient: RelayClient, serializer: Serializing, @@ -43,8 +41,7 @@ public class NetworkingInteractor: NetworkInteracting { self.rpcHistory = rpcHistory self.logger = logger self.socketConnectionStatusPublisher = relayClient.socketConnectionStatusPublisher - self.networkMonitor = NetworkMonitor() - self.networkConnectionStatusPublisher = networkMonitor.networkConnectionStatusPublisher + self.networkConnectionStatusPublisher = relayClient.networkConnectionStatusPublisher setupRelaySubscribtion() } diff --git a/Sources/WalletConnectRelay/Dispatching.swift b/Sources/WalletConnectRelay/Dispatching.swift index bf3ef2c92..9327608e6 100644 --- a/Sources/WalletConnectRelay/Dispatching.swift +++ b/Sources/WalletConnectRelay/Dispatching.swift @@ -3,6 +3,7 @@ import Combine protocol Dispatching { var onMessage: ((String) -> Void)? { get set } + var networkConnectionStatusPublisher: AnyPublisher { get } var socketConnectionStatusPublisher: AnyPublisher { get } func send(_ string: String, completion: @escaping (Error?) -> Void) func protectedSend(_ string: String, completion: @escaping (Error?) -> Void) @@ -17,8 +18,9 @@ final class Dispatcher: NSObject, Dispatching { var socketConnectionHandler: SocketConnectionHandler private let relayUrlFactory: RelayUrlFactory + private let networkMonitor: NetworkMonitoring private let logger: ConsoleLogging - + private let defaultTimeout: Int = 5 /// The property is used to determine whether relay.walletconnect.org will be used /// in case relay.walletconnect.com doesn't respond for some reason (most likely due to being blocked in the user's location). @@ -30,15 +32,21 @@ final class Dispatcher: NSObject, Dispatching { socketConnectionStatusPublisherSubject.eraseToAnyPublisher() } + var networkConnectionStatusPublisher: AnyPublisher { + networkMonitor.networkConnectionStatusPublisher + } + private let concurrentQueue = DispatchQueue(label: "com.walletconnect.sdk.dispatcher", attributes: .concurrent) init( socketFactory: WebSocketFactory, relayUrlFactory: RelayUrlFactory, + networkMonitor: NetworkMonitoring, socketConnectionType: SocketConnectionType, logger: ConsoleLogging ) { self.relayUrlFactory = relayUrlFactory + self.networkMonitor = networkMonitor self.logger = logger let socket = socketFactory.create(with: relayUrlFactory.create(fallback: fallback)) @@ -69,13 +77,13 @@ final class Dispatcher: NSObject, Dispatching { } func protectedSend(_ string: String, completion: @escaping (Error?) -> Void) { - guard !socket.isConnected else { + guard !socket.isConnected, !networkMonitor.isConnected else { return send(string, completion: completion) } var cancellable: AnyCancellable? - cancellable = socketConnectionStatusPublisher - .filter { $0 == .connected } + cancellable = Publishers.CombineLatest(socketConnectionStatusPublisher, networkConnectionStatusPublisher) + .filter { $0.0 == .connected && $0.1 == .connected } .setFailureType(to: NetworkError.self) .timeout(.seconds(defaultTimeout), scheduler: concurrentQueue, customError: { .webSocketNotConnected }) .sink(receiveCompletion: { [unowned self] result in diff --git a/Sources/WalletConnectRelay/NetworkMonitoring.swift b/Sources/WalletConnectRelay/NetworkMonitoring.swift index 1d3932db5..e6c6b4477 100644 --- a/Sources/WalletConnectRelay/NetworkMonitoring.swift +++ b/Sources/WalletConnectRelay/NetworkMonitoring.swift @@ -8,6 +8,7 @@ public enum NetworkConnectionStatus { } public protocol NetworkMonitoring: AnyObject { + var isConnected: Bool { get } var networkConnectionStatusPublisher: AnyPublisher { get } } @@ -16,7 +17,11 @@ public final class NetworkMonitor: NetworkMonitoring { private let workerQueue = DispatchQueue(label: "com.walletconnect.sdk.network.monitor") private let networkConnectionStatusPublisherSubject = CurrentValueSubject(.connected) - + + public var isConnected: Bool { + return networkConnectionStatusPublisherSubject.value == .connected + } + public var networkConnectionStatusPublisher: AnyPublisher { networkConnectionStatusPublisherSubject .share() diff --git a/Sources/WalletConnectRelay/RelayClient.swift b/Sources/WalletConnectRelay/RelayClient.swift index 24cae47c0..3febc4c60 100644 --- a/Sources/WalletConnectRelay/RelayClient.swift +++ b/Sources/WalletConnectRelay/RelayClient.swift @@ -27,6 +27,10 @@ public final class RelayClient { dispatcher.socketConnectionStatusPublisher } + public var networkConnectionStatusPublisher: AnyPublisher { + dispatcher.networkConnectionStatusPublisher + } + private let messagePublisherSubject = PassthroughSubject<(topic: String, message: String, publishedAt: Date), Never>() private let subscriptionResponsePublisherSubject = PassthroughSubject<(RPCID?, [String]), Never>() diff --git a/Sources/WalletConnectRelay/RelayClientFactory.swift b/Sources/WalletConnectRelay/RelayClientFactory.swift index 98066e6c8..b59a50d29 100644 --- a/Sources/WalletConnectRelay/RelayClientFactory.swift +++ b/Sources/WalletConnectRelay/RelayClientFactory.swift @@ -20,6 +20,8 @@ public struct RelayClientFactory { let logger = ConsoleLogger(prefix: "🚄" ,loggingLevel: .off) + let networkMonitor = NetworkMonitor() + return RelayClientFactory.create( relayHost: relayHost, projectId: projectId, @@ -27,6 +29,7 @@ public struct RelayClientFactory { keychainStorage: keychainStorage, socketFactory: socketFactory, socketConnectionType: socketConnectionType, + networkMonitor: networkMonitor, logger: logger ) } @@ -39,6 +42,7 @@ public struct RelayClientFactory { keychainStorage: KeychainStorageProtocol, socketFactory: WebSocketFactory, socketConnectionType: SocketConnectionType = .automatic, + networkMonitor: NetworkMonitoring, logger: ConsoleLogging ) -> RelayClient { @@ -52,9 +56,11 @@ public struct RelayClientFactory { projectId: projectId, socketAuthenticator: socketAuthenticator ) + let dispatcher = Dispatcher( socketFactory: socketFactory, - relayUrlFactory: relayUrlFactory, + relayUrlFactory: relayUrlFactory, + networkMonitor: networkMonitor, socketConnectionType: socketConnectionType, logger: logger ) From 6489245568a8a36f527b1aa627f61f199277ba5a Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 23 Jan 2024 14:36:58 +0300 Subject: [PATCH 02/10] protectedSend logic fixed --- Sources/WalletConnectRelay/Dispatching.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnectRelay/Dispatching.swift b/Sources/WalletConnectRelay/Dispatching.swift index 9327608e6..f32d7a5e8 100644 --- a/Sources/WalletConnectRelay/Dispatching.swift +++ b/Sources/WalletConnectRelay/Dispatching.swift @@ -77,7 +77,7 @@ final class Dispatcher: NSObject, Dispatching { } func protectedSend(_ string: String, completion: @escaping (Error?) -> Void) { - guard !socket.isConnected, !networkMonitor.isConnected else { + guard !socket.isConnected || !networkMonitor.isConnected else { return send(string, completion: completion) } From 8f54f0b5d02fd6740aeda118483ff1a6d7f9dc66 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 23 Jan 2024 14:37:06 +0300 Subject: [PATCH 03/10] Integration tests repaired --- Example/IntegrationTests/Auth/AuthTests.swift | 1 + Example/IntegrationTests/Chat/ChatTests.swift | 1 + Example/IntegrationTests/Pairing/PairingTests.swift | 1 + Example/IntegrationTests/Push/NotifyTests.swift | 1 + Example/IntegrationTests/Sign/SignClientTests.swift | 1 + Example/IntegrationTests/Sync/SyncTests.swift | 1 + .../XPlatform/Web3Wallet/XPlatformW3WTests.swift | 1 + 7 files changed, 7 insertions(+) diff --git a/Example/IntegrationTests/Auth/AuthTests.swift b/Example/IntegrationTests/Auth/AuthTests.swift index 276e14e84..ab831899f 100644 --- a/Example/IntegrationTests/Auth/AuthTests.swift +++ b/Example/IntegrationTests/Auth/AuthTests.swift @@ -40,6 +40,7 @@ final class AuthTests: XCTestCase { keyValueStorage: keyValueStorage, keychainStorage: keychain, socketFactory: DefaultSocketFactory(), + networkMonitor: NetworkMonitor(), logger: logger) let networkingClient = NetworkingClientFactory.create( diff --git a/Example/IntegrationTests/Chat/ChatTests.swift b/Example/IntegrationTests/Chat/ChatTests.swift index ff09c65f1..747bd29a3 100644 --- a/Example/IntegrationTests/Chat/ChatTests.swift +++ b/Example/IntegrationTests/Chat/ChatTests.swift @@ -56,6 +56,7 @@ final class ChatTests: XCTestCase { keyValueStorage: keyValueStorage, keychainStorage: keychain, socketFactory: DefaultSocketFactory(), + networkMonitor: NetworkMonitor(), logger: logger) let networkingInteractor = NetworkingClientFactory.create( diff --git a/Example/IntegrationTests/Pairing/PairingTests.swift b/Example/IntegrationTests/Pairing/PairingTests.swift index 6bc02014c..d9e83de6e 100644 --- a/Example/IntegrationTests/Pairing/PairingTests.swift +++ b/Example/IntegrationTests/Pairing/PairingTests.swift @@ -34,6 +34,7 @@ final class PairingTests: XCTestCase { keyValueStorage: RuntimeKeyValueStorage(), keychainStorage: keychain, socketFactory: DefaultSocketFactory(), + networkMonitor: NetworkMonitor(), logger: logger) let networkingClient = NetworkingClientFactory.create( diff --git a/Example/IntegrationTests/Push/NotifyTests.swift b/Example/IntegrationTests/Push/NotifyTests.swift index 5644fcd89..26400548c 100644 --- a/Example/IntegrationTests/Push/NotifyTests.swift +++ b/Example/IntegrationTests/Push/NotifyTests.swift @@ -45,6 +45,7 @@ final class NotifyTests: XCTestCase { keyValueStorage: keyValueStorage, keychainStorage: keychain, socketFactory: DefaultSocketFactory(), + networkMonitor: NetworkMonitor(), logger: relayLogger) let networkingClient = NetworkingClientFactory.create( diff --git a/Example/IntegrationTests/Sign/SignClientTests.swift b/Example/IntegrationTests/Sign/SignClientTests.swift index 28202a224..9e0fc6867 100644 --- a/Example/IntegrationTests/Sign/SignClientTests.swift +++ b/Example/IntegrationTests/Sign/SignClientTests.swift @@ -26,6 +26,7 @@ final class SignClientTests: XCTestCase { keyValueStorage: keyValueStorage, keychainStorage: keychain, socketFactory: DefaultSocketFactory(), + networkMonitor: NetworkMonitor(), logger: logger ) diff --git a/Example/IntegrationTests/Sync/SyncTests.swift b/Example/IntegrationTests/Sync/SyncTests.swift index adcfdc532..5e19c1345 100644 --- a/Example/IntegrationTests/Sync/SyncTests.swift +++ b/Example/IntegrationTests/Sync/SyncTests.swift @@ -63,6 +63,7 @@ final class SyncTests: XCTestCase { keyValueStorage: RuntimeKeyValueStorage(), keychainStorage: keychain, socketFactory: DefaultSocketFactory(), + networkMonitor: NetworkMonitor(), logger: logger) let networkingInteractor = NetworkingClientFactory.create( relayClient: relayClient, diff --git a/Example/IntegrationTests/XPlatform/Web3Wallet/XPlatformW3WTests.swift b/Example/IntegrationTests/XPlatform/Web3Wallet/XPlatformW3WTests.swift index 3d794d18a..c2f18b4c1 100644 --- a/Example/IntegrationTests/XPlatform/Web3Wallet/XPlatformW3WTests.swift +++ b/Example/IntegrationTests/XPlatform/Web3Wallet/XPlatformW3WTests.swift @@ -33,6 +33,7 @@ final class XPlatformW3WTests: XCTestCase { keyValueStorage: keyValueStorage, keychainStorage: keychain, socketFactory: DefaultSocketFactory(), + networkMonitor: NetworkMonitor(), logger: relayLogger ) From ff5a895561cb529d2fc13edfd1ff52e1bcbf959b Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 23 Jan 2024 14:50:32 +0300 Subject: [PATCH 04/10] Relayer tests updated --- Tests/RelayerTests/DispatcherTests.swift | 4 +++- Tests/RelayerTests/Mocks/DispatcherMock.swift | 4 ++++ Tests/RelayerTests/Mocks/NetworkMonitoringMock.swift | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Tests/RelayerTests/DispatcherTests.swift b/Tests/RelayerTests/DispatcherTests.swift index 8d86455df..331bd640d 100644 --- a/Tests/RelayerTests/DispatcherTests.swift +++ b/Tests/RelayerTests/DispatcherTests.swift @@ -62,6 +62,7 @@ final class DispatcherTests: XCTestCase { networkMonitor = NetworkMonitoringMock() let defaults = RuntimeKeyValueStorage() let logger = ConsoleLoggerMock() + let networkMonitor = NetworkMonitoringMock() let keychainStorageMock = DispatcherKeychainStorageMock() let clientIdStorage = ClientIdStorage(defaults: defaults, keychain: keychainStorageMock, logger: logger) let socketAuthenticator = ClientIdAuthenticator(clientIdStorage: clientIdStorage) @@ -72,7 +73,8 @@ final class DispatcherTests: XCTestCase { ) sut = Dispatcher( socketFactory: webSocketFactory, - relayUrlFactory: relayUrlFactory, + relayUrlFactory: relayUrlFactory, + networkMonitor: networkMonitor, socketConnectionType: .manual, logger: ConsoleLoggerMock() ) diff --git a/Tests/RelayerTests/Mocks/DispatcherMock.swift b/Tests/RelayerTests/Mocks/DispatcherMock.swift index d5088bf61..869e3a0f9 100644 --- a/Tests/RelayerTests/Mocks/DispatcherMock.swift +++ b/Tests/RelayerTests/Mocks/DispatcherMock.swift @@ -4,11 +4,15 @@ import Combine @testable import WalletConnectRelay class DispatcherMock: Dispatching { + private var publishers = Set() private let socketConnectionStatusPublisherSubject = CurrentValueSubject(.disconnected) var socketConnectionStatusPublisher: AnyPublisher { return socketConnectionStatusPublisherSubject.eraseToAnyPublisher() } + var networkConnectionStatusPublisher: AnyPublisher { + return Just(.connected).eraseToAnyPublisher() + } var sent = false var lastMessage: String = "" diff --git a/Tests/RelayerTests/Mocks/NetworkMonitoringMock.swift b/Tests/RelayerTests/Mocks/NetworkMonitoringMock.swift index 1095d1677..bfbad58cf 100644 --- a/Tests/RelayerTests/Mocks/NetworkMonitoringMock.swift +++ b/Tests/RelayerTests/Mocks/NetworkMonitoringMock.swift @@ -4,6 +4,10 @@ import Combine @testable import WalletConnectRelay class NetworkMonitoringMock: NetworkMonitoring { + var isConnected: Bool { + return true + } + var networkConnectionStatusPublisher: AnyPublisher { networkConnectionStatusPublisherSubject.eraseToAnyPublisher() } From c8fd1670ffed79e807121d0192f48d9204b11769 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 23 Jan 2024 15:05:06 +0300 Subject: [PATCH 05/10] RelayClientEndToEndTests repaired --- Example/RelayIntegrationTests/RelayClientEndToEndTests.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift b/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift index 119a62901..4fee45c97 100644 --- a/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift +++ b/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift @@ -47,6 +47,7 @@ final class RelayClientEndToEndTests: XCTestCase { let dispatcher = Dispatcher( socketFactory: webSocketFactory, relayUrlFactory: urlFactory, + networkMonitor: NetworkMonitor(), socketConnectionType: .manual, logger: logger ) From e05bce532d97e0bf01e9a188f103976505d3fb37 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 23 Jan 2024 15:42:01 +0300 Subject: [PATCH 06/10] Update RelayClientEndToEndTests.swift --- .../RelayIntegrationTests/RelayClientEndToEndTests.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift b/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift index 4fee45c97..3ac8d75b7 100644 --- a/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift +++ b/Example/RelayIntegrationTests/RelayClientEndToEndTests.swift @@ -44,10 +44,11 @@ final class RelayClientEndToEndTests: XCTestCase { ) let socket = WebSocket(url: urlFactory.create(fallback: false)) let webSocketFactory = WebSocketFactoryMock(webSocket: socket) + let networkMonitor = NetworkMonitor() let dispatcher = Dispatcher( socketFactory: webSocketFactory, relayUrlFactory: urlFactory, - networkMonitor: NetworkMonitor(), + networkMonitor: networkMonitor, socketConnectionType: .manual, logger: logger ) @@ -58,7 +59,8 @@ final class RelayClientEndToEndTests: XCTestCase { keyValueStorage: keyValueStorage, keychainStorage: keychain, socketFactory: DefaultSocketFactory(), - socketConnectionType: .manual, + socketConnectionType: .manual, + networkMonitor: networkMonitor, logger: logger ) let clientId = try! relayClient.getClientId() From 14cbe5214e97139da89ca8469b9220921ce076fb Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 23 Jan 2024 16:15:12 +0300 Subject: [PATCH 07/10] Unsubscribe optional completion --- Sources/WalletConnectRelay/RelayClient.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/WalletConnectRelay/RelayClient.swift b/Sources/WalletConnectRelay/RelayClient.swift index 3febc4c60..5ff6135fd 100644 --- a/Sources/WalletConnectRelay/RelayClient.swift +++ b/Sources/WalletConnectRelay/RelayClient.swift @@ -169,9 +169,9 @@ public final class RelayClient { } } - public func unsubscribe(topic: String, completion: @escaping ((Error?) -> Void)) { + public func unsubscribe(topic: String, completion: ((Error?) -> Void)?) { guard let subscriptionId = subscriptions[topic] else { - completion(Errors.subscriptionIdNotFound) + completion?(Errors.subscriptionIdNotFound) return } logger.debug("Unsubscribing from topic: \(topic)") @@ -183,12 +183,12 @@ public final class RelayClient { dispatcher.protectedSend(message) { [weak self] error in if let error = error { self?.logger.debug("Failed to unsubscribe from topic") - completion(error) + completion?(error) } else { self?.concurrentQueue.async(flags: .barrier) { self?.subscriptions[topic] = nil } - completion(nil) + completion?(nil) } } } From 5774ada2e4673b7242b968537eaca91f0702cbe5 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 23 Jan 2024 17:06:00 +0300 Subject: [PATCH 08/10] RPCHistory cleanup on error --- .../NetworkingInteractor.swift | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Sources/WalletConnectNetworking/NetworkingInteractor.swift b/Sources/WalletConnectNetworking/NetworkingInteractor.swift index 08ace2bdb..d086b8db8 100644 --- a/Sources/WalletConnectNetworking/NetworkingInteractor.swift +++ b/Sources/WalletConnectNetworking/NetworkingInteractor.swift @@ -202,8 +202,21 @@ public class NetworkingInteractor: NetworkInteracting { public func request(_ request: RPCRequest, topic: String, protocolMethod: ProtocolMethod, envelopeType: Envelope.EnvelopeType) async throws { try rpcHistory.set(request, forTopic: topic, emmitedBy: .local) - let message = try serializer.serialize(topic: topic, encodable: request, envelopeType: envelopeType) - try await relayClient.publish(topic: topic, payload: message, tag: protocolMethod.requestConfig.tag, prompt: protocolMethod.requestConfig.prompt, ttl: protocolMethod.requestConfig.ttl) + + do { + let message = try serializer.serialize(topic: topic, encodable: request, envelopeType: envelopeType) + + try await relayClient.publish(topic: topic, + payload: message, + tag: protocolMethod.requestConfig.tag, + prompt: protocolMethod.requestConfig.prompt, + ttl: protocolMethod.requestConfig.ttl) + } catch { + if let id = request.id { + rpcHistory.delete(id: id) + } + throw error + } } public func respond(topic: String, response: RPCResponse, protocolMethod: ProtocolMethod, envelopeType: Envelope.EnvelopeType) async throws { From cb77784c0380f2f5026f8a05e2f3ca0dc24fc08a Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Wed, 24 Jan 2024 15:19:10 +0300 Subject: [PATCH 09/10] Common network error --- Sources/WalletConnectRelay/Dispatching.swift | 6 +++--- Sources/WalletConnectRelay/Misc/NetworkError.swift | 8 ++++---- Tests/RelayerTests/Helpers/Error+Extension.swift | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Sources/WalletConnectRelay/Dispatching.swift b/Sources/WalletConnectRelay/Dispatching.swift index f32d7a5e8..efd932f70 100644 --- a/Sources/WalletConnectRelay/Dispatching.swift +++ b/Sources/WalletConnectRelay/Dispatching.swift @@ -68,7 +68,7 @@ final class Dispatcher: NSObject, Dispatching { func send(_ string: String, completion: @escaping (Error?) -> Void) { guard socket.isConnected else { - completion(NetworkError.webSocketNotConnected) + completion(NetworkError.connectionFailed) return } socket.write(string: string) { @@ -85,7 +85,7 @@ final class Dispatcher: NSObject, Dispatching { cancellable = Publishers.CombineLatest(socketConnectionStatusPublisher, networkConnectionStatusPublisher) .filter { $0.0 == .connected && $0.1 == .connected } .setFailureType(to: NetworkError.self) - .timeout(.seconds(defaultTimeout), scheduler: concurrentQueue, customError: { .webSocketNotConnected }) + .timeout(.seconds(defaultTimeout), scheduler: concurrentQueue, customError: { .connectionFailed }) .sink(receiveCompletion: { [unowned self] result in switch result { case .failure(let error): @@ -145,7 +145,7 @@ extension Dispatcher { } private func handleFallbackIfNeeded(error: NetworkError) { - if error == .webSocketNotConnected && socket.request.url?.host == NetworkConstants.defaultUrl { + if error == .connectionFailed && socket.request.url?.host == NetworkConstants.defaultUrl { logger.debug("[WebSocket] - Fallback to \(NetworkConstants.fallbackUrl)") fallback = true socket.request.url = relayUrlFactory.create(fallback: fallback) diff --git a/Sources/WalletConnectRelay/Misc/NetworkError.swift b/Sources/WalletConnectRelay/Misc/NetworkError.swift index f31340bbd..e0a66c2c1 100644 --- a/Sources/WalletConnectRelay/Misc/NetworkError.swift +++ b/Sources/WalletConnectRelay/Misc/NetworkError.swift @@ -1,13 +1,13 @@ import Foundation enum NetworkError: Error, Equatable { - case webSocketNotConnected + case connectionFailed case sendMessageFailed(Error) case receiveMessageFailure(Error) static func == (lhs: NetworkError, rhs: NetworkError) -> Bool { switch (lhs, rhs) { - case (.webSocketNotConnected, .webSocketNotConnected): return true + case (.connectionFailed, .connectionFailed): return true case (.sendMessageFailed, .sendMessageFailed): return true case (.receiveMessageFailure, .receiveMessageFailure): return true default: return false @@ -22,8 +22,8 @@ extension NetworkError: LocalizedError { var localizedDescription: String { switch self { - case .webSocketNotConnected: - return "Web socket is not connected to any URL." + case .connectionFailed: + return "Web socket is not connected to any URL or networking connection error" case .sendMessageFailed(let error): return "Failed to send a message through the web socket: \(error)" case .receiveMessageFailure(let error): diff --git a/Tests/RelayerTests/Helpers/Error+Extension.swift b/Tests/RelayerTests/Helpers/Error+Extension.swift index 901d2d829..76dd92672 100644 --- a/Tests/RelayerTests/Helpers/Error+Extension.swift +++ b/Tests/RelayerTests/Helpers/Error+Extension.swift @@ -24,7 +24,7 @@ extension Error { extension NetworkError { var isWebSocketError: Bool { - guard case .webSocketNotConnected = self else { return false } + guard case .connectionFailed = self else { return false } return true } From e816d31421c5fbe4e0b5e1c83cf4d1497de173a2 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Wed, 24 Jan 2024 17:29:44 +0300 Subject: [PATCH 10/10] Update Dispatching.swift --- Sources/WalletConnectRelay/Dispatching.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/WalletConnectRelay/Dispatching.swift b/Sources/WalletConnectRelay/Dispatching.swift index efd932f70..7d13bc39f 100644 --- a/Sources/WalletConnectRelay/Dispatching.swift +++ b/Sources/WalletConnectRelay/Dispatching.swift @@ -90,7 +90,9 @@ final class Dispatcher: NSObject, Dispatching { switch result { case .failure(let error): cancellable?.cancel() - self.handleFallbackIfNeeded(error: error) + if !socket.isConnected { + handleFallbackIfNeeded(error: error) + } completion(error) case .finished: break }