diff --git a/Example/IntegrationTests/Relay/RelayClientEndToEndTests.swift b/Example/IntegrationTests/Relay/RelayClientEndToEndTests.swift index e14d9481e..60ab35252 100644 --- a/Example/IntegrationTests/Relay/RelayClientEndToEndTests.swift +++ b/Example/IntegrationTests/Relay/RelayClientEndToEndTests.swift @@ -10,10 +10,11 @@ final class RelayClientEndToEndTests: XCTestCase { private var publishers = Set() func makeRelayClient() -> RelayClient { - let clientIdStorage = ClientIdStorage(keychain: KeychainStorageMock()) + let didKeyFactory = ED25519DIDKeyFactory() + let clientIdStorage = ClientIdStorage(keychain: KeychainStorageMock(), didKeyFactory: didKeyFactory) let socketAuthenticator = SocketAuthenticator( clientIdStorage: clientIdStorage, - didKeyFactory: ED25519DIDKeyFactory(), + didKeyFactory: didKeyFactory, relayHost: InputConfig.relayHost ) let urlFactory = RelayUrlFactory(socketAuthenticator: socketAuthenticator) @@ -21,7 +22,7 @@ final class RelayClientEndToEndTests: XCTestCase { let logger = ConsoleLogger() let dispatcher = Dispatcher(socket: socket, socketConnectionHandler: ManualSocketConnectionHandler(socket: socket), logger: logger) - return RelayClient(dispatcher: dispatcher, logger: logger, keyValueStorage: RuntimeKeyValueStorage()) + return RelayClient(dispatcher: dispatcher, logger: logger, keyValueStorage: RuntimeKeyValueStorage(), clientIdStorage: clientIdStorage) } func testSubscribe() { diff --git a/Sources/WalletConnectNetworking/NetworkingClient.swift b/Sources/WalletConnectNetworking/NetworkingClient.swift index db04cd32e..f39e2790d 100644 --- a/Sources/WalletConnectNetworking/NetworkingClient.swift +++ b/Sources/WalletConnectNetworking/NetworkingClient.swift @@ -6,4 +6,5 @@ public protocol NetworkingClient { var socketConnectionStatusPublisher: AnyPublisher { get } func connect() throws func disconnect(closeCode: URLSessionWebSocketTask.CloseCode) throws + func getClientId() throws -> String } diff --git a/Sources/WalletConnectNetworking/NetworkingInteractor.swift b/Sources/WalletConnectNetworking/NetworkingInteractor.swift index 4e025d8de..39faee02a 100644 --- a/Sources/WalletConnectNetworking/NetworkingInteractor.swift +++ b/Sources/WalletConnectNetworking/NetworkingInteractor.swift @@ -180,4 +180,8 @@ extension NetworkingInteractor: NetworkingClient { public func disconnect(closeCode: URLSessionWebSocketTask.CloseCode) throws { try relayClient.disconnect(closeCode: closeCode) } + + public func getClientId() throws -> String { + try relayClient.getClientId() + } } diff --git a/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift b/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift index 826ae67e6..7d945bcda 100644 --- a/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift +++ b/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift @@ -3,14 +3,18 @@ import WalletConnectKMS protocol ClientIdStoring { func getOrCreateKeyPair() throws -> SigningPrivateKey + func getClientId() throws -> String } struct ClientIdStorage: ClientIdStoring { private let key = "com.walletconnect.iridium.client_id" private let keychain: KeychainStorageProtocol + private let didKeyFactory: DIDKeyFactory - init(keychain: KeychainStorageProtocol) { + init(keychain: KeychainStorageProtocol, + didKeyFactory: DIDKeyFactory) { self.keychain = keychain + self.didKeyFactory = didKeyFactory } func getOrCreateKeyPair() throws -> SigningPrivateKey { @@ -22,4 +26,10 @@ struct ClientIdStorage: ClientIdStoring { return privateKey } } + + func getClientId() throws -> String { + let privateKey: SigningPrivateKey = try keychain.read(key: key) + let pubKey = privateKey.publicKey.rawRepresentation + return didKeyFactory.make(pubKey: pubKey, prefix: true) + } } diff --git a/Sources/WalletConnectRelay/RelayClient.swift b/Sources/WalletConnectRelay/RelayClient.swift index c038cb0dd..0a156c7f5 100644 --- a/Sources/WalletConnectRelay/RelayClient.swift +++ b/Sources/WalletConnectRelay/RelayClient.swift @@ -41,6 +41,8 @@ public final class RelayClient { requestAcknowledgePublisherSubject.eraseToAnyPublisher() } + private let clientIdStorage: ClientIdStoring + private var dispatcher: Dispatching private let rpcHistory: RPCHistory private let logger: ConsoleLogging @@ -52,11 +54,13 @@ public final class RelayClient { init( dispatcher: Dispatching, logger: ConsoleLogging, - keyValueStorage: KeyValueStorage + keyValueStorage: KeyValueStorage, + clientIdStorage: ClientIdStoring ) { self.logger = logger self.dispatcher = dispatcher self.rpcHistory = RPCHistoryFactory.createForRelay(keyValueStorage: keyValueStorage) + self.clientIdStorage = clientIdStorage setUpBindings() } @@ -82,9 +86,11 @@ public final class RelayClient { socketConnectionType: SocketConnectionType = .automatic, logger: ConsoleLogging = ConsoleLogger(loggingLevel: .off) ) { + let didKeyFactory = ED25519DIDKeyFactory() + let clientIdStorage = ClientIdStorage(keychain: keychainStorage, didKeyFactory: didKeyFactory) let socketAuthenticator = SocketAuthenticator( - clientIdStorage: ClientIdStorage(keychain: keychainStorage), - didKeyFactory: ED25519DIDKeyFactory(), + clientIdStorage: clientIdStorage, + didKeyFactory: didKeyFactory, relayHost: relayHost ) let relayUrlFactory = RelayUrlFactory(socketAuthenticator: socketAuthenticator) @@ -101,7 +107,7 @@ public final class RelayClient { socketConnectionHandler = ManualSocketConnectionHandler(socket: socket) } let dispatcher = Dispatcher(socket: socket, socketConnectionHandler: socketConnectionHandler, logger: logger) - self.init(dispatcher: dispatcher, logger: logger, keyValueStorage: keyValueStorage) + self.init(dispatcher: dispatcher, logger: logger, keyValueStorage: keyValueStorage, clientIdStorage: clientIdStorage) } /// Connects web socket @@ -231,6 +237,10 @@ public final class RelayClient { } } + public func getClientId() throws -> String { + try clientIdStorage.getClientId() + } + // FIXME: Parse data to string once before trying to decode -> respond error on fail private func handlePayloadMessage(_ payload: String) { if let request = tryDecode(RPCRequest.self, from: payload) { diff --git a/Tests/RelayerTests/AuthTests/ClientIdStorageTests.swift b/Tests/RelayerTests/AuthTests/ClientIdStorageTests.swift index 38e27a073..a9e3e2770 100644 --- a/Tests/RelayerTests/AuthTests/ClientIdStorageTests.swift +++ b/Tests/RelayerTests/AuthTests/ClientIdStorageTests.swift @@ -6,16 +6,33 @@ import WalletConnectKMS final class ClientIdStorageTests: XCTestCase { - func testGetOrCreate() throws { - let keychain = KeychainStorageMock() - let storage = ClientIdStorage(keychain: keychain) + var sut: ClientIdStorage! + var keychain: KeychainStorageMock! + var didKeyFactory: ED25519DIDKeyFactoryMock! + + override func setUp() { + keychain = KeychainStorageMock() + didKeyFactory = ED25519DIDKeyFactoryMock() + sut = ClientIdStorage(keychain: keychain, didKeyFactory: didKeyFactory) + } + func testGetOrCreate() throws { XCTAssertThrowsError(try keychain.read(key: "com.walletconnect.iridium.client_id") as SigningPrivateKey) - let saved = try storage.getOrCreateKeyPair() + let saved = try sut.getOrCreateKeyPair() XCTAssertEqual(saved, try keychain.read(key: "com.walletconnect.iridium.client_id")) - let restored = try storage.getOrCreateKeyPair() + let restored = try sut.getOrCreateKeyPair() XCTAssertEqual(saved, restored) } + + func testGetClientId() { + let did = "did:key:z6MkodHZwneVRShtaLf8JKYkxpDGp1vGZnpGmdBpX8M2exxH" + didKeyFactory.did = did + _ = try! sut.getOrCreateKeyPair() + + let clientId = try! sut.getClientId() + XCTAssertEqual(did, clientId) + + } } diff --git a/Tests/RelayerTests/Mocks/ClientIdStorageMock.swift b/Tests/RelayerTests/Mocks/ClientIdStorageMock.swift index 2453c6174..5d26c6d34 100644 --- a/Tests/RelayerTests/Mocks/ClientIdStorageMock.swift +++ b/Tests/RelayerTests/Mocks/ClientIdStorageMock.swift @@ -3,9 +3,14 @@ import WalletConnectKMS import Foundation class ClientIdStorageMock: ClientIdStoring { + var keyPair: SigningPrivateKey! func getOrCreateKeyPair() throws -> SigningPrivateKey { return keyPair } + + func getClientId() throws -> String { + fatalError() + } } diff --git a/Tests/RelayerTests/Mocks/ED25519DIDKeyFactoryMock.swift b/Tests/RelayerTests/Mocks/ED25519DIDKeyFactoryMock.swift index 23afd5c3c..11ef10631 100644 --- a/Tests/RelayerTests/Mocks/ED25519DIDKeyFactoryMock.swift +++ b/Tests/RelayerTests/Mocks/ED25519DIDKeyFactoryMock.swift @@ -2,7 +2,7 @@ import WalletConnectKMS @testable import WalletConnectRelay import Foundation -struct ED25519DIDKeyFactoryMock: DIDKeyFactory { +class ED25519DIDKeyFactoryMock: DIDKeyFactory { var did: String! func make(pubKey: Data, prefix: Bool) -> String { return did diff --git a/Tests/RelayerTests/RelayClientTests.swift b/Tests/RelayerTests/RelayClientTests.swift index f9094bf17..f37148fca 100644 --- a/Tests/RelayerTests/RelayClientTests.swift +++ b/Tests/RelayerTests/RelayClientTests.swift @@ -9,13 +9,13 @@ final class RelayClientTests: XCTestCase { var sut: RelayClient! var dispatcher: DispatcherMock! - var publishers = Set() override func setUp() { dispatcher = DispatcherMock() let logger = ConsoleLogger() - sut = RelayClient(dispatcher: dispatcher, logger: logger, keyValueStorage: RuntimeKeyValueStorage()) + let clientIdStorage = ClientIdStorageMock() + sut = RelayClient(dispatcher: dispatcher, logger: logger, keyValueStorage: RuntimeKeyValueStorage(), clientIdStorage: clientIdStorage) } override func tearDown() {