From 2cf31544bd2696c96c21f770de567a4e32327fdd Mon Sep 17 00:00:00 2001 From: Alexander Lisovik Date: Wed, 15 Feb 2023 12:17:38 +0100 Subject: [PATCH 01/55] Add echo client to web3wallet --- Package.swift | 2 +- Sources/WalletConnectEcho/EchoClient.swift | 2 +- Sources/WalletConnectEcho/EchoClientProtocol.swift | 5 +++++ Sources/Web3Wallet/Web3Wallet.swift | 4 +++- Sources/Web3Wallet/Web3WalletClient.swift | 10 +++++++++- Sources/Web3Wallet/Web3WalletClientFactory.swift | 7 +++++-- 6 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 Sources/WalletConnectEcho/EchoClientProtocol.swift diff --git a/Package.swift b/Package.swift index 9a457fd6e..82a150761 100644 --- a/Package.swift +++ b/Package.swift @@ -60,7 +60,7 @@ let package = Package( path: "Sources/Auth"), .target( name: "Web3Wallet", - dependencies: ["Auth", "WalletConnectSign"], + dependencies: ["Auth", "WalletConnectSign", "WalletConnectEcho"], path: "Sources/Web3Wallet"), .target( name: "WalletConnectPush", diff --git a/Sources/WalletConnectEcho/EchoClient.swift b/Sources/WalletConnectEcho/EchoClient.swift index 495b19939..c7f18809b 100644 --- a/Sources/WalletConnectEcho/EchoClient.swift +++ b/Sources/WalletConnectEcho/EchoClient.swift @@ -1,7 +1,7 @@ import Foundation import WalletConnectNetworking -public class EchoClient { +public class EchoClient: EchoClientProtocol { private let registerService: EchoRegisterService init(registerService: EchoRegisterService) { diff --git a/Sources/WalletConnectEcho/EchoClientProtocol.swift b/Sources/WalletConnectEcho/EchoClientProtocol.swift new file mode 100644 index 000000000..b10577744 --- /dev/null +++ b/Sources/WalletConnectEcho/EchoClientProtocol.swift @@ -0,0 +1,5 @@ +import Foundation + +public protocol EchoClientProtocol { + func register(deviceToken: Data) async throws +} diff --git a/Sources/Web3Wallet/Web3Wallet.swift b/Sources/Web3Wallet/Web3Wallet.swift index 3fb7bc876..7a6afc05f 100644 --- a/Sources/Web3Wallet/Web3Wallet.swift +++ b/Sources/Web3Wallet/Web3Wallet.swift @@ -1,4 +1,5 @@ import Foundation +import WalletConnectEcho import Combine /// Web3Wallet instance wrapper @@ -23,7 +24,8 @@ public class Web3Wallet { return Web3WalletClientFactory.create( authClient: Auth.instance, signClient: Sign.instance, - pairingClient: Pair.instance as! PairingClient + pairingClient: Pair.instance as! PairingClient, + echoClient: Echo.instance ) }() diff --git a/Sources/Web3Wallet/Web3WalletClient.swift b/Sources/Web3Wallet/Web3WalletClient.swift index cde24b697..685606686 100644 --- a/Sources/Web3Wallet/Web3WalletClient.swift +++ b/Sources/Web3Wallet/Web3WalletClient.swift @@ -1,4 +1,5 @@ import Foundation +import WalletConnectEcho import Combine /// Web3 Wallet Client @@ -41,17 +42,20 @@ public class Web3WalletClient { private let authClient: AuthClientProtocol private let signClient: SignClientProtocol private let pairingClient: PairingClientProtocol + private let echoClient: EchoClientProtocol private var account: Account? init( authClient: AuthClientProtocol, signClient: SignClientProtocol, - pairingClient: PairingClientProtocol + pairingClient: PairingClientProtocol, + echoClient: EchoClientProtocol ) { self.authClient = authClient self.signClient = signClient self.pairingClient = pairingClient + self.echoClient = echoClient } /// For a wallet to approve a session proposal. @@ -176,4 +180,8 @@ public class Web3WalletClient { public func getPendingRequests() throws -> [AuthRequest] { try authClient.getPendingRequests() } + + public func registerEchoClient(deviceToken: Data) async throws { + try await echoClient.register(deviceToken: deviceToken) + } } diff --git a/Sources/Web3Wallet/Web3WalletClientFactory.swift b/Sources/Web3Wallet/Web3WalletClientFactory.swift index 6a91213a7..7315600db 100644 --- a/Sources/Web3Wallet/Web3WalletClientFactory.swift +++ b/Sources/Web3Wallet/Web3WalletClientFactory.swift @@ -1,15 +1,18 @@ import Foundation +import WalletConnectEcho public struct Web3WalletClientFactory { public static func create( authClient: AuthClientProtocol, signClient: SignClientProtocol, - pairingClient: PairingClientProtocol + pairingClient: PairingClientProtocol, + echoClient: EchoClientProtocol ) -> Web3WalletClient { return Web3WalletClient( authClient: authClient, signClient: signClient, - pairingClient: pairingClient + pairingClient: pairingClient, + echoClient: echoClient ) } } From 060e5061f4adfa28234e51f9103b72eb5754c3ad Mon Sep 17 00:00:00 2001 From: Pavel Zak Date: Mon, 20 Feb 2023 12:30:23 +0100 Subject: [PATCH 02/55] making Session.Event init available publicly --- Sources/WalletConnectSign/Session.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sources/WalletConnectSign/Session.swift b/Sources/WalletConnectSign/Session.swift index 624b1eca2..a274c8e2b 100644 --- a/Sources/WalletConnectSign/Session.swift +++ b/Sources/WalletConnectSign/Session.swift @@ -32,6 +32,11 @@ extension Session { public let name: String public let data: AnyCodable + public init(name: String, data: AnyCodable) { + self.name = name + self.data = data + } + internal func internalRepresentation() -> SessionType.EventParams.Event { SessionType.EventParams.Event(name: name, data: data) } From cfd2027a190be8843023b42a2806e8302b16a11c Mon Sep 17 00:00:00 2001 From: Pavel Zak Date: Tue, 21 Feb 2023 09:34:26 +0100 Subject: [PATCH 03/55] added support for printing error messages --- Sources/WalletConnectSign/WalletConnectError.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Sources/WalletConnectSign/WalletConnectError.swift b/Sources/WalletConnectSign/WalletConnectError.swift index 0213059c1..a66091280 100644 --- a/Sources/WalletConnectSign/WalletConnectError.swift +++ b/Sources/WalletConnectSign/WalletConnectError.swift @@ -60,3 +60,10 @@ extension WalletConnectError { } } } + + +extension WalletConnectError: LocalizedError { + public var errorDescription: String? { + return self.localizedDescription + } +} From 35bc295bebbcf2fa38bf4b17cbe2115aba363b52 Mon Sep 17 00:00:00 2001 From: Pavel Zak Date: Tue, 21 Feb 2023 09:52:07 +0100 Subject: [PATCH 04/55] need to import Foundation --- Sources/WalletConnectSign/WalletConnectError.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/WalletConnectSign/WalletConnectError.swift b/Sources/WalletConnectSign/WalletConnectError.swift index a66091280..a1be34777 100644 --- a/Sources/WalletConnectSign/WalletConnectError.swift +++ b/Sources/WalletConnectSign/WalletConnectError.swift @@ -1,3 +1,5 @@ +import Foundation + enum WalletConnectError: Error { case pairingProposalFailed From 1da1f3d120b0601a3ced5bca5de34aa5d64eeec9 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Sun, 26 Feb 2023 12:30:00 +0100 Subject: [PATCH 05/55] Add echo authenticator --- Package.swift | 2 +- .../Register/EchoAuthPayload.swift | 39 +++++++++++++++++++ .../Register/EchoAuthenticator.swift | 26 +++++++++++++ .../Register/EchoRegisterService.swift | 2 + .../Register/EchoService.swift | 1 + .../ClientAuth/ClientIdStorage.swift | 8 ++-- 6 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 Sources/WalletConnectEcho/Register/EchoAuthPayload.swift create mode 100644 Sources/WalletConnectEcho/Register/EchoAuthenticator.swift diff --git a/Package.swift b/Package.swift index a4393df00..972115a82 100644 --- a/Package.swift +++ b/Package.swift @@ -68,7 +68,7 @@ let package = Package( path: "Sources/WalletConnectPush"), .target( name: "WalletConnectEcho", - dependencies: ["WalletConnectNetworking"], + dependencies: ["WalletConnectNetworking", "WalletConnectJWT"], path: "Sources/WalletConnectEcho"), .target( name: "WalletConnectRelay", diff --git a/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift b/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift new file mode 100644 index 000000000..86bf08b8e --- /dev/null +++ b/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift @@ -0,0 +1,39 @@ +import Foundation + +struct EchoAuthPayload: JWTClaimsCodable { + + struct Wrapper: JWTWrapper { + let jwtString: String + } + + struct Claims: JWTEncodable { + let iss: String + let sub: String + let aud: String + let iat: Int64 + let exp: Int64 + } + + let subject: String + let audience: String + + init(subject: String, audience: String) { + self.subject = subject + self.audience = audience + } + + init(claims: Claims) throws { + self.subject = claims.sub + self.audience = claims.aud + } + + func encode(iss: String) throws -> Claims { + return Claims( + iss: iss, + sub: subject, + aud: audience, + iat: defaultIat(), + exp: expiry(days: 1) + ) + } +} diff --git a/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift b/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift new file mode 100644 index 000000000..89783ccdf --- /dev/null +++ b/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift @@ -0,0 +1,26 @@ +import Foundation + +class EchoAuthenticator { + private let clientIdStorage: ClientIdStoring + private let echoHost: String + + init(clientIdStorage: ClientIdStoring, echoHost: String) { + self.clientIdStorage = clientIdStorage + self.echoHost = echoHost + } + + func createAuthToken() throws -> String { + let keyPair = try clientIdStorage.getOrCreateKeyPair() + let payload = EchoAuthPayload(subject: getSubject(), audience: getAudience()) + return try payload.signAndCreateWrapper(keyPair: keyPair).jwtString + } + + private func getAudience() -> String { + return "https://\(echoHost)" + } + + private func getSubject() -> String { + return Data.randomBytes(count: 32).toHexString() + } +} + diff --git a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift index 9a3bbb6d5..2ec548eaa 100644 --- a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift +++ b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift @@ -1,5 +1,6 @@ import Foundation import WalletConnectNetworking +import WalletConnectJWT actor EchoRegisterService { private let httpClient: HTTPClient @@ -55,3 +56,4 @@ actor EchoRegisterService { } #endif } + diff --git a/Sources/WalletConnectEcho/Register/EchoService.swift b/Sources/WalletConnectEcho/Register/EchoService.swift index 998c81c6c..460fb8e65 100644 --- a/Sources/WalletConnectEcho/Register/EchoService.swift +++ b/Sources/WalletConnectEcho/Register/EchoService.swift @@ -44,3 +44,4 @@ enum EchoAPI: HTTPService { return "https" } } + diff --git a/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift b/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift index 4dd110000..d09deb12b 100644 --- a/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift +++ b/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift @@ -1,11 +1,11 @@ import Foundation -protocol ClientIdStoring { +public protocol ClientIdStoring { func getOrCreateKeyPair() throws -> SigningPrivateKey func getClientId() throws -> String } -struct ClientIdStorage: ClientIdStoring { +public struct ClientIdStorage: ClientIdStoring { private let key = "com.walletconnect.iridium.client_id" private let keychain: KeychainStorageProtocol @@ -13,7 +13,7 @@ struct ClientIdStorage: ClientIdStoring { self.keychain = keychain } - func getOrCreateKeyPair() throws -> SigningPrivateKey { + public func getOrCreateKeyPair() throws -> SigningPrivateKey { do { return try keychain.read(key: key) } catch { @@ -23,7 +23,7 @@ struct ClientIdStorage: ClientIdStoring { } } - func getClientId() throws -> String { + public func getClientId() throws -> String { let privateKey: SigningPrivateKey = try keychain.read(key: key) let pubKey = privateKey.publicKey.rawRepresentation return DIDKey(rawData: pubKey).did(prefix: true, variant: .ED25519) From cf3b819718099cc3d7850ed9b1f062c99639982e Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 27 Feb 2023 14:00:46 -0700 Subject: [PATCH 06/55] savepoint --- Sources/WalletConnectEcho/Register/EchoAuthenticator.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift b/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift index 89783ccdf..b25d202a3 100644 --- a/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift +++ b/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift @@ -1,4 +1,5 @@ import Foundation +import WalletConnectNetworking class EchoAuthenticator { private let clientIdStorage: ClientIdStoring From fa926dbc95ca9845902ce5d11d73e08ca211c0e0 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Fri, 3 Mar 2023 09:57:56 -0700 Subject: [PATCH 07/55] savepoint --- .../Wallet/Welcome/WelcomePresenter.swift | 4 ++++ .../Register/EchoAuthPayload.swift | 1 + .../Register/EchoRegisterService.swift | 5 +++++ .../{EcoResponse.swift => EchoResponse.swift} | 0 .../Register/EchoService.swift | 19 ++++++++++++++----- .../HTTPClient/HTTPService.swift | 5 +++++ 6 files changed, 29 insertions(+), 5 deletions(-) rename Sources/WalletConnectEcho/Register/{EcoResponse.swift => EchoResponse.swift} (100%) diff --git a/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomePresenter.swift b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomePresenter.swift index 31381569c..136dc41da 100644 --- a/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomePresenter.swift +++ b/Example/WalletApp/PresentationLayer/Wallet/Welcome/WelcomePresenter.swift @@ -1,4 +1,5 @@ import UIKit +import WalletConnectNetworking import Combine final class WelcomePresenter: ObservableObject { @@ -15,6 +16,9 @@ final class WelcomePresenter: ObservableObject { } func onGetStarted() { + let pasteboard = UIPasteboard.general + let clientId = try? Networking.interactor.getClientId() + pasteboard.string = clientId router.presentWallet() } } diff --git a/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift b/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift index 86bf08b8e..03e112baf 100644 --- a/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift +++ b/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift @@ -1,4 +1,5 @@ import Foundation +import WalletConnectJWT struct EchoAuthPayload: JWTClaimsCodable { diff --git a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift index 2ec548eaa..bc0f0ecea 100644 --- a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift +++ b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift @@ -8,6 +8,7 @@ actor EchoRegisterService { private let clientId: String private let logger: ConsoleLogging private let environment: APNSEnvironment + private let echoAuthenticator: EchoAuthenticator // DID method specific identifier private var clientIdMutlibase: String { return clientId.replacingOccurrences(of: "did:key:", with: "") @@ -20,10 +21,12 @@ actor EchoRegisterService { init(httpClient: HTTPClient, projectId: String, clientId: String, + echoAuthenticator: EchoAuthenticator, logger: ConsoleLogging, environment: APNSEnvironment) { self.httpClient = httpClient self.clientId = clientId + self.echoAuthenticator = echoAuthenticator self.projectId = projectId self.logger = logger self.environment = environment @@ -32,6 +35,7 @@ actor EchoRegisterService { func register(deviceToken: Data) async throws { let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) } let token = tokenParts.joined() + let echoAuthToken = try echoAuthenticator.createAuthToken() logger.debug("APNS device token: \(token)") let response = try await httpClient.request( EchoResponse.self, @@ -45,6 +49,7 @@ actor EchoRegisterService { #if DEBUG public func register(deviceToken: String) async throws { + let echoAuthToken = try echoAuthenticator.createAuthToken() let response = try await httpClient.request( EchoResponse.self, at: EchoAPI.register(clientId: clientIdMutlibase, token: deviceToken, projectId: projectId, environment: environment) diff --git a/Sources/WalletConnectEcho/Register/EcoResponse.swift b/Sources/WalletConnectEcho/Register/EchoResponse.swift similarity index 100% rename from Sources/WalletConnectEcho/Register/EcoResponse.swift rename to Sources/WalletConnectEcho/Register/EchoResponse.swift diff --git a/Sources/WalletConnectEcho/Register/EchoService.swift b/Sources/WalletConnectEcho/Register/EchoService.swift index 460fb8e65..fe2b0180f 100644 --- a/Sources/WalletConnectEcho/Register/EchoService.swift +++ b/Sources/WalletConnectEcho/Register/EchoService.swift @@ -2,14 +2,14 @@ import Foundation import WalletConnectNetworking enum EchoAPI: HTTPService { - case register(clientId: String, token: String, projectId: String, environment: APNSEnvironment) - case unregister(clientId: String, projectId: String) + case register(clientId: String, token: String, projectId: String, environment: APNSEnvironment, auth: String) + case unregister(clientId: String, projectId: String, auth: String) var path: String { switch self { - case .register(_, _, let projectId, _): + case .register(_, _, let projectId, _, _): return "/\(projectId)/clients" - case .unregister(let clientId, let projectId): + case .unregister(let clientId, let projectId, _): return "/\(projectId)/clients\(clientId)" } } @@ -25,7 +25,7 @@ enum EchoAPI: HTTPService { var body: Data? { switch self { - case .register(let clientId, let token, _, let environment): + case .register(let clientId, let token, _, let environment, _): return try? JSONEncoder().encode([ "client_id": clientId, "type": environment.rawValue, @@ -43,5 +43,14 @@ enum EchoAPI: HTTPService { var scheme: String { return "https" } + + var headerFields: [String : String]? { + switch { + case .register(_, _, _, _, let auth): + + case .unregister(_, _, let auth): + } + } + } diff --git a/Sources/WalletConnectNetworking/HTTPClient/HTTPService.swift b/Sources/WalletConnectNetworking/HTTPClient/HTTPService.swift index 1a1a75b62..4c9c86eb4 100644 --- a/Sources/WalletConnectNetworking/HTTPClient/HTTPService.swift +++ b/Sources/WalletConnectNetworking/HTTPClient/HTTPService.swift @@ -12,6 +12,7 @@ public protocol HTTPService { var method: HTTPMethod { get } var body: Data? { get } var queryParameters: [String: String]? { get } + var headerFields: [String: String]? { get } func resolve(for host: String) -> URLRequest? } @@ -34,6 +35,10 @@ public extension HTTPService { } var request = URLRequest(url: url) request.httpMethod = method.rawValue + headerFields?.forEach { + request.addValue($0.value, forHTTPHeaderField: $0.key) + } + request.httpBody = body request.addValue("application/json", forHTTPHeaderField: "Content-Type") return request From c143ea6b97032baff9fc40f635d13397184e663c Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Wed, 8 Mar 2023 14:09:03 +0100 Subject: [PATCH 08/55] update echo auth --- .../WalletConnectEcho/EchoClientFactory.swift | 15 +++++++++++++-- .../Register/EchoAuthPayload.swift | 16 ++++++++-------- .../Register/EchoRegisterService.swift | 8 ++++---- .../WalletConnectEcho/Register/EchoService.swift | 5 +++-- .../ClientAuth/ClientIdStorage.swift | 2 +- Sources/WalletConnectRelay/RelayClient.swift | 2 +- .../RelayStorageIndentifiers.swift | 5 +++++ 7 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 Sources/WalletConnectRelay/RelayStorageIndentifiers.swift diff --git a/Sources/WalletConnectEcho/EchoClientFactory.swift b/Sources/WalletConnectEcho/EchoClientFactory.swift index b8beb2c87..92c0449d4 100644 --- a/Sources/WalletConnectEcho/EchoClientFactory.swift +++ b/Sources/WalletConnectEcho/EchoClientFactory.swift @@ -2,24 +2,35 @@ import Foundation import WalletConnectNetworking public struct EchoClientFactory { - public static func create(projectId: String, clientId: String, echoHost: String, environment: APNSEnvironment) -> EchoClient { + public static func create(projectId: String, + clientId: String, + echoHost: String, + keychainStorage: KeychainStorageProtocol = KeychainStorage(serviceIdentifier: RelayStorageIndentifiers.keychain), + environment: APNSEnvironment) -> EchoClient { let httpClient = HTTPNetworkClient(host: echoHost) + let clientIdStorage = ClientIdStorage(keychain: keychainStorage) + + let echoAuthenticator = IrnClientAuthenticator(clientIdStorage: clientIdStorage, echoHost: echoHost) + return EchoClientFactory.create( projectId: projectId, clientId: clientId, httpClient: httpClient, + echoAuthenticator: echoAuthenticator, environment: environment) } static func create(projectId: String, clientId: String, httpClient: HTTPClient, + echoAuthenticator: IrnClientAuthenticator, environment: APNSEnvironment) -> EchoClient { let logger = ConsoleLogger(loggingLevel: .debug) - let registerService = EchoRegisterService(httpClient: httpClient, projectId: projectId, clientId: clientId, logger: logger, environment: environment) + + let registerService = EchoRegisterService(httpClient: httpClient, projectId: projectId, clientId: clientId, echoAuthenticator: echoAuthenticator, logger: logger, environment: environment) return EchoClient( registerService: registerService) diff --git a/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift b/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift index 03e112baf..c3867c3da 100644 --- a/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift +++ b/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift @@ -3,16 +3,16 @@ import WalletConnectJWT struct EchoAuthPayload: JWTClaimsCodable { - struct Wrapper: JWTWrapper { - let jwtString: String - } - - struct Claims: JWTEncodable { + struct Claims: JWTClaims { let iss: String let sub: String let aud: String - let iat: Int64 - let exp: Int64 + let iat: UInt64 + let exp: UInt64 + } + + struct Wrapper: JWTWrapper { + let jwtString: String } let subject: String @@ -33,7 +33,7 @@ struct EchoAuthPayload: JWTClaimsCodable { iss: iss, sub: subject, aud: audience, - iat: defaultIat(), + iat: defaultIatMilliseconds(), exp: expiry(days: 1) ) } diff --git a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift index bc0f0ecea..c5b61ac14 100644 --- a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift +++ b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift @@ -8,7 +8,7 @@ actor EchoRegisterService { private let clientId: String private let logger: ConsoleLogging private let environment: APNSEnvironment - private let echoAuthenticator: EchoAuthenticator + private let echoAuthenticator: IrnClientAuthenticator // DID method specific identifier private var clientIdMutlibase: String { return clientId.replacingOccurrences(of: "did:key:", with: "") @@ -21,7 +21,7 @@ actor EchoRegisterService { init(httpClient: HTTPClient, projectId: String, clientId: String, - echoAuthenticator: EchoAuthenticator, + echoAuthenticator: IrnClientAuthenticator, logger: ConsoleLogging, environment: APNSEnvironment) { self.httpClient = httpClient @@ -39,7 +39,7 @@ actor EchoRegisterService { logger.debug("APNS device token: \(token)") let response = try await httpClient.request( EchoResponse.self, - at: EchoAPI.register(clientId: clientIdMutlibase, token: token, projectId: projectId, environment: environment) + at: EchoAPI.register(clientId: clientIdMutlibase, token: token, projectId: projectId, environment: environment, auth: echoAuthToken) ) guard response.status == .success else { throw Errors.registrationFailed @@ -52,7 +52,7 @@ actor EchoRegisterService { let echoAuthToken = try echoAuthenticator.createAuthToken() let response = try await httpClient.request( EchoResponse.self, - at: EchoAPI.register(clientId: clientIdMutlibase, token: deviceToken, projectId: projectId, environment: environment) + at: EchoAPI.register(clientId: clientIdMutlibase, token: deviceToken, projectId: projectId, environment: environment, auth: echoAuthToken) ) guard response.status == .success else { throw Errors.registrationFailed diff --git a/Sources/WalletConnectEcho/Register/EchoService.swift b/Sources/WalletConnectEcho/Register/EchoService.swift index fe2b0180f..23b8ff48e 100644 --- a/Sources/WalletConnectEcho/Register/EchoService.swift +++ b/Sources/WalletConnectEcho/Register/EchoService.swift @@ -45,10 +45,11 @@ enum EchoAPI: HTTPService { } var headerFields: [String : String]? { - switch { + switch self { case .register(_, _, _, _, let auth): - + return ["auth": auth] case .unregister(_, _, let auth): + return ["auth": auth] } } diff --git a/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift b/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift index d09deb12b..b2c1f6014 100644 --- a/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift +++ b/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift @@ -9,7 +9,7 @@ public struct ClientIdStorage: ClientIdStoring { private let key = "com.walletconnect.iridium.client_id" private let keychain: KeychainStorageProtocol - init(keychain: KeychainStorageProtocol) { + public init(keychain: KeychainStorageProtocol) { self.keychain = keychain } diff --git a/Sources/WalletConnectRelay/RelayClient.swift b/Sources/WalletConnectRelay/RelayClient.swift index b762450e4..b27bdca89 100644 --- a/Sources/WalletConnectRelay/RelayClient.swift +++ b/Sources/WalletConnectRelay/RelayClient.swift @@ -74,7 +74,7 @@ public final class RelayClient { relayHost: String, projectId: String, keyValueStorage: KeyValueStorage = UserDefaults.standard, - keychainStorage: KeychainStorageProtocol = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk"), + keychainStorage: KeychainStorageProtocol = KeychainStorage(serviceIdentifier: RelayStorageIndentifiers.keychain), socketFactory: WebSocketFactory, socketConnectionType: SocketConnectionType = .automatic, logger: ConsoleLogging = ConsoleLogger(loggingLevel: .off) diff --git a/Sources/WalletConnectRelay/RelayStorageIndentifiers.swift b/Sources/WalletConnectRelay/RelayStorageIndentifiers.swift new file mode 100644 index 000000000..f9558c79e --- /dev/null +++ b/Sources/WalletConnectRelay/RelayStorageIndentifiers.swift @@ -0,0 +1,5 @@ +import Foundation + +public enum RelayStorageIndentifiers { + public static let keychain = "com.walletconnect.sdk" +} From 055f92772306f65a174e9283a50d84c87084b2f5 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Thu, 9 Mar 2023 09:43:23 +0100 Subject: [PATCH 09/55] rename irn client, fix build issues --- Sources/WalletConnectEcho/EchoClientFactory.swift | 4 ++-- Sources/WalletConnectEcho/Register/EchoRegisterService.swift | 4 ++-- Sources/WalletConnectIdentity/IdentityKeyAPI.swift | 4 ++++ .../Signer/Ethereum/EIP1271/RPCService.swift | 5 +++++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Sources/WalletConnectEcho/EchoClientFactory.swift b/Sources/WalletConnectEcho/EchoClientFactory.swift index 92c0449d4..b0e026407 100644 --- a/Sources/WalletConnectEcho/EchoClientFactory.swift +++ b/Sources/WalletConnectEcho/EchoClientFactory.swift @@ -12,7 +12,7 @@ public struct EchoClientFactory { let clientIdStorage = ClientIdStorage(keychain: keychainStorage) - let echoAuthenticator = IrnClientAuthenticator(clientIdStorage: clientIdStorage, echoHost: echoHost) + let echoAuthenticator = EchoAuthenticator(clientIdStorage: clientIdStorage, echoHost: echoHost) return EchoClientFactory.create( projectId: projectId, @@ -25,7 +25,7 @@ public struct EchoClientFactory { static func create(projectId: String, clientId: String, httpClient: HTTPClient, - echoAuthenticator: IrnClientAuthenticator, + echoAuthenticator: EchoAuthenticator, environment: APNSEnvironment) -> EchoClient { let logger = ConsoleLogger(loggingLevel: .debug) diff --git a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift index c5b61ac14..e280d40ba 100644 --- a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift +++ b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift @@ -8,7 +8,7 @@ actor EchoRegisterService { private let clientId: String private let logger: ConsoleLogging private let environment: APNSEnvironment - private let echoAuthenticator: IrnClientAuthenticator + private let echoAuthenticator: EchoAuthenticator // DID method specific identifier private var clientIdMutlibase: String { return clientId.replacingOccurrences(of: "did:key:", with: "") @@ -21,7 +21,7 @@ actor EchoRegisterService { init(httpClient: HTTPClient, projectId: String, clientId: String, - echoAuthenticator: IrnClientAuthenticator, + echoAuthenticator: EchoAuthenticator, logger: ConsoleLogging, environment: APNSEnvironment) { self.httpClient = httpClient diff --git a/Sources/WalletConnectIdentity/IdentityKeyAPI.swift b/Sources/WalletConnectIdentity/IdentityKeyAPI.swift index 1346d40ac..7ca4d2777 100644 --- a/Sources/WalletConnectIdentity/IdentityKeyAPI.swift +++ b/Sources/WalletConnectIdentity/IdentityKeyAPI.swift @@ -50,6 +50,10 @@ enum IdentityKeyAPI: HTTPService { return nil } } + + var headerFields: [String : String]? { + return nil + } } private extension IdentityKeyAPI { diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/RPCService.swift b/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/RPCService.swift index be1ec2414..affda4701 100644 --- a/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/RPCService.swift +++ b/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/RPCService.swift @@ -27,4 +27,9 @@ struct RPCService: HTTPService { "projectId": projectId ] } + + var headerFields: [String : String]? { + return nil + } + } From b8c32fad5aedd32c1d35e5c05076473f5df2b6bd Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Thu, 9 Mar 2023 10:37:28 +0100 Subject: [PATCH 10/55] update echo factory --- Sources/WalletConnectEcho/EchoClientFactory.swift | 5 +++-- Sources/WalletConnectEcho/Register/EchoAuthenticator.swift | 6 +++++- .../WalletConnectEcho/Register/EchoRegisterService.swift | 4 ++-- Sources/WalletConnectRelay/RelayClient.swift | 2 +- Sources/WalletConnectRelay/RelayStorageIndentifiers.swift | 5 ----- 5 files changed, 11 insertions(+), 11 deletions(-) delete mode 100644 Sources/WalletConnectRelay/RelayStorageIndentifiers.swift diff --git a/Sources/WalletConnectEcho/EchoClientFactory.swift b/Sources/WalletConnectEcho/EchoClientFactory.swift index b0e026407..53c0f1081 100644 --- a/Sources/WalletConnectEcho/EchoClientFactory.swift +++ b/Sources/WalletConnectEcho/EchoClientFactory.swift @@ -5,11 +5,12 @@ public struct EchoClientFactory { public static func create(projectId: String, clientId: String, echoHost: String, - keychainStorage: KeychainStorageProtocol = KeychainStorage(serviceIdentifier: RelayStorageIndentifiers.keychain), environment: APNSEnvironment) -> EchoClient { let httpClient = HTTPNetworkClient(host: echoHost) + let keychainStorage = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk") + let clientIdStorage = ClientIdStorage(keychain: keychainStorage) let echoAuthenticator = EchoAuthenticator(clientIdStorage: clientIdStorage, echoHost: echoHost) @@ -25,7 +26,7 @@ public struct EchoClientFactory { static func create(projectId: String, clientId: String, httpClient: HTTPClient, - echoAuthenticator: EchoAuthenticator, + echoAuthenticator: EchoAuthenticating, environment: APNSEnvironment) -> EchoClient { let logger = ConsoleLogger(loggingLevel: .debug) diff --git a/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift b/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift index b25d202a3..892ada61b 100644 --- a/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift +++ b/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift @@ -1,7 +1,11 @@ import Foundation import WalletConnectNetworking -class EchoAuthenticator { +protocol EchoAuthenticating { + func createAuthToken() throws -> String +} + +class EchoAuthenticator: EchoAuthenticating { private let clientIdStorage: ClientIdStoring private let echoHost: String diff --git a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift index e280d40ba..4076cc80a 100644 --- a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift +++ b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift @@ -8,7 +8,7 @@ actor EchoRegisterService { private let clientId: String private let logger: ConsoleLogging private let environment: APNSEnvironment - private let echoAuthenticator: EchoAuthenticator + private let echoAuthenticator: EchoAuthenticating // DID method specific identifier private var clientIdMutlibase: String { return clientId.replacingOccurrences(of: "did:key:", with: "") @@ -21,7 +21,7 @@ actor EchoRegisterService { init(httpClient: HTTPClient, projectId: String, clientId: String, - echoAuthenticator: EchoAuthenticator, + echoAuthenticator: EchoAuthenticating, logger: ConsoleLogging, environment: APNSEnvironment) { self.httpClient = httpClient diff --git a/Sources/WalletConnectRelay/RelayClient.swift b/Sources/WalletConnectRelay/RelayClient.swift index b27bdca89..b762450e4 100644 --- a/Sources/WalletConnectRelay/RelayClient.swift +++ b/Sources/WalletConnectRelay/RelayClient.swift @@ -74,7 +74,7 @@ public final class RelayClient { relayHost: String, projectId: String, keyValueStorage: KeyValueStorage = UserDefaults.standard, - keychainStorage: KeychainStorageProtocol = KeychainStorage(serviceIdentifier: RelayStorageIndentifiers.keychain), + keychainStorage: KeychainStorageProtocol = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk"), socketFactory: WebSocketFactory, socketConnectionType: SocketConnectionType = .automatic, logger: ConsoleLogging = ConsoleLogger(loggingLevel: .off) diff --git a/Sources/WalletConnectRelay/RelayStorageIndentifiers.swift b/Sources/WalletConnectRelay/RelayStorageIndentifiers.swift deleted file mode 100644 index f9558c79e..000000000 --- a/Sources/WalletConnectRelay/RelayStorageIndentifiers.swift +++ /dev/null @@ -1,5 +0,0 @@ -import Foundation - -public enum RelayStorageIndentifiers { - public static let keychain = "com.walletconnect.sdk" -} From fa71a6dc8a414715425ff76bda34c7530e6241ee Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Fri, 10 Mar 2023 20:24:11 +0500 Subject: [PATCH 11/55] Sent Invites --- Example/ExampleApp.xcodeproj/project.pbxproj | 4 ++ .../DomainLayer/Chat/ChatService.swift | 4 ++ .../Chat/ChatList/ChatListInteractor.swift | 10 ++- .../Chat/ChatList/ChatListPresenter.swift | 34 ++++++++--- .../Chat/ChatList/ChatListRouter.swift | 8 ++- .../Chat/ChatList/ChatListView.swift | 61 +++++++++++++------ .../InviteList/InviteListInteractor.swift | 10 ++- .../Chat/InviteList/InviteListModule.swift | 4 +- .../Chat/InviteList/InviteListPresenter.swift | 38 ++++++++++-- .../Chat/InviteList/Models/InviteType.swift | 15 +++++ .../InviteList/Models/InviteViewModel.swift | 49 +++++++-------- 11 files changed, 171 insertions(+), 66 deletions(-) create mode 100644 Example/Showcase/Classes/PresentationLayer/Chat/InviteList/Models/InviteType.swift diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 8cccc1637..da2e34869 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -205,6 +205,7 @@ A5C20229287EB34C007E3188 /* AccountStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5C20228287EB34C007E3188 /* AccountStorage.swift */; }; A5C2022B287EB89A007E3188 /* WelcomeInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5C2022A287EB89A007E3188 /* WelcomeInteractor.swift */; }; A5C4DD8728A2DE88006A626D /* WalletConnectRouter in Frameworks */ = {isa = PBXBuildFile; productRef = A5C4DD8628A2DE88006A626D /* WalletConnectRouter */; }; + A5C5153329BB7A6A004210BA /* InviteType.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5C5153229BB7A6A004210BA /* InviteType.swift */; }; A5C8BE85292FE20B006CC85C /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = A5C8BE84292FE20B006CC85C /* Web3 */; }; A5D85226286333D500DAF5C3 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = A5D85225286333D500DAF5C3 /* Starscream */; }; A5D85228286333E300DAF5C3 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = A5D85227286333E300DAF5C3 /* Starscream */; }; @@ -544,6 +545,7 @@ A5C20222287EA7E2007E3188 /* BrandButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrandButton.swift; sourceTree = ""; }; A5C20228287EB34C007E3188 /* AccountStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountStorage.swift; sourceTree = ""; }; A5C2022A287EB89A007E3188 /* WelcomeInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeInteractor.swift; sourceTree = ""; }; + A5C5153229BB7A6A004210BA /* InviteType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteType.swift; sourceTree = ""; }; A5E03DED286464DB00888481 /* IntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; A5E03DF9286465C700888481 /* SignClientTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignClientTests.swift; sourceTree = ""; }; A5E03DFC286465D100888481 /* Stubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stubs.swift; sourceTree = ""; }; @@ -1135,6 +1137,7 @@ isa = PBXGroup; children = ( A5629AE728772A0100094373 /* InviteViewModel.swift */, + A5C5153229BB7A6A004210BA /* InviteType.swift */, ); path = Models; sourceTree = ""; @@ -2259,6 +2262,7 @@ A58E7CED28729F550082D443 /* SceneDelegate.swift in Sources */, A5C2020F287D9DEE007E3188 /* WelcomeView.swift in Sources */, A518A98929683FB60035247E /* Web3InboxRouter.swift in Sources */, + A5C5153329BB7A6A004210BA /* InviteType.swift in Sources */, A5C2020D287D9DEE007E3188 /* WelcomeRouter.swift in Sources */, A578FA372873D8EE00AA7720 /* UIColor.swift in Sources */, A518A98729683FB60035247E /* Web3InboxViewController.swift in Sources */, diff --git a/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift b/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift index ca1843015..a8fce70a2 100644 --- a/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift +++ b/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift @@ -70,6 +70,10 @@ final class ChatService { client.getReceivedInvites() } + func getSentInvites() -> [SentInvite] { + client.getSentInvites() + } + func sendMessage(topic: String, message: String) async throws { try await client.message(topic: topic, message: message) } diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListInteractor.swift b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListInteractor.swift index 20eee450e..4ff6ef004 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListInteractor.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListInteractor.swift @@ -18,14 +18,22 @@ final class ChatListInteractor { return chatService.threadPublisher } - func getInvites() -> [ReceivedInvite] { + func getReceivedInvites() -> [ReceivedInvite] { return chatService.getReceivedInvites() } + func getSentInvites() -> [SentInvite] { + return chatService.getSentInvites() + } + func receivedInvitesSubscription() -> Stream<[ReceivedInvite]> { return chatService.receivedInvitePublisher } + func sentInvitesSubscription() -> Stream<[SentInvite]> { + return chatService.sentInvitePublisher + } + func logout() async throws { guard let importAccount = accountStorage.importAccount else { return } try await chatService.goPrivate(account: importAccount.account) diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListPresenter.swift b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListPresenter.swift index f643271ab..d2062d732 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListPresenter.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListPresenter.swift @@ -11,6 +11,7 @@ final class ChatListPresenter: ObservableObject { @Published private var threads: [WalletConnectChat.Thread] = [] @Published private var receivedInvites: [ReceivedInvite] = [] + @Published private var sentInvites: [SentInvite] = [] var threadViewModels: [ThreadViewModel] { return threads @@ -18,13 +19,20 @@ final class ChatListPresenter: ObservableObject { .map { ThreadViewModel(thread: $0) } } - var inviteViewModels: [InviteViewModel] { + var receivedInviteViewModels: [InviteViewModel] { return receivedInvites .filter { $0.status == .pending } .sorted(by: { $0.timestamp < $1.timestamp }) .map { InviteViewModel(invite: $0) } } + var sentInviteViewModels: [InviteViewModel] { + return sentInvites + .filter { $0.status == .pending } + .sorted(by: { $0.timestamp < $1.timestamp }) + .map { InviteViewModel(invite: $0) } + } + init(account: Account, interactor: ChatListInteractor, router: ChatListRouter) { defer { setupInitialState() } self.account = account @@ -32,20 +40,24 @@ final class ChatListPresenter: ObservableObject { self.router = router } - var requestsCount: String { - return String(inviteViewModels.count) + var showReceivedInvites: Bool { + return !receivedInviteViewModels.isEmpty } - var showRequests: Bool { - return !inviteViewModels.isEmpty + var showSentInvites: Bool { + return !sentInviteViewModels.isEmpty } func didPressThread(_ thread: ThreadViewModel) { router.presentChat(thread: thread.thread) } - func didPressChatRequests() { - router.presentInviteList(account: account) + func didPressReceivedInvites() { + router.presentReceivedInviteList(account: account) + } + + func didPressSentInvites() { + router.presentSentInviteList(account: account) } @MainActor @@ -86,7 +98,8 @@ private extension ChatListPresenter { func setupInitialState() { threads = interactor.getThreads() - receivedInvites = interactor.getInvites() + receivedInvites = interactor.getReceivedInvites() + sentInvites = interactor.getSentInvites() interactor.threadsSubscription() .sink { [unowned self] threads in @@ -97,6 +110,11 @@ private extension ChatListPresenter { .sink { [unowned self] receivedInvites in self.receivedInvites = receivedInvites }.store(in: &disposeBag) + + interactor.sentInvitesSubscription() + .sink { [unowned self] sentInvites in + self.sentInvites = sentInvites + }.store(in: &disposeBag) } @objc func presentInvite() { diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListRouter.swift b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListRouter.swift index 94210189e..85f613e26 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListRouter.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListRouter.swift @@ -17,8 +17,12 @@ final class ChatListRouter { .present(from: viewController) } - func presentInviteList(account: Account) { - InviteListModule.create(app: app, account: account).push(from: viewController) + func presentReceivedInviteList(account: Account) { + InviteListModule.create(app: app, account: account, type: .received).push(from: viewController) + } + + func presentSentInviteList(account: Account) { + InviteListModule.create(app: app, account: account, type: .sent).push(from: viewController) } func presentChat(thread: WalletConnectChat.Thread) { diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListView.swift b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListView.swift index 94644d90d..3dc52a15f 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListView.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListView.swift @@ -9,29 +9,22 @@ struct ChatListView: View { VStack { ScrollView(showsIndicators: false) { VStack { - if presenter.showRequests { - Button(action: { - presenter.didPressChatRequests() - }) { - HStack(spacing: 8.0) { - Text(presenter.requestsCount) - .frame(width: 24.0, height: 24.0) - .background(Color.w_greenForground) - .foregroundColor(.w_greenBackground) - .font(.system(size: 17.0, weight: .bold)) - .clipShape(Circle()) - - Text("Chat Requests") - .foregroundColor(.w_greenForground) - .font(.system(size: 17.0, weight: .bold)) + HStack { + if presenter.showReceivedInvites { + invitesButton(title: "Received Invites", count: presenter.receivedInviteViewModels.count, textColor: .w_greenForground, backgroundColor: .w_greenBackground) { + presenter.didPressReceivedInvites() } } - .frame(height: 44.0) - .frame(maxWidth: .infinity) - .background(Color.w_greenBackground) - .clipShape(Capsule()) - .padding(16.0) + + if presenter.showSentInvites { + invitesButton(title: "Sent Invites", count: presenter.sentInviteViewModels.count, textColor: .w_foreground, backgroundColor: .w_purpleBackground) { + presenter.didPressSentInvites() + } + } + + Spacer() } + .padding(16.0) if presenter.threadViewModels.isEmpty { Spacer() @@ -54,6 +47,34 @@ struct ChatListView: View { } } + private func invitesButton( + title: String, + count: Int, + textColor: Color, + backgroundColor: Color, + action: @escaping () -> Void + ) -> some View { + Button(action: action) { + HStack(spacing: 8.0) { + Text(String(count)) + .frame(width: 24.0, height: 24.0) + .background(textColor) + .foregroundColor(backgroundColor) + .font(.system(size: 15.0, weight: .bold)) + .clipShape(Circle()) + + Text(title) + .foregroundColor(textColor) + .font(.system(size: 15.0, weight: .bold)) + } + .padding(.vertical, 8) + .padding(.horizontal, 16) + } + .frame(height: 44.0) + .background(backgroundColor) + .clipShape(Capsule()) + } + private func chatsList() -> some View { ForEach(presenter.threadViewModels) { thread in Button(action: { diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListInteractor.swift b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListInteractor.swift index 59ee20151..f7043f7a1 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListInteractor.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListInteractor.swift @@ -11,10 +11,18 @@ final class InviteListInteractor { return chatService.getReceivedInvites() } - func invitesReceivedSubscription() -> Stream<[ReceivedInvite]> { + func getSentInvites() -> [SentInvite] { + return chatService.getSentInvites() + } + + func receivedInvitesSubscription() -> Stream<[ReceivedInvite]> { return chatService.receivedInvitePublisher } + func sentInvitesSubscription() -> Stream<[SentInvite]> { + return chatService.sentInvitePublisher + } + func accept(invite: ReceivedInvite) async throws { try await chatService.accept(invite: invite) } diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListModule.swift b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListModule.swift index d3a84e12c..91d870eb2 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListModule.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListModule.swift @@ -3,10 +3,10 @@ import SwiftUI final class InviteListModule { @discardableResult - static func create(app: Application, account: Account) -> UIViewController { + static func create(app: Application, account: Account, type: InviteType) -> UIViewController { let router = InviteListRouter(app: app) let interactor = InviteListInteractor(chatService: app.chatService) - let presenter = InviteListPresenter(interactor: interactor, router: router, account: account) + let presenter = InviteListPresenter(interactor: interactor, router: router, account: account, inviteType: type) let view = InviteListView().environmentObject(presenter) let viewController = SceneViewController(viewModel: presenter, content: view) diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListPresenter.swift b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListPresenter.swift index af3eaa08b..ca32fd3ea 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListPresenter.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListPresenter.swift @@ -7,29 +7,49 @@ final class InviteListPresenter: ObservableObject { private let interactor: InviteListInteractor private let router: InviteListRouter private let account: Account + private let inviteType: InviteType private var disposeBag = Set() + var invites: [InviteViewModel] { + switch inviteType { + case .received: + return receivedInviteViewModels + case .sent: + return sentInviteViewModels + } + } + @Published private var receivedInvites: [ReceivedInvite] = [] + @Published private var sentInvites: [SentInvite] = [] - var invites: [InviteViewModel] { + private var receivedInviteViewModels: [InviteViewModel] { return receivedInvites .sorted(by: { $0.timestamp > $1.timestamp }) .map { InviteViewModel(invite: $0) } } - init(interactor: InviteListInteractor, router: InviteListRouter, account: Account) { + private var sentInviteViewModels: [InviteViewModel] { + return sentInvites + .sorted(by: { $0.timestamp > $1.timestamp }) + .map { InviteViewModel(invite: $0) } + } + + init(interactor: InviteListInteractor, router: InviteListRouter, account: Account, inviteType: InviteType) { defer { setupInitialState() } self.interactor = interactor self.router = router self.account = account + self.inviteType = inviteType } func didPressAccept(invite: InviteViewModel) async throws { - try await interactor.accept(invite: invite.invite) + guard let invite = invite.receivedInvite else { return } + try await interactor.accept(invite: invite) } func didPressReject(invite: InviteViewModel) async throws { - try await interactor.reject(invite: invite.invite) + guard let invite = invite.receivedInvite else { return } + try await interactor.reject(invite: invite) } } @@ -38,7 +58,7 @@ final class InviteListPresenter: ObservableObject { extension InviteListPresenter: SceneViewModel { var sceneTitle: String? { - return "Chat Requests" + return inviteType.title } var largeTitleDisplayMode: UINavigationItem.LargeTitleDisplayMode { @@ -52,11 +72,17 @@ private extension InviteListPresenter { func setupInitialState() { receivedInvites = interactor.getReceivedInvites() + sentInvites = interactor.getSentInvites() - interactor.invitesReceivedSubscription() + interactor.receivedInvitesSubscription() .sink { [unowned self] receivedInvites in self.receivedInvites = receivedInvites }.store(in: &disposeBag) + + interactor.sentInvitesSubscription() + .sink { [unowned self] sentInvites in + self.sentInvites = sentInvites + }.store(in: &disposeBag) } @MainActor diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/Models/InviteType.swift b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/Models/InviteType.swift new file mode 100644 index 000000000..1191f5a9e --- /dev/null +++ b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/Models/InviteType.swift @@ -0,0 +1,15 @@ +import Foundation + +enum InviteType { + case received + case sent + + var title: String { + switch self { + case .received: + return "Chat Requests" + case .sent: + return "Sent Invites" + } + } +} diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/Models/InviteViewModel.swift b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/Models/InviteViewModel.swift index 1f290a33d..e91092042 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/Models/InviteViewModel.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/Models/InviteViewModel.swift @@ -2,36 +2,33 @@ import Foundation import WalletConnectChat struct InviteViewModel: Identifiable { - let invite: ReceivedInvite - var id: Int64 { - return invite.id - } - - init(invite: ReceivedInvite) { - self.invite = invite - } + let id: Int64 + let title: String + let subtitle: String + let showActions: Bool + let statusTitle: String - var title: String { - return invite.inviterAccount.address - } - - var subtitle: String { - return invite.message - } + let receivedInvite: ReceivedInvite? + let sentInvite: SentInvite? - var showActions: Bool { - return invite.status == .pending + init(invite: ReceivedInvite) { + self.id = invite.id + self.title = invite.inviterAccount.address + self.subtitle = invite.message + self.showActions = invite.status == .pending + self.statusTitle = invite.status.rawValue.capitalized + self.receivedInvite = invite + self.sentInvite = nil } - var statusTitle: String { - switch invite.status { - case .pending: - return "Pending" - case .approved: - return "Approved" - case .rejected: - return "Rejected" - } + init(invite: SentInvite) { + self.id = invite.id + self.title = invite.inviteeAccount.address + self.subtitle = invite.message + self.showActions = false + self.statusTitle = invite.status.rawValue.capitalized + self.sentInvite = invite + self.receivedInvite = nil } } From b31d834333a6b3a69cd81ac1cbbeb48c6fe6241b Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 13 Mar 2023 17:55:51 +0500 Subject: [PATCH 12/55] ENSResolver --- Example/ExampleApp.xcodeproj/project.pbxproj | 12 ++++ .../Auth/ENS/ENSResolverTests.swift | 14 ++++ .../Signer/ENSResolverFactory.swift | 24 +++++++ .../ContractCall/ContractDecoder.swift | 71 +++++++++++++++++++ .../ContractCall/ContractEncoder.swift | 15 ++++ .../Ethereum/ContractCall/EthCall.swift | 6 ++ .../RPCService.swift | 0 .../Ethereum/EIP1271/EIP1271Verifier.swift | 5 -- .../EIP1271/ValidSignatureMethod.swift | 10 +-- .../Signer/Ethereum/ENS/ENSNameMethod.swift | 11 +++ .../Ethereum/ENS/ENSRegistryContract.swift | 41 +++++++++++ .../Signer/Ethereum/ENS/ENSResolver.swift | 56 +++++++++++++++ .../Ethereum/ENS/ENSResolverContract.swift | 42 +++++++++++ .../Ethereum/ENS/ENSResolverMethod.swift | 11 +++ 14 files changed, 305 insertions(+), 13 deletions(-) create mode 100644 Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift create mode 100644 Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift create mode 100644 Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/ContractDecoder.swift create mode 100644 Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/ContractEncoder.swift create mode 100644 Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/EthCall.swift rename Sources/WalletConnectSigner/Signer/Ethereum/{EIP1271 => ContractCall}/RPCService.swift (100%) create mode 100644 Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSNameMethod.swift create mode 100644 Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSRegistryContract.swift create mode 100644 Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift create mode 100644 Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverContract.swift create mode 100644 Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverMethod.swift diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index da2e34869..1b0cd5522 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -140,6 +140,7 @@ A578FA3D2874002400AA7720 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = A578FA3C2874002400AA7720 /* View.swift */; }; A57E71A6291CF76400325797 /* ETHSigner.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57E71A5291CF76400325797 /* ETHSigner.swift */; }; A57E71A8291CF8A500325797 /* SOLSigner.swift in Sources */ = {isa = PBXBuildFile; fileRef = A57E71A7291CF8A500325797 /* SOLSigner.swift */; }; + A58A1ECC29BF458600A82A20 /* ENSResolverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58A1ECB29BF458600A82A20 /* ENSResolverTests.swift */; }; A58E7CEB28729F550082D443 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58E7CEA28729F550082D443 /* AppDelegate.swift */; }; A58E7CED28729F550082D443 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58E7CEC28729F550082D443 /* SceneDelegate.swift */; }; A58E7CF428729F550082D443 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A58E7CF328729F550082D443 /* Assets.xcassets */; }; @@ -490,6 +491,7 @@ A578FA3C2874002400AA7720 /* View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = ""; }; A57E71A5291CF76400325797 /* ETHSigner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ETHSigner.swift; sourceTree = ""; }; A57E71A7291CF8A500325797 /* SOLSigner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SOLSigner.swift; sourceTree = ""; }; + A58A1ECB29BF458600A82A20 /* ENSResolverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ENSResolverTests.swift; sourceTree = ""; }; A58E7CE828729F550082D443 /* Showcase.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Showcase.app; sourceTree = BUILT_PRODUCTS_DIR; }; A58E7CEA28729F550082D443 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; A58E7CEC28729F550082D443 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -1022,6 +1024,7 @@ 84D2A66728A4F5260088AE09 /* Auth */ = { isa = PBXGroup; children = ( + A58A1ECA29BF457800A82A20 /* ENS */, A54195992934BFDD0035AD19 /* Signer */, 84D2A66528A4F51E0088AE09 /* AuthTests.swift */, ); @@ -1197,6 +1200,14 @@ path = Signer; sourceTree = ""; }; + A58A1ECA29BF457800A82A20 /* ENS */ = { + isa = PBXGroup; + children = ( + A58A1ECB29BF458600A82A20 /* ENSResolverTests.swift */, + ); + path = ENS; + sourceTree = ""; + }; A58E7CE928729F550082D443 /* Showcase */ = { isa = PBXGroup; children = ( @@ -2327,6 +2338,7 @@ 7694A5262874296A0001257E /* RegistryTests.swift in Sources */, A541959F2934BFEF0035AD19 /* SignerTests.swift in Sources */, A50C036528AAD32200FE72D3 /* ClientDelegate.swift in Sources */, + A58A1ECC29BF458600A82A20 /* ENSResolverTests.swift in Sources */, A5E03DFA286465C700888481 /* SignClientTests.swift in Sources */, A54195A02934BFEF0035AD19 /* EIP1271VerifierTests.swift in Sources */, A54195A12934BFEF0035AD19 /* EIP191VerifierTests.swift in Sources */, diff --git a/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift b/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift new file mode 100644 index 000000000..fda62a2a2 --- /dev/null +++ b/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift @@ -0,0 +1,14 @@ +import Foundation +import XCTest +@testable import WalletConnectSigner + +class ENSSignerTests: XCTestCase { + + private let account = Account("eip155:1:0x025d1eAC1467c5be5e38cA411dC2454964B5C666")! + + func testResolveAddress() async throws { + let resolver = ENSResolverFactory(signerFactory: DefaultSignerFactory()).create(projectId: InputConfig.projectId) + let ens = try await resolver.resolve(account: account) + XCTAssertEqual(ens, "web3.eth") + } +} diff --git a/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift b/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift new file mode 100644 index 000000000..04001c877 --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift @@ -0,0 +1,24 @@ +import Foundation + +public final class ENSResolverFactory { + + public let signerFactory: SignerFactory + + public init(signerFactory: SignerFactory) { + self.signerFactory = signerFactory + } + + public func create() -> ENSResolver { + return create(projectId: Networking.projectId) + } + + public func create(projectId: String) -> ENSResolver { + return ENSResolver( + // [Default ENS registry address](https://docs.ens.domains/ens-deployments) + resolverAddress: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", + projectId: projectId, + httpClient: HTTPNetworkClient(host: "rpc.walletconnect.com"), + signer: signerFactory.createEthereumSigner() + ) + } +} diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/ContractDecoder.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/ContractDecoder.swift new file mode 100644 index 000000000..ac69987db --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/ContractDecoder.swift @@ -0,0 +1,71 @@ +import Foundation + +struct ContractDecoder { + + static func address(_ result: String, offset: String.Index? = nil) throws -> (String, String.Index) { + guard let (s, end) = extractHexFragment(result, start: offset ?? index0x(result)) else { + throw Errors.invalidAddress + } + let hex = s.suffix(from: s.index(s.startIndex, offsetBy: 24)) + return ("0x" + hex, end) + } + + static func int(_ result: String, offset: String.Index? = nil) throws -> (Int, String.Index) { + guard let (s, end) = extractHexFragment(result, start: offset ?? index0x(result)) else { + throw Errors.invalidInt + } + return (Int(s, radix: 16)!, end) + } + + static func string(_ result: String, at: Int) throws -> String { + let data = try dynamicBytes(result, at: at) + guard let string = String(data: data, encoding: .utf8) else { + throw Errors.invalidString + } + return string + } + + static func dynamicBytes(_ result: String, at: Int) throws -> Data { + guard + let i = index0x(result), + let lengthStart = result.index(i, offsetBy: at * 2, limitedBy: result.endIndex), + let (length, start) = try? ContractDecoder.int(result, offset: lengthStart), + let end = result.index(start, offsetBy: length * 2, limitedBy: result.endIndex) + else { throw Errors.invalidDynamicBytes } + + let s = result[start.. String.Index? { + if s.starts(with: "0x") { + return s.index(s.startIndex, offsetBy: 2) + } + return nil + } + + static func extractHexFragment(_ s: String, start _start: String.Index? = nil) -> (String, String.Index)? { + let start: String.Index + if let i = _start { + start = i + } else if let i = index0x(s) { + start = i + } else { + return nil + } + if let end = s.index(start, offsetBy: 64, limitedBy: s.endIndex) { + return (String(s[start.. String { + let padding = 32 - bytes.count + return bytes.toHexString() + String(repeating: "0", count: padding * 2) + } + + static func leadingZeros(for value: String, end: Bool) -> String { + let count = max(0, value.count % 32 - 2) + let padding = String(repeating: "0", count: count) + return end ? padding + value : value + padding + } +} diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/EthCall.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/EthCall.swift new file mode 100644 index 000000000..a60770ebd --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/EthCall.swift @@ -0,0 +1,6 @@ +import Foundation + +struct EthCall: Codable { + let to: String + let data: String +} diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/RPCService.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/RPCService.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/RPCService.swift rename to Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/RPCService.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift b/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift index a3b70ae8b..83a23d5c2 100644 --- a/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift +++ b/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift @@ -36,9 +36,4 @@ extension EIP1271Verifier { enum Errors: Error { case invalidSignature } - - struct EthCall: Codable { - let to: String - let data: String - } } diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift b/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift index 134d62427..5410b764c 100644 --- a/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift +++ b/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift @@ -12,17 +12,11 @@ struct ValidSignatureMethod { func encode() -> String { return [ ValidSignatureMethod.methodHash, - leadingZeros(for: messageHash.toHexString(), end: false), + ContractEncoder.leadingZeros(for: messageHash.toHexString(), end: false), ValidSignatureMethod.paddingIndex, ValidSignatureMethod.signatureLength, - leadingZeros(for: signature.toHexString(), end: true), + ContractEncoder.leadingZeros(for: signature.toHexString(), end: true), ValidSignatureMethod.signaturePadding ].joined() } - - private func leadingZeros(for value: String, end: Bool) -> String { - let count = max(0, value.count % 32 - 2) - let padding = String(repeating: "0", count: count) - return end ? padding + value : value + padding - } } diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSNameMethod.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSNameMethod.swift new file mode 100644 index 000000000..238ec69e3 --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSNameMethod.swift @@ -0,0 +1,11 @@ +import Foundation + +struct ENSNameMethod { + static let methodHash = "0x691f3431" + + let namehash: Data + + func encode() -> String { + return [ENSNameMethod.methodHash, ContractEncoder.bytes(namehash)].joined() + } +} diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSRegistryContract.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSRegistryContract.swift new file mode 100644 index 000000000..2ea5e3156 --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSRegistryContract.swift @@ -0,0 +1,41 @@ +import Foundation + +actor ENSRegistryContract { + + private let address: String + private let projectId: String + private let chainId: String + private let httpClient: HTTPClient + + init(address: String, projectId: String, chainId: String, httpClient: HTTPClient) { + self.address = address + self.projectId = projectId + self.chainId = chainId + self.httpClient = httpClient + } + + func resolver(namehash: Data) async throws -> String { + let encoder = ENSResolverMethod(namehash: namehash) + let call = EthCall(to: address, data: encoder.encode()) + let params = AnyCodable([AnyCodable(call), AnyCodable("latest")]) + let request = RPCRequest(method: "eth_call", params: params) + let data = try JSONEncoder().encode(request) + let httpService = RPCService(data: data, projectId: projectId, chainId: chainId) + let response = try await httpClient.request(RPCResponse.self, at: httpService) + return try validateResponse(response) + } +} + +private extension ENSRegistryContract { + + enum Errors: Error { + case invalidResponse + } + + func validateResponse(_ response: RPCResponse) throws -> String { + guard let result = try response.result?.get(String.self) + else { throw Errors.invalidResponse } + + return try ContractDecoder.address(result).0 + } +} diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift new file mode 100644 index 000000000..5050d56e2 --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift @@ -0,0 +1,56 @@ +import Foundation + +public actor ENSResolver { + + private let resolverAddress: String + private let projectId: String + private let httpClient: HTTPClient + private let signer: EthereumSigner + + init(resolverAddress: String, projectId: String, httpClient: HTTPClient, signer: EthereumSigner) { + self.resolverAddress = resolverAddress + self.projectId = projectId + self.httpClient = httpClient + self.signer = signer + } + + public func resolve(account: Account) async throws -> String { + let registry = ENSRegistryContract( + address: resolverAddress, + projectId: projectId, + chainId: account.blockchainIdentifier, + httpClient: httpClient + ) + let reversedDomain = account.address.lowercased() + .replacingOccurrences(of: "0x", with: "") + ".addr.reverse" + let namehash = namehash(reversedDomain) + let resolverAddaress = try await registry.resolver(namehash: namehash) + let resolver = ENSResolverContract( + address: resolverAddaress, + projectId: projectId, + chainId: account.blockchainIdentifier, + httpClient: httpClient + ) + return try await resolver.name(namehash: namehash) + } +} + +private extension ENSResolver { + + func namehash(_ name: String) -> Data { + var result = [UInt8](repeating: 0, count: 32) + let labels = name.split(separator: ".") + for label in labels.reversed() { + let labelHash = signer.keccak256(normalizeLabel(label).rawRepresentation) + result.append(contentsOf: labelHash) + result = [UInt8](signer.keccak256(Data(result))) + } + return Data(result) + } + + func normalizeLabel(_ label: S) -> String { + // NOTE: this is NOT a [EIP-137](https://eips.ethereum.org/EIPS/eip-137) compliant implementation + // TODO: properly implement domain name encoding via [UTS #46](https://unicode.org/reports/tr46/) + return label.lowercased() + } +} diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverContract.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverContract.swift new file mode 100644 index 000000000..3b2a66652 --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverContract.swift @@ -0,0 +1,42 @@ +import Foundation + +actor ENSResolverContract { + + private let address: String + private let projectId: String + private let chainId: String + private let httpClient: HTTPClient + + init(address: String, projectId: String, chainId: String, httpClient: HTTPClient) { + self.address = address + self.projectId = projectId + self.chainId = chainId + self.httpClient = httpClient + } + + func name(namehash: Data) async throws -> String { + let encoder = ENSNameMethod(namehash: namehash) + let call = EthCall(to: address, data: encoder.encode()) + let params = AnyCodable([AnyCodable(call), AnyCodable("latest")]) + let request = RPCRequest(method: "eth_call", params: params) + let data = try JSONEncoder().encode(request) + let httpService = RPCService(data: data, projectId: projectId, chainId: chainId) + let response = try await httpClient.request(RPCResponse.self, at: httpService) + return try validateResponse(response) + } +} + +private extension ENSResolverContract { + + enum Errors: Error { + case invalidResponse + } + + func validateResponse(_ response: RPCResponse) throws -> String { + guard let result = try response.result?.get(String.self) + else { throw Errors.invalidResponse } + + let (at, _) = try ContractDecoder.int(result) + return try ContractDecoder.string(result, at: at) + } +} diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverMethod.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverMethod.swift new file mode 100644 index 000000000..813d3d18a --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverMethod.swift @@ -0,0 +1,11 @@ +import Foundation + +struct ENSResolverMethod { + static let methodHash = "0x0178b8bf" + + let namehash: Data + + func encode() -> String { + return [ENSResolverMethod.methodHash, ContractEncoder.bytes(namehash)].joined() + } +} From b2446694e16c249660f3b2ce65a598b80f8136b0 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 13 Mar 2023 19:43:28 +0500 Subject: [PATCH 13/55] ENS address resolver --- .../Auth/ENS/ENSResolverTests.swift | 13 +++-- .../Signer/ENSResolverFactory.swift | 11 +++-- .../Ethereum/ENS/ENSAddressMethod.swift | 11 +++++ .../Ethereum/ENS/ENSRegistryContract.swift | 6 +-- .../Signer/Ethereum/ENS/ENSResolver.swift | 47 ++++++++++++------- .../Ethereum/ENS/ENSResolverContract.swift | 40 ++++++++++++---- 6 files changed, 93 insertions(+), 35 deletions(-) create mode 100644 Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSAddressMethod.swift diff --git a/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift b/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift index fda62a2a2..2eb8404b9 100644 --- a/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift +++ b/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift @@ -4,11 +4,18 @@ import XCTest class ENSSignerTests: XCTestCase { - private let account = Account("eip155:1:0x025d1eAC1467c5be5e38cA411dC2454964B5C666")! + private let account = Account("eip155:1:0x025d1eac1467c5be5e38ca411dc2454964b5c666")! + private let ens = "web3.eth" + + func testResolveEns() async throws { + let resolver = ENSResolverFactory(signerFactory: DefaultSignerFactory()).create(projectId: InputConfig.projectId) + let resolved = try await resolver.resolveEns(account: account) + XCTAssertEqual(resolved, ens) + } func testResolveAddress() async throws { let resolver = ENSResolverFactory(signerFactory: DefaultSignerFactory()).create(projectId: InputConfig.projectId) - let ens = try await resolver.resolve(account: account) - XCTAssertEqual(ens, "web3.eth") + let address = try await resolver.resolveAddress(ens: ens, blockchain: account.blockchain) + XCTAssertEqual(address, account.address) } } diff --git a/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift b/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift index 04001c877..3d95cd40d 100644 --- a/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift +++ b/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift @@ -13,11 +13,16 @@ public final class ENSResolverFactory { } public func create(projectId: String) -> ENSResolver { + let httpClient = HTTPNetworkClient(host: "rpc.walletconnect.com") return ENSResolver( - // [Default ENS registry address](https://docs.ens.domains/ens-deployments) - resolverAddress: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", projectId: projectId, - httpClient: HTTPNetworkClient(host: "rpc.walletconnect.com"), + httpClient: httpClient, + registry: ENSRegistryContract( + // [Default ENS registry address](https://docs.ens.domains/ens-deployments) + address: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e", + projectId: projectId, + httpClient: httpClient + ), signer: signerFactory.createEthereumSigner() ) } diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSAddressMethod.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSAddressMethod.swift new file mode 100644 index 000000000..6ccda4e23 --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSAddressMethod.swift @@ -0,0 +1,11 @@ +import Foundation + +struct ENSAddressMethod { + static let methodHash = "0x3b3b57de" + + let namehash: Data + + func encode() -> String { + return [ENSAddressMethod.methodHash, ContractEncoder.bytes(namehash)].joined() + } +} diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSRegistryContract.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSRegistryContract.swift index 2ea5e3156..1e6ba1855 100644 --- a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSRegistryContract.swift +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSRegistryContract.swift @@ -4,17 +4,15 @@ actor ENSRegistryContract { private let address: String private let projectId: String - private let chainId: String private let httpClient: HTTPClient - init(address: String, projectId: String, chainId: String, httpClient: HTTPClient) { + init(address: String, projectId: String, httpClient: HTTPClient) { self.address = address self.projectId = projectId - self.chainId = chainId self.httpClient = httpClient } - func resolver(namehash: Data) async throws -> String { + func resolver(namehash: Data, chainId: String) async throws -> String { let encoder = ENSResolverMethod(namehash: namehash) let call = EthCall(to: address, data: encoder.encode()) let params = AnyCodable([AnyCodable(call), AnyCodable("latest")]) diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift index 5050d56e2..b9ccb3112 100644 --- a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift @@ -2,36 +2,47 @@ import Foundation public actor ENSResolver { - private let resolverAddress: String private let projectId: String private let httpClient: HTTPClient + private let registry: ENSRegistryContract private let signer: EthereumSigner - init(resolverAddress: String, projectId: String, httpClient: HTTPClient, signer: EthereumSigner) { - self.resolverAddress = resolverAddress + init(projectId: String, httpClient: HTTPClient, registry: ENSRegistryContract, signer: EthereumSigner) { self.projectId = projectId self.httpClient = httpClient + self.registry = registry self.signer = signer } - public func resolve(account: Account) async throws -> String { - let registry = ENSRegistryContract( - address: resolverAddress, + public func resolveEns(account: Account) async throws -> String { + let namehash = namehash(account.reversedDomain) + let resolverAddaress = try await registry.resolver( + namehash: namehash, + chainId: account.blockchainIdentifier + ) + let resolver = ENSResolverContract( + address: resolverAddaress, projectId: projectId, chainId: account.blockchainIdentifier, httpClient: httpClient ) - let reversedDomain = account.address.lowercased() - .replacingOccurrences(of: "0x", with: "") + ".addr.reverse" - let namehash = namehash(reversedDomain) - let resolverAddaress = try await registry.resolver(namehash: namehash) + return try await resolver.name(namehash: namehash) + } + + public func resolveAddress(ens: String, blockchain: Blockchain) async throws -> String { + let namehash = namehash(ens) + let resolverAddaress = try await registry.resolver( + namehash: namehash, + chainId: blockchain.absoluteString + ) let resolver = ENSResolverContract( address: resolverAddaress, projectId: projectId, - chainId: account.blockchainIdentifier, + chainId: blockchain.absoluteString, httpClient: httpClient ) - return try await resolver.name(namehash: namehash) + + return try await resolver.address(namehash: namehash) } } @@ -41,16 +52,18 @@ private extension ENSResolver { var result = [UInt8](repeating: 0, count: 32) let labels = name.split(separator: ".") for label in labels.reversed() { - let labelHash = signer.keccak256(normalizeLabel(label).rawRepresentation) + let labelHash = signer.keccak256(label.lowercased().rawRepresentation) result.append(contentsOf: labelHash) result = [UInt8](signer.keccak256(Data(result))) } return Data(result) } +} + +private extension Account { - func normalizeLabel(_ label: S) -> String { - // NOTE: this is NOT a [EIP-137](https://eips.ethereum.org/EIPS/eip-137) compliant implementation - // TODO: properly implement domain name encoding via [UTS #46](https://unicode.org/reports/tr46/) - return label.lowercased() + var reversedDomain: String { + return address.lowercased() + .replacingOccurrences(of: "0x", with: "") + ".addr.reverse" } } diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverContract.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverContract.swift index 3b2a66652..e91f17972 100644 --- a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverContract.swift +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverContract.swift @@ -16,13 +16,14 @@ actor ENSResolverContract { func name(namehash: Data) async throws -> String { let encoder = ENSNameMethod(namehash: namehash) - let call = EthCall(to: address, data: encoder.encode()) - let params = AnyCodable([AnyCodable(call), AnyCodable("latest")]) - let request = RPCRequest(method: "eth_call", params: params) - let data = try JSONEncoder().encode(request) - let httpService = RPCService(data: data, projectId: projectId, chainId: chainId) - let response = try await httpClient.request(RPCResponse.self, at: httpService) - return try validateResponse(response) + let response = try await ethCall(with: encoder.encode()) + return try validateNameResponse(response) + } + + func address(namehash: Data) async throws -> String { + let encoder = ENSAddressMethod(namehash: namehash) + let response = try await ethCall(with: encoder.encode()) + return try validateAddressResponse(response) } } @@ -30,13 +31,36 @@ private extension ENSResolverContract { enum Errors: Error { case invalidResponse + case recordNotFound } - func validateResponse(_ response: RPCResponse) throws -> String { + func ethCall(with data: String) async throws -> RPCResponse { + let call = EthCall(to: address, data: data) + let params = AnyCodable([AnyCodable(call), AnyCodable("latest")]) + let request = RPCRequest(method: "eth_call", params: params) + let data = try JSONEncoder().encode(request) + let httpService = RPCService(data: data, projectId: projectId, chainId: chainId) + return try await httpClient.request(RPCResponse.self, at: httpService) + } + + func validateNameResponse(_ response: RPCResponse) throws -> String { guard let result = try response.result?.get(String.self) else { throw Errors.invalidResponse } let (at, _) = try ContractDecoder.int(result) return try ContractDecoder.string(result, at: at) } + + func validateAddressResponse(_ response: RPCResponse) throws -> String { + guard let result = try response.result?.get(String.self) + else { throw Errors.invalidResponse } + + let address = try ContractDecoder.address(result).0 + + guard address != "0x0000000000000000000000000000000000000000" else { + throw Errors.recordNotFound + } + + return address + } } From 0c2a85424159d0ca16f64a64ca85f3c0a165b977 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 13 Mar 2023 20:30:54 +0500 Subject: [PATCH 14/55] Sending invite by ens --- .../Auth/ENS/ENSResolverTests.swift | 4 +-- .../Chat/Invite/InviteInteractor.swift | 8 +++++ .../Chat/Invite/InvitePresenter.swift | 35 +++++++++++++++---- .../Signer/Ethereum/ENS/ENSResolver.swift | 13 +++++-- 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift b/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift index 2eb8404b9..1d951341a 100644 --- a/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift +++ b/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift @@ -15,7 +15,7 @@ class ENSSignerTests: XCTestCase { func testResolveAddress() async throws { let resolver = ENSResolverFactory(signerFactory: DefaultSignerFactory()).create(projectId: InputConfig.projectId) - let address = try await resolver.resolveAddress(ens: ens, blockchain: account.blockchain) - XCTAssertEqual(address, account.address) + let resolved = try await resolver.resolveAddress(ens: ens, blockchain: account.blockchain) + XCTAssertEqual(resolved, account) } } diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InviteInteractor.swift b/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InviteInteractor.swift index 309251dc6..7d9ca4bd8 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InviteInteractor.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InviteInteractor.swift @@ -1,3 +1,5 @@ +import WalletConnectSigner + final class InviteInteractor { private let accountStorage: AccountStorage @@ -11,4 +13,10 @@ final class InviteInteractor { func invite(inviterAccount: Account, inviteeAccount: Account, message: String) async throws { try await chatService.invite(inviterAccount: inviterAccount, inviteeAccount: inviteeAccount, message: message) } + + func resolve(ens: String) async throws -> Account { + let resolver = ENSResolverFactory(signerFactory: DefaultSignerFactory()).create() + let blochain = Blockchain("eip155:1")! + return try await resolver.resolveAddress(ens: ens, blockchain: Blockchain("eip155:1")!) + } } diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InvitePresenter.swift b/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InvitePresenter.swift index 54374f459..7cc915aac 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InvitePresenter.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InvitePresenter.swift @@ -14,7 +14,7 @@ final class InvitePresenter: ObservableObject { } var showButton: Bool { - return resolveAccount(from: input) != nil + return validation(from: input) } init(interactor: InviteInteractor, router: InviteRouter, account: Account) { @@ -25,11 +25,11 @@ final class InvitePresenter: ObservableObject { @MainActor func invite() async throws { - guard let inviteeAccount = resolveAccount(from: input) - else { return } + let inviteeAccount = try await resolveAccount(from: input) try await interactor.invite(inviterAccount: account, inviteeAccount: inviteeAccount, message: "Welcome to WalletConnect Chat!") - router.dismiss() + + await dismiss() } } @@ -50,11 +50,34 @@ extension InvitePresenter: SceneViewModel { private extension InvitePresenter { + @MainActor + func dismiss() async { + router.dismiss() + } + func didInputChanged() { rightBarButtonItem?.isEnabled = !input.isEmpty } - func resolveAccount(from input: String) -> Account? { + func validation(from input: String) -> Bool { + if let _ = Account(input) { + return true + } + if let _ = ImportAccount(input: input)?.account { + return true + } + if let _ = try? EthereumAddress(hex: input, eip55: false) { + return true + } + + let components = input.components(separatedBy: ".") + if components.count > 1, !components.contains("") { + return true + } + return false + } + + func resolveAccount(from input: String) async throws -> Account { if let account = Account(input) { return account } @@ -64,6 +87,6 @@ private extension InvitePresenter { if let address = try? EthereumAddress(hex: input, eip55: false) { return Account("eip155:1:\(address.hex(eip55: true))")! } - return nil + return try await interactor.resolve(ens: input) } } diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift index b9ccb3112..e1ee8d2e1 100644 --- a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift @@ -29,7 +29,7 @@ public actor ENSResolver { return try await resolver.name(namehash: namehash) } - public func resolveAddress(ens: String, blockchain: Blockchain) async throws -> String { + public func resolveAddress(ens: String, blockchain: Blockchain) async throws -> Account { let namehash = namehash(ens) let resolverAddaress = try await registry.resolver( namehash: namehash, @@ -42,12 +42,21 @@ public actor ENSResolver { httpClient: httpClient ) - return try await resolver.address(namehash: namehash) + let address = try await resolver.address(namehash: namehash) + + guard let account = Account(blockchain: blockchain, address: address) + else { throw Errors.invalidAccount } + + return account } } private extension ENSResolver { + enum Errors: Error { + case invalidAccount + } + func namehash(_ name: String) -> Data { var result = [UInt8](repeating: 0, count: 32) let labels = name.split(separator: ".") From 0aee51b734095ac978ac5fa22a0175125710cb9c Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 14 Mar 2023 17:10:29 +0500 Subject: [PATCH 15/55] Lowercased Account --- Sources/WalletConnectUtils/Account.swift | 6 +++--- Tests/AuthTests/SIWEMessageFormatterTests.swift | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Sources/WalletConnectUtils/Account.swift b/Sources/WalletConnectUtils/Account.swift index 7d5c2cbee..651d874e6 100644 --- a/Sources/WalletConnectUtils/Account.swift +++ b/Sources/WalletConnectUtils/Account.swift @@ -48,9 +48,9 @@ public struct Account: Equatable, Hashable { public init?(_ string: String) { guard String.conformsToCAIP10(string) else { return nil } let splits = string.split(separator: ":") - self.namespace = String(splits[0]) - self.reference = String(splits[1]) - self.address = String(splits[2]) + self.namespace = String(splits[0].lowercased()) + self.reference = String(splits[1].lowercased()) + self.address = String(splits[2].lowercased()) } /** diff --git a/Tests/AuthTests/SIWEMessageFormatterTests.swift b/Tests/AuthTests/SIWEMessageFormatterTests.swift index 129fe4c52..18ff4ce77 100644 --- a/Tests/AuthTests/SIWEMessageFormatterTests.swift +++ b/Tests/AuthTests/SIWEMessageFormatterTests.swift @@ -4,7 +4,7 @@ import XCTest class SIWEMessageFormatterTests: XCTestCase { var sut: SIWECacaoFormatter! - let address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" + let address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" override func setUp() { sut = SIWECacaoFormatter() @@ -14,7 +14,7 @@ class SIWEMessageFormatterTests: XCTestCase { let expectedMessage = """ service.invalid wants you to sign in with your Ethereum account: - 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 + 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 I accept the ServiceOrg Terms of Service: https://service.invalid/tos @@ -35,7 +35,7 @@ class SIWEMessageFormatterTests: XCTestCase { let expectedMessage = """ service.invalid wants you to sign in with your Ethereum account: - 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 + 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 URI: https://service.invalid/login Version: 1 @@ -58,7 +58,7 @@ class SIWEMessageFormatterTests: XCTestCase { let expectedMessage = """ service.invalid wants you to sign in with your Ethereum account: - 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 + 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 I accept the ServiceOrg Terms of Service: https://service.invalid/tos @@ -79,7 +79,7 @@ class SIWEMessageFormatterTests: XCTestCase { let expectedMessage = """ service.invalid wants you to sign in with your Ethereum account: - 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 + 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 URI: https://service.invalid/login Version: 1 From 38506ff5838b703cf84b7a48112d4adc36a13385 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Wed, 15 Mar 2023 16:12:42 +0500 Subject: [PATCH 16/55] Integration tests fixed --- Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift | 2 +- Example/IntegrationTests/Auth/Signer/SignerTests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift b/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift index 8066c147d..a2ee1376e 100644 --- a/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift +++ b/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift @@ -12,7 +12,7 @@ class CacaoSignerTest: XCTestCase { let message: String = """ service.invalid wants you to sign in with your Ethereum account: - 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 + 0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 I accept the ServiceOrg Terms of Service: https://service.invalid/tos diff --git a/Example/IntegrationTests/Auth/Signer/SignerTests.swift b/Example/IntegrationTests/Auth/Signer/SignerTests.swift index 568dd2c82..14954da01 100644 --- a/Example/IntegrationTests/Auth/Signer/SignerTests.swift +++ b/Example/IntegrationTests/Auth/Signer/SignerTests.swift @@ -32,6 +32,6 @@ class SignerTest: XCTestCase { func testSignerAddressFromAccount() throws { let account = Account("eip155:1:0xBAc675C310721717Cd4A37F6cbeA1F081b1C2a07")! - XCTAssertEqual(DIDPKH(account: account).string, "did:pkh:eip155:1:0xBAc675C310721717Cd4A37F6cbeA1F081b1C2a07") + XCTAssertEqual(DIDPKH(account: account).string, "did:pkh:eip155:1:0xbac675c310721717cd4a37f6cbea1f081b1c2a07") } } From 82f71939a54ca84b121ad19a6e4c5a6006d5ed1e Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Thu, 16 Mar 2023 08:25:42 +0100 Subject: [PATCH 17/55] update header name --- Sources/WalletConnectEcho/Register/EchoService.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/WalletConnectEcho/Register/EchoService.swift b/Sources/WalletConnectEcho/Register/EchoService.swift index 23b8ff48e..e954de6a5 100644 --- a/Sources/WalletConnectEcho/Register/EchoService.swift +++ b/Sources/WalletConnectEcho/Register/EchoService.swift @@ -47,9 +47,9 @@ enum EchoAPI: HTTPService { var headerFields: [String : String]? { switch self { case .register(_, _, _, _, let auth): - return ["auth": auth] + return ["Authorization": auth] case .unregister(_, _, let auth): - return ["auth": auth] + return ["Authorization": auth] } } From 63a595617821066dca236de7769b4b9309c53b91 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Thu, 16 Mar 2023 15:53:46 +0500 Subject: [PATCH 18/55] CacaoSignerTest fixed --- Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift b/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift index a2ee1376e..ee5224a1d 100644 --- a/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift +++ b/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift @@ -41,10 +41,10 @@ class CacaoSignerTest: XCTestCase { ] ), iat: "2021-09-30T16:25:24Z") - let signature = CacaoSignature(t: .eip191, s: "0x438effc459956b57fcd9f3dac6c675f9cee88abf21acab7305e8e32aa0303a883b06dcbd956279a7a2ca21ffa882ff55cc22e8ab8ec0f3fe90ab45f306938cfa1b") + let signature = CacaoSignature(t: .eip191, s: "0x2755a5cf4542e8649fadcfca8c983068ef3bda6057550ecd1ead32b75125a4547ed8e91ef76ef17e969434ffa4ac2e4dc1e8cd8be55d342ad9e223c64fbfe1dd1b") func testCacaoSign() throws { - let address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" + let address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" let cacaoPayload = try payload.cacaoPayload(address: address) let formatted = try SIWECacaoFormatter().formatMessage(from: cacaoPayload) XCTAssertEqual(formatted, message) From b7f6fe1803e28f796823597e588665ab6986d541 Mon Sep 17 00:00:00 2001 From: Alexander Lisovyk Date: Thu, 16 Mar 2023 12:26:18 +0100 Subject: [PATCH 19/55] Update echo configuration --- .../Configurator/ThirdPartyConfigurator.swift | 2 +- Sources/WalletConnectEcho/EchoClient.swift | 2 -- Sources/WalletConnectEcho/EchoClientProtocol.swift | 3 +++ Sources/Web3Wallet/Web3Wallet.swift | 6 +++--- Sources/Web3Wallet/Web3WalletClient.swift | 8 ++++++++ 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift index f06ba1b35..876a7e701 100644 --- a/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift +++ b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift @@ -14,7 +14,7 @@ struct ThirdPartyConfigurator: Configurator { icons: ["https://avatars.githubusercontent.com/u/37784886"] ) - Web3Wallet.configure(metadata: metadata, signerFactory: DefaultSignerFactory()) + Web3Wallet.configure(metadata: metadata, signerFactory: DefaultSignerFactory(), environment: .sandbox) Push.configure(environment: BuildConfiguration.shared.apnsEnvironment) } diff --git a/Sources/WalletConnectEcho/EchoClient.swift b/Sources/WalletConnectEcho/EchoClient.swift index c7f18809b..ae4801e91 100644 --- a/Sources/WalletConnectEcho/EchoClient.swift +++ b/Sources/WalletConnectEcho/EchoClient.swift @@ -17,6 +17,4 @@ public class EchoClient: EchoClientProtocol { try await registerService.register(deviceToken: deviceToken) } #endif - - } diff --git a/Sources/WalletConnectEcho/EchoClientProtocol.swift b/Sources/WalletConnectEcho/EchoClientProtocol.swift index b10577744..c3b783df9 100644 --- a/Sources/WalletConnectEcho/EchoClientProtocol.swift +++ b/Sources/WalletConnectEcho/EchoClientProtocol.swift @@ -2,4 +2,7 @@ import Foundation public protocol EchoClientProtocol { func register(deviceToken: Data) async throws +#if DEBUG + func register(deviceToken: String) async throws +#endif } diff --git a/Sources/Web3Wallet/Web3Wallet.swift b/Sources/Web3Wallet/Web3Wallet.swift index 7a6afc05f..2326009d8 100644 --- a/Sources/Web3Wallet/Web3Wallet.swift +++ b/Sources/Web3Wallet/Web3Wallet.swift @@ -20,7 +20,6 @@ public class Web3Wallet { guard let config = Web3Wallet.config else { fatalError("Error - you must call Web3Wallet.configure(_:) before accessing the shared instance.") } - return Web3WalletClientFactory.create( authClient: Auth.instance, signClient: Sign.instance, @@ -37,10 +36,11 @@ public class Web3Wallet { /// - Parameters: /// - metadata: App metadata /// - signerFactory: Auth signers factory - static public func configure(metadata: AppMetadata, signerFactory: SignerFactory) { + static public func configure(metadata: AppMetadata, signerFactory: SignerFactory, echoHost: String = "echo.walletconnect.com", environment: APNSEnvironment) { Pair.configure(metadata: metadata) Auth.configure(signerFactory: signerFactory) - + let clientId = try! Networking.interactor.getClientId() + Echo.configure(clientId: clientId, echoHost: echoHost, environment: environment) Web3Wallet.config = Web3Wallet.Config(signerFactory: signerFactory) } } diff --git a/Sources/Web3Wallet/Web3WalletClient.swift b/Sources/Web3Wallet/Web3WalletClient.swift index 685606686..68c2aab41 100644 --- a/Sources/Web3Wallet/Web3WalletClient.swift +++ b/Sources/Web3Wallet/Web3WalletClient.swift @@ -185,3 +185,11 @@ public class Web3WalletClient { try await echoClient.register(deviceToken: deviceToken) } } + +#if targetEnvironment(simulator) +extension Web3WalletClient { + public func registerEchoClient(deviceToken: String) async throws { + try await echoClient.register(deviceToken: deviceToken) + } +} +#endif From b31dfbda81e8da699a1bda3e2a54d0458fd0ed8c Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Thu, 16 Mar 2023 12:37:54 +0100 Subject: [PATCH 20/55] change iat to seconds --- Sources/WalletConnectEcho/Register/EchoAuthPayload.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift b/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift index c3867c3da..dc42a5be2 100644 --- a/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift +++ b/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift @@ -33,7 +33,7 @@ struct EchoAuthPayload: JWTClaimsCodable { iss: iss, sub: subject, aud: audience, - iat: defaultIatMilliseconds(), + iat: defaultIat(), exp: expiry(days: 1) ) } From 5f53f431c6339bb850dc757efc81393654f269bd Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 20 Mar 2023 17:53:22 +0500 Subject: [PATCH 21/55] Crash fix --- Example/Showcase/Classes/DomainLayer/Chat/ImportAccount.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Example/Showcase/Classes/DomainLayer/Chat/ImportAccount.swift b/Example/Showcase/Classes/DomainLayer/Chat/ImportAccount.swift index 329f30e75..2c8ccffa0 100644 --- a/Example/Showcase/Classes/DomainLayer/Chat/ImportAccount.swift +++ b/Example/Showcase/Classes/DomainLayer/Chat/ImportAccount.swift @@ -48,8 +48,8 @@ enum ImportAccount { case .js: return Account("eip155:1:0x7ABa5B1F436e42f6d4A579FB3Ad6D204F6A91863")! case .custom(let privateKey): - let address = try! EthereumPrivateKey(hexPrivateKey: "0x" + privateKey, ctx: nil).address.rawAddress - return Account("eip155:1:\(address))")! + let address = try! EthereumPrivateKey(hexPrivateKey: "0x" + privateKey, ctx: nil).address.hex(eip55: false) + return Account("eip155:1:\(address)")! } } From 6576e3cd2d3ef71b8e15e4003f5dd1dec44bc382 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 21 Mar 2023 13:08:57 +0500 Subject: [PATCH 22/55] cd script --- .../workflows/{set-user-agent.yml => cd.yml} | 15 +++++++++++++-- .../IdentityImports.swift | 1 + .../IdentityKeyAPI.swift | 2 +- ...thPayload.swift => RelayAuthPayload.swift} | 2 +- .../ClientAuth/SocketAuthenticator.swift | 2 +- .../RPC/Methods/Subscription.swift | 2 -- .../AuthTests/EdDSASignerTests.swift | 2 +- Tests/RelayerTests/AuthTests/JWTTests.swift | 8 ++++---- WalletConnectSwiftV2.podspec | 19 ++++++++++++++++++- 9 files changed, 40 insertions(+), 13 deletions(-) rename .github/workflows/{set-user-agent.yml => cd.yml} (62%) rename Sources/WalletConnectRelay/ClientAuth/{AuthPayload.swift => RelayAuthPayload.swift} (94%) diff --git a/.github/workflows/set-user-agent.yml b/.github/workflows/cd.yml similarity index 62% rename from .github/workflows/set-user-agent.yml rename to .github/workflows/cd.yml index a08089f8a..c0a66c572 100644 --- a/.github/workflows/set-user-agent.yml +++ b/.github/workflows/cd.yml @@ -3,12 +3,14 @@ # it takes pull request name # and automatically commit it as a package version # pull request name should always be a version of a new release +# +# After version bump publishing Cocoapods release -name: set-user-agent +name: cd on: pull_request: - branches: [ main ] + branches: [ main, develop ] env: PACKAGE_VERSION: ${{ github.event.pull_request.title }} @@ -18,6 +20,7 @@ jobs: steps: - uses: actions/checkout@v2 with: + fetch-depth: 0 token: ${{ secrets.GH_TOKEN }} - name: Set User Agent @@ -27,4 +30,12 @@ jobs: - uses: stefanzweifel/git-auto-commit-action@v4 with: commit_message: Set User Agent + tagging_message: ${{ github.event.pull_request.title }} + skip_checkout: true + + - name: Publish to CocoaPod register + env: + COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} + run: | + pod trunk push WalletConnectSwiftV2.podspec --verbose diff --git a/Sources/WalletConnectIdentity/IdentityImports.swift b/Sources/WalletConnectIdentity/IdentityImports.swift index 23c1738ef..463cb7c23 100644 --- a/Sources/WalletConnectIdentity/IdentityImports.swift +++ b/Sources/WalletConnectIdentity/IdentityImports.swift @@ -1,3 +1,4 @@ #if !CocoaPods @_exported import WalletConnectNetworking +@_exported import WalletConnectJWT #endif diff --git a/Sources/WalletConnectIdentity/IdentityKeyAPI.swift b/Sources/WalletConnectIdentity/IdentityKeyAPI.swift index 1346d40ac..d29da2480 100644 --- a/Sources/WalletConnectIdentity/IdentityKeyAPI.swift +++ b/Sources/WalletConnectIdentity/IdentityKeyAPI.swift @@ -18,7 +18,7 @@ enum IdentityKeyAPI: HTTPService { } } - var method: WalletConnectNetworking.HTTPMethod { + var method: HTTPMethod { switch self { case .registerIdentity, .registerInvite: return .post diff --git a/Sources/WalletConnectRelay/ClientAuth/AuthPayload.swift b/Sources/WalletConnectRelay/ClientAuth/RelayAuthPayload.swift similarity index 94% rename from Sources/WalletConnectRelay/ClientAuth/AuthPayload.swift rename to Sources/WalletConnectRelay/ClientAuth/RelayAuthPayload.swift index 580cad76d..737f515c0 100644 --- a/Sources/WalletConnectRelay/ClientAuth/AuthPayload.swift +++ b/Sources/WalletConnectRelay/ClientAuth/RelayAuthPayload.swift @@ -1,6 +1,6 @@ import Foundation -struct AuthPayload: JWTClaimsCodable { +struct RelayAuthPayload: JWTClaimsCodable { struct Wrapper: JWTWrapper { let jwtString: String diff --git a/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift b/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift index 96c1f77fb..bb7a8b540 100644 --- a/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift +++ b/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift @@ -15,7 +15,7 @@ struct SocketAuthenticator: SocketAuthenticating { func createAuthToken() throws -> String { let keyPair = try clientIdStorage.getOrCreateKeyPair() - let payload = AuthPayload(subject: getSubject(), audience: getAudience()) + let payload = RelayAuthPayload(subject: getSubject(), audience: getAudience()) return try payload.signAndCreateWrapper(keyPair: keyPair).jwtString } diff --git a/Sources/WalletConnectRelay/RPC/Methods/Subscription.swift b/Sources/WalletConnectRelay/RPC/Methods/Subscription.swift index 8021370f6..c4e4b1831 100644 --- a/Sources/WalletConnectRelay/RPC/Methods/Subscription.swift +++ b/Sources/WalletConnectRelay/RPC/Methods/Subscription.swift @@ -1,6 +1,4 @@ - import Foundation -import WalletConnectUtils struct Subscription: RelayRPC { diff --git a/Tests/RelayerTests/AuthTests/EdDSASignerTests.swift b/Tests/RelayerTests/AuthTests/EdDSASignerTests.swift index d00d66376..87d5ae4c3 100644 --- a/Tests/RelayerTests/AuthTests/EdDSASignerTests.swift +++ b/Tests/RelayerTests/AuthTests/EdDSASignerTests.swift @@ -12,7 +12,7 @@ final class EdDSASignerTests: XCTestCase { let signingKey = try! SigningPrivateKey(rawRepresentation: keyRaw) sut = EdDSASigner(signingKey) let header = try! JWTHeader(alg: "EdDSA").encode() - let claims = try! AuthPayload.Claims.stub().encode() + let claims = try! RelayAuthPayload.Claims.stub().encode() let signature = try! sut.sign(header: header, claims: claims) XCTAssertNotNil(signature) } diff --git a/Tests/RelayerTests/AuthTests/JWTTests.swift b/Tests/RelayerTests/AuthTests/JWTTests.swift index e6fdbf0fc..de21300c5 100644 --- a/Tests/RelayerTests/AuthTests/JWTTests.swift +++ b/Tests/RelayerTests/AuthTests/JWTTests.swift @@ -7,7 +7,7 @@ final class JWTTests: XCTestCase { let expectedJWT = "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTY5MTAwOTcsImV4cCI6MTY1Njk5NjQ5NywiaXNzIjoiZGlkOmtleTp6Nk1rb2RIWnduZVZSU2h0YUxmOEpLWWt4cERHcDF2R1pucEdtZEJwWDhNMmV4eEgiLCJzdWIiOiJjNDc5ZmU1ZGM0NjRlNzcxZTc4YjE5M2QyMzlhNjViNThkMjc4Y2FkMWMzNGJmYjBiNTcxNmU1YmI1MTQ5MjhlIiwiYXVkIjoid3NzOi8vcmVsYXkud2FsbGV0Y29ubmVjdC5jb20ifQ.0JkxOM-FV21U7Hk-xycargj_qNRaYV2H5HYtE4GzAeVQYiKWj7YySY5AdSqtCgGzX4Gt98XWXn2kSr9rE1qvCA" func testJWTEncoding() { - var jwt = JWT(claims: AuthPayload.Claims.stub()) + var jwt = JWT(claims: RelayAuthPayload.Claims.stub()) let signer = EdDSASignerMock() signer.signature = "0JkxOM-FV21U7Hk-xycargj_qNRaYV2H5HYtE4GzAeVQYiKWj7YySY5AdSqtCgGzX4Gt98XWXn2kSr9rE1qvCA" try! jwt.sign(using: signer) @@ -16,8 +16,8 @@ final class JWTTests: XCTestCase { } } -extension AuthPayload.Claims { - static func stub() -> AuthPayload.Claims { +extension RelayAuthPayload.Claims { + static func stub() -> RelayAuthPayload.Claims { let iss = "did:key:z6MkodHZwneVRShtaLf8JKYkxpDGp1vGZnpGmdBpX8M2exxH" let sub = "c479fe5dc464e771e78b193d239a65b58d278cad1c34bfb0b5716e5bb514928e" let iatDate = Date(timeIntervalSince1970: 1656910097) @@ -27,6 +27,6 @@ extension AuthPayload.Claims { let aud = "wss://relay.walletconnect.com" let expDate = Calendar.current.date(byAdding: components, to: iatDate)! let exp = UInt64(expDate.timeIntervalSince1970) - return AuthPayload.Claims(iss: iss, sub: sub, aud: aud, iat: iat, exp: exp) + return RelayAuthPayload.Claims(iss: iss, sub: sub, aud: aud, iat: iat, exp: exp) } } diff --git a/WalletConnectSwiftV2.podspec b/WalletConnectSwiftV2.podspec index 51446a7c5..a79bd3039 100644 --- a/WalletConnectSwiftV2.podspec +++ b/WalletConnectSwiftV2.podspec @@ -92,7 +92,24 @@ Pod::Spec.new do |spec| spec.subspec 'WalletConnectChat' do |ss| ss.source_files = 'Sources/Chat/**/*.{h,m,swift}' + ss.dependency 'WalletConnectSwiftV2/WalletConnectSigner' + ss.dependency 'WalletConnectSwiftV2/WalletConnectIdentity' + end + + spec.subspec 'WalletConnectSigner' do |ss| + ss.source_files = 'Sources/WalletConnectSigner/**/*.{h,m,swift}' + ss.dependency 'WalletConnectSwiftV2/WalletConnectNetworking' + end + + spec.subspec 'WalletConnectIdentity' do |ss| + ss.source_files = 'Sources/WalletConnectIdentity/**/*.{h,m,swift}' ss.dependency 'WalletConnectSwiftV2/WalletConnectNetworking' + ss.dependency 'WalletConnectSwiftV2/WalletConnectJWT' + end + + spec.subspec 'WalletConnectJWT' do |ss| + ss.source_files = 'Sources/WalletConnectJWT/**/*.{h,m,swift}' + ss.dependency 'WalletConnectSwiftV2/WalletConnectKMS' end spec.subspec 'WalletConnectNetworking' do |ss| @@ -117,7 +134,7 @@ Pod::Spec.new do |spec| spec.subspec 'WalletConnectRelay' do |ss| ss.source_files = 'Sources/WalletConnectRelay/**/*.{h,m,swift}' - ss.dependency 'WalletConnectSwiftV2/WalletConnectKMS' + ss.dependency 'WalletConnectSwiftV2/WalletConnectJWT' ss.resource_bundles = { 'WalletConnect_WalletConnectRelay' => [ 'Sources/WalletConnectRelay/PackageConfig.json' From 034ab60a5671a4da1b0e09777df9cf8771aa3227 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 21 Mar 2023 14:58:11 +0500 Subject: [PATCH 23/55] import WalletConnectSigner --- WalletConnectSwiftV2.podspec | 1 + 1 file changed, 1 insertion(+) diff --git a/WalletConnectSwiftV2.podspec b/WalletConnectSwiftV2.podspec index a79bd3039..a9f746cae 100644 --- a/WalletConnectSwiftV2.podspec +++ b/WalletConnectSwiftV2.podspec @@ -82,6 +82,7 @@ Pod::Spec.new do |spec| spec.subspec 'WalletConnectAuth' do |ss| ss.source_files = 'Sources/Auth/**/*.{h,m,swift}' ss.dependency 'WalletConnectSwiftV2/WalletConnectPairing' + ss.dependency 'WalletConnectSwiftV2/WalletConnectSigner' end spec.subspec 'Web3Wallet' do |ss| From 1255099615c07131ac5dec65ba13a0c3570afc6e Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 21 Mar 2023 16:35:22 +0500 Subject: [PATCH 24/55] allow warnings --- .github/workflows/cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index c0a66c572..a915963c6 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -37,5 +37,5 @@ jobs: env: COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} run: | - pod trunk push WalletConnectSwiftV2.podspec --verbose + pod trunk push WalletConnectSwiftV2.podspec --verbose --allow-warnings From 5319a234563c7ddfc865d78067b0f8e7eb56da08 Mon Sep 17 00:00:00 2001 From: flypaper0 Date: Tue, 21 Mar 2023 13:10:16 +0000 Subject: [PATCH 25/55] Set User Agent --- Sources/WalletConnectRelay/PackageConfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnectRelay/PackageConfig.json b/Sources/WalletConnectRelay/PackageConfig.json index 818e3430c..2901f0eb7 100644 --- a/Sources/WalletConnectRelay/PackageConfig.json +++ b/Sources/WalletConnectRelay/PackageConfig.json @@ -1 +1 @@ -{"version": "1.5.1"} +{"version": "1.5.3"} From 5c0fb6df69d706e1cdcc8a0d48958cec47699997 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Wed, 22 Mar 2023 14:48:49 +0500 Subject: [PATCH 26/55] rfc3986 --- Sources/WalletConnectUtils/Extensions/CharacterSet.swift | 8 ++++++++ Sources/WalletConnectUtils/WalletConnectURI.swift | 5 +++++ 2 files changed, 13 insertions(+) create mode 100644 Sources/WalletConnectUtils/Extensions/CharacterSet.swift diff --git a/Sources/WalletConnectUtils/Extensions/CharacterSet.swift b/Sources/WalletConnectUtils/Extensions/CharacterSet.swift new file mode 100644 index 000000000..846f4d0ec --- /dev/null +++ b/Sources/WalletConnectUtils/Extensions/CharacterSet.swift @@ -0,0 +1,8 @@ +import Foundation + +extension CharacterSet { + + public static var rfc3986: CharacterSet { + return .alphanumerics.union(CharacterSet(charactersIn: "-._~")) + } +} diff --git a/Sources/WalletConnectUtils/WalletConnectURI.swift b/Sources/WalletConnectUtils/WalletConnectURI.swift index 7db772582..306dcd6ff 100644 --- a/Sources/WalletConnectUtils/WalletConnectURI.swift +++ b/Sources/WalletConnectUtils/WalletConnectURI.swift @@ -11,6 +11,11 @@ public struct WalletConnectURI: Equatable { return "wc:\(topic)@\(version)?symKey=\(symKey)&\(relayQuery)" } + public var deeplinkUri: String { + return absoluteString + .addingPercentEncoding(withAllowedCharacters: .rfc3986)! + } + public init(topic: String, symKey: String, relay: RelayProtocolOptions) { self.version = "2" self.topic = topic From 4d2d248362eade988c0e0c5ea3494af9cd00f1c0 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Wed, 22 Mar 2023 14:52:06 +0500 Subject: [PATCH 27/55] Do not run on develop --- .github/workflows/cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index a915963c6..fce27c131 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -10,7 +10,7 @@ name: cd on: pull_request: - branches: [ main, develop ] + branches: [ main ] env: PACKAGE_VERSION: ${{ github.event.pull_request.title }} From ec57c01629a7950350e984c5e07141d1e9ac152d Mon Sep 17 00:00:00 2001 From: Alexander Lisovyk Date: Wed, 22 Mar 2023 17:10:28 +0400 Subject: [PATCH 28/55] Update tests --- Tests/Web3WalletTests/Mocks/EchoClientMock.swift | 16 ++++++++++++++++ Tests/Web3WalletTests/Web3WalletTests.swift | 13 ++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Tests/Web3WalletTests/Mocks/EchoClientMock.swift diff --git a/Tests/Web3WalletTests/Mocks/EchoClientMock.swift b/Tests/Web3WalletTests/Mocks/EchoClientMock.swift new file mode 100644 index 000000000..2a43ee0e6 --- /dev/null +++ b/Tests/Web3WalletTests/Mocks/EchoClientMock.swift @@ -0,0 +1,16 @@ +import Foundation +import Combine + +@testable import WalletConnectEcho + +final class EchoClientMock: EchoClientProtocol { + var registedCalled = false + + func register(deviceToken: Data) async throws { + registedCalled = true + } + + func register(deviceToken: String) async throws { + registedCalled = true + } +} diff --git a/Tests/Web3WalletTests/Web3WalletTests.swift b/Tests/Web3WalletTests/Web3WalletTests.swift index b533bd200..dc8489d73 100644 --- a/Tests/Web3WalletTests/Web3WalletTests.swift +++ b/Tests/Web3WalletTests/Web3WalletTests.swift @@ -9,6 +9,7 @@ final class Web3WalletTests: XCTestCase { var authClient: AuthClientMock! var signClient: SignClientMock! var pairingClient: PairingClientMock! + var echoClient: EchoClientMock! private var disposeBag = Set() @@ -16,11 +17,13 @@ final class Web3WalletTests: XCTestCase { authClient = AuthClientMock() signClient = SignClientMock() pairingClient = PairingClientMock() + echoClient = EchoClientMock() web3WalletClient = Web3WalletClientFactory.create( authClient: authClient, signClient: signClient, - pairingClient: pairingClient + pairingClient: pairingClient, + echoClient: echoClient ) } @@ -263,4 +266,12 @@ final class Web3WalletTests: XCTestCase { func testGetPairingsNotEmpty() async { XCTAssertEqual(1, web3WalletClient.getPairings().count) } + + func testEchoClientRegisterCalled() async { + try! await echoClient.register(deviceToken: Data()) + XCTAssertTrue(echoClient.registedCalled) + echoClient.registedCalled = false + try! await echoClient.register(deviceToken: "") + XCTAssertTrue(echoClient.registedCalled) + } } From 5bf8f90e618e23f497430ca256416f77fade957b Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Thu, 23 Mar 2023 17:08:52 +0500 Subject: [PATCH 29/55] force unwrap removed --- Sources/WalletConnectUtils/WalletConnectURI.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnectUtils/WalletConnectURI.swift b/Sources/WalletConnectUtils/WalletConnectURI.swift index 306dcd6ff..604929ff0 100644 --- a/Sources/WalletConnectUtils/WalletConnectURI.swift +++ b/Sources/WalletConnectUtils/WalletConnectURI.swift @@ -13,7 +13,7 @@ public struct WalletConnectURI: Equatable { public var deeplinkUri: String { return absoluteString - .addingPercentEncoding(withAllowedCharacters: .rfc3986)! + .addingPercentEncoding(withAllowedCharacters: .rfc3986) ?? absoluteString } public init(topic: String, symKey: String, relay: RelayProtocolOptions) { From 3e5c14cd67cfef7837d12f74aa1581de268f5165 Mon Sep 17 00:00:00 2001 From: Alexander Lisovyk Date: Mon, 27 Mar 2023 10:38:23 +0400 Subject: [PATCH 30/55] Update wallet app url --- Example/DApp/Sign/SelectChain/SelectChainViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/DApp/Sign/SelectChain/SelectChainViewController.swift b/Example/DApp/Sign/SelectChain/SelectChainViewController.swift index 45510a1f1..5c456a453 100644 --- a/Example/DApp/Sign/SelectChain/SelectChainViewController.swift +++ b/Example/DApp/Sign/SelectChain/SelectChainViewController.swift @@ -84,7 +84,7 @@ class SelectChainViewController: UIViewController, UITableViewDataSource { @objc private func openWallet() { - UIApplication.shared.open(URL(string: "walletconnectwallet://")!) + UIApplication.shared.open(URL(string: "walletapp://")!) } private func showConnectScreen(uri: WalletConnectURI) { From 0dd37675a0024c736aaa1123876fb12ad17db9f6 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 27 Mar 2023 13:58:32 +0500 Subject: [PATCH 31/55] Update String+CAIPs.swift --- Sources/WalletConnectUtils/Extensions/String+CAIPs.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnectUtils/Extensions/String+CAIPs.swift b/Sources/WalletConnectUtils/Extensions/String+CAIPs.swift index 2f51d8b4e..d5d0ae905 100644 --- a/Sources/WalletConnectUtils/Extensions/String+CAIPs.swift +++ b/Sources/WalletConnectUtils/Extensions/String+CAIPs.swift @@ -4,7 +4,7 @@ extension String { static let chainNamespaceRegex = "^[-a-z0-9]{3,8}$" static let chainReferenceRegex = "^[-a-zA-Z0-9_]{1,32}$" - static let accountAddressRegex = "^[a-zA-Z0-9]{1,64}$" + static let accountAddressRegex = "^[-.%a-zA-Z0-9]{1,128}$" static func conformsToCAIP2(_ string: String) -> Bool { let splits = string.split(separator: ":", omittingEmptySubsequences: false) From a1f460c7d9ca0263519ca0f57c48b31f50fac116 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 27 Mar 2023 16:51:54 +0500 Subject: [PATCH 32/55] Unit tests fixed --- Tests/WalletConnectUtilsTests/String+ExtensionTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/WalletConnectUtilsTests/String+ExtensionTests.swift b/Tests/WalletConnectUtilsTests/String+ExtensionTests.swift index d783cfa2e..f7201164b 100644 --- a/Tests/WalletConnectUtilsTests/String+ExtensionTests.swift +++ b/Tests/WalletConnectUtilsTests/String+ExtensionTests.swift @@ -47,10 +47,10 @@ final class StringExtensionTests: XCTestCase { func testConformanceToCAIP10() { // Minimum and maximum length cases XCTAssertTrue(String.conformsToCAIP10("std:0:0"), "Dummy min length (3+1+1+1+1 = 7 chars/bytes)") - XCTAssertTrue(String.conformsToCAIP10("chainstd:8c3444cf8970a9e41a706fab93e7a6c4:6d9b0b4b9994e8a6afbd3dc3ed983cd51c755afb27cd1dc7825ef59c134a39f7"), "Dummy max length (64+1+8+1+32 = 106 chars/bytes)") + XCTAssertTrue(String.conformsToCAIP10("chainstd:8c3444cf8970a9e41a706fab93e7a6c4:6d9b0b4b9994e8a6afbd3dc3ed983cd51c755afb27cd1dc7825ef59c134a39f76d9b0b4b9994e8a6afbd3dc3ed983cd51c755afb27cd1dc7825ef59c134a39f7"), "Dummy max length (8+1+32+1+128 = 170 chars/bytes)") // Invalid address formatting - XCTAssertFalse(String.conformsToCAIP10("chainstd:0:6d9b0b4b9994e8a6afbd3dc3ed983cd51c755afb27cd1dc7825ef59c134a39f77"), "Address overflow") + XCTAssertFalse(String.conformsToCAIP10("chainstd:0:6d9b0b4b9994e8a6afbd3dc3ed983cd51c755afb27cd1dc7825ef59c134a39f76d9b0b4b9994e8a6afbd3dc3ed983cd51c755afb27cd1dc7825ef59c134a39f7f"), "Address overflow") XCTAssertFalse(String.conformsToCAIP10("chainstd:0:$"), "Address uses special character") XCTAssertFalse(String.conformsToCAIP10("chainstd:0:"), "Empty address") From 76d513d8d8b5c3367ccf4a7b9bbcae3c6da63e3f Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 27 Mar 2023 20:57:46 +0500 Subject: [PATCH 33/55] Account agnostic chat --- .../ApplicationLayer/Application.swift | 2 +- .../DomainLayer/Chat/ChatService.swift | 26 +++++------ .../Chat/ChatList/ChatListInteractor.swift | 16 ++++--- .../Chat/ChatList/ChatListPresenter.swift | 8 ++-- .../InviteList/InviteListInteractor.swift | 8 ++-- .../Chat/InviteList/InviteListPresenter.swift | 4 +- Sources/Chat/Chat.swift | 13 ------ Sources/Chat/ChatClient.swift | 28 +++++------- Sources/Chat/ChatClientFactory.swift | 16 +++---- Sources/Chat/ChatStorage.swift | 44 +++++++------------ .../Accounts/AccountService.swift | 14 ------ .../Common/MessagingService.swift | 15 +++---- .../Common/ResubscriptionService.swift | 3 -- .../Invitee/InvitationHandlingService.swift | 25 ++++------- .../Inviter/InviteService.swift | 6 +-- .../ChatClient/ChatClientProxy.swift | 21 +++++++-- Sources/Web3Inbox/Web3Inbox.swift | 1 - 17 files changed, 99 insertions(+), 151 deletions(-) delete mode 100644 Sources/Chat/ProtocolServices/Accounts/AccountService.swift diff --git a/Example/Showcase/Classes/ApplicationLayer/Application.swift b/Example/Showcase/Classes/ApplicationLayer/Application.swift index 27a3577f4..3cc8d8713 100644 --- a/Example/Showcase/Classes/ApplicationLayer/Application.swift +++ b/Example/Showcase/Classes/ApplicationLayer/Application.swift @@ -4,7 +4,7 @@ import WalletConnectChat final class Application { lazy var chatService: ChatService = { - return ChatService(accountStorage: accountStorage) + return ChatService() }() lazy var accountStorage: AccountStorage = { diff --git a/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift b/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift index a8fce70a2..addd4ab45 100644 --- a/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift +++ b/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift @@ -8,10 +8,6 @@ typealias Stream = AnyPublisher final class ChatService { private lazy var client: ChatClient = { - guard let importAccount = accountStorage.importAccount else { - fatalError("Error - you must call Chat.configure(_:) before accessing the shared instance.") - } - Chat.configure(account: importAccount.account) return Chat.instance }() @@ -19,12 +15,6 @@ final class ChatService { return Networking.instance }() - private let accountStorage: AccountStorage - - init(accountStorage: AccountStorage) { - self.accountStorage = accountStorage - } - var connectionPublisher: Stream { return networking.socketConnectionStatusPublisher .receive(on: DispatchQueue.main) @@ -62,16 +52,20 @@ final class ChatService { client.getMessages(topic: thread.topic) } - func getThreads() -> [WalletConnectChat.Thread] { - client.getThreads() + func getThreads(account: Account) -> [WalletConnectChat.Thread] { + return client.getThreads(account: account) + } + + func getReceivedInvites(account: Account) -> [ReceivedInvite] { + return client.getReceivedInvites(account: account) } - func getReceivedInvites() -> [ReceivedInvite] { - client.getReceivedInvites() + func getSentInvites(account: Account) -> [SentInvite] { + return client.getSentInvites(account: account) } - func getSentInvites() -> [SentInvite] { - client.getSentInvites() + func setupSubscriptions(account: Account) { + client.setupSubscriptions(account: account) } func sendMessage(topic: String, message: String) async throws { diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListInteractor.swift b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListInteractor.swift index 4ff6ef004..758b03fb7 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListInteractor.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListInteractor.swift @@ -10,20 +10,20 @@ final class ChatListInteractor { self.accountStorage = accountStorage } - func getThreads() -> [WalletConnectChat.Thread] { - return chatService.getThreads() + func getThreads(account: Account) -> [WalletConnectChat.Thread] { + return chatService.getThreads(account: account) } func threadsSubscription() -> Stream<[WalletConnectChat.Thread]> { return chatService.threadPublisher } - func getReceivedInvites() -> [ReceivedInvite] { - return chatService.getReceivedInvites() + func getReceivedInvites(account: Account) -> [ReceivedInvite] { + return chatService.getReceivedInvites(account: account) } - func getSentInvites() -> [SentInvite] { - return chatService.getSentInvites() + func getSentInvites(account: Account) -> [SentInvite] { + return chatService.getSentInvites(account: account) } func receivedInvitesSubscription() -> Stream<[ReceivedInvite]> { @@ -34,6 +34,10 @@ final class ChatListInteractor { return chatService.sentInvitePublisher } + func setupSubscriptions(account: Account) { + chatService.setupSubscriptions(account: account) + } + func logout() async throws { guard let importAccount = accountStorage.importAccount else { return } try await chatService.goPrivate(account: importAccount.account) diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListPresenter.swift b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListPresenter.swift index d2062d732..e44e516b8 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListPresenter.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/ChatList/ChatListPresenter.swift @@ -97,9 +97,11 @@ extension ChatListPresenter: SceneViewModel { private extension ChatListPresenter { func setupInitialState() { - threads = interactor.getThreads() - receivedInvites = interactor.getReceivedInvites() - sentInvites = interactor.getSentInvites() + interactor.setupSubscriptions(account: account) + + threads = interactor.getThreads(account: account) + receivedInvites = interactor.getReceivedInvites(account: account) + sentInvites = interactor.getSentInvites(account: account) interactor.threadsSubscription() .sink { [unowned self] threads in diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListInteractor.swift b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListInteractor.swift index f7043f7a1..0444c487d 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListInteractor.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListInteractor.swift @@ -7,12 +7,12 @@ final class InviteListInteractor { self.chatService = chatService } - func getReceivedInvites() -> [ReceivedInvite] { - return chatService.getReceivedInvites() + func getReceivedInvites(account: Account) -> [ReceivedInvite] { + return chatService.getReceivedInvites(account: account) } - func getSentInvites() -> [SentInvite] { - return chatService.getSentInvites() + func getSentInvites(account: Account) -> [SentInvite] { + return chatService.getSentInvites(account: account) } func receivedInvitesSubscription() -> Stream<[ReceivedInvite]> { diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListPresenter.swift b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListPresenter.swift index ca32fd3ea..69116cc9b 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListPresenter.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/InviteList/InviteListPresenter.swift @@ -71,8 +71,8 @@ extension InviteListPresenter: SceneViewModel { private extension InviteListPresenter { func setupInitialState() { - receivedInvites = interactor.getReceivedInvites() - sentInvites = interactor.getSentInvites() + receivedInvites = interactor.getReceivedInvites(account: account) + sentInvites = interactor.getSentInvites(account: account) interactor.receivedInvitesSubscription() .sink { [unowned self] receivedInvites in diff --git a/Sources/Chat/Chat.swift b/Sources/Chat/Chat.swift index a2c3f364a..24177a2ba 100644 --- a/Sources/Chat/Chat.swift +++ b/Sources/Chat/Chat.swift @@ -5,24 +5,11 @@ public class Chat { /// Chat client instance public static var instance: ChatClient = { - guard let account = account else { - fatalError("Error - you must call Chat.configure(_:) before accessing the shared instance.") - } return ChatClientFactory.create( - account: account, relayClient: Relay.instance, networkingInteractor: Networking.interactor ) }() - private static var account: Account? - private init() { } - - /// Chat instance config method - /// - Parameters: - /// - account: Chat initial account - static public func configure(account: Account) { - Chat.account = account - } } diff --git a/Sources/Chat/ChatClient.swift b/Sources/Chat/ChatClient.swift index 946742d21..543bfbe1d 100644 --- a/Sources/Chat/ChatClient.swift +++ b/Sources/Chat/ChatClient.swift @@ -5,7 +5,6 @@ public class ChatClient { private var publishers = [AnyCancellable]() private let identityClient: IdentityClient private let messagingService: MessagingService - private let accountService: AccountService private let resubscriptionService: ResubscriptionService private let invitationHandlingService: InvitationHandlingService private let inviteService: InviteService @@ -59,7 +58,6 @@ public class ChatClient { init(identityClient: IdentityClient, messagingService: MessagingService, - accountService: AccountService, resubscriptionService: ResubscriptionService, invitationHandlingService: InvitationHandlingService, inviteService: InviteService, @@ -70,7 +68,6 @@ public class ChatClient { ) { self.identityClient = identityClient self.messagingService = messagingService - self.accountService = accountService self.resubscriptionService = resubscriptionService self.invitationHandlingService = invitationHandlingService self.inviteService = inviteService @@ -93,8 +90,6 @@ public class ChatClient { ) async throws -> String { let publicKey = try await identityClient.register(account: account, onSign: onSign) - accountService.setAccount(account) - guard !isPrivate else { return publicKey } @@ -178,26 +173,23 @@ public class ChatClient { try await leaveService.leave(topic: topic) } - /// Sets peer account with public key - /// - Parameter account: CAIP10 blockachain account - /// - Parameter publicKey: Account associated publicKey hex string - public func setContact(account: Account, publicKey: String) async throws { - fatalError("not implemented") + public func getReceivedInvites(account: Account) -> [ReceivedInvite] { + return chatStorage.getReceivedInvites(account: account) } - public func getReceivedInvites() -> [ReceivedInvite] { - return chatStorage.getReceivedInvites(account: accountService.currentAccount) + public func getSentInvites(account: Account) -> [SentInvite] { + return chatStorage.getSentInvites(account: account) } - public func getSentInvites() -> [SentInvite] { - return chatStorage.getSentInvites(account: accountService.currentAccount) + public func getThreads(account: Account) -> [Thread] { + return chatStorage.getThreads(account: account) } - public func getThreads() -> [Thread] { - return chatStorage.getThreads(account: accountService.currentAccount) + public func getMessages(topic: String) -> [Message] { + return chatStorage.getMessages(topic: topic) } - public func getMessages(topic: String) -> [Message] { - return chatStorage.getMessages(topic: topic, account: accountService.currentAccount) + public func setupSubscriptions(account: Account) { + chatStorage.setupSubscriptions(account: account) } } diff --git a/Sources/Chat/ChatClientFactory.swift b/Sources/Chat/ChatClientFactory.swift index 40ac3f50a..1ab48e594 100644 --- a/Sources/Chat/ChatClientFactory.swift +++ b/Sources/Chat/ChatClientFactory.swift @@ -2,11 +2,10 @@ import Foundation public struct ChatClientFactory { - static func create(account: Account, relayClient: RelayClient, networkingInteractor: NetworkingInteractor) -> ChatClient { + static func create(relayClient: RelayClient, networkingInteractor: NetworkingInteractor) -> ChatClient { let keychain = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk") let keyserverURL = URL(string: "https://keys.walletconnect.com")! return ChatClientFactory.create( - account: account, keyserverURL: keyserverURL, relayClient: relayClient, networkingInteractor: networkingInteractor, @@ -17,7 +16,6 @@ public struct ChatClientFactory { } public static func create( - account: Account, keyserverURL: URL, relayClient: RelayClient, networkingInteractor: NetworkingInteractor, @@ -25,24 +23,22 @@ public struct ChatClientFactory { logger: ConsoleLogging, keyValueStorage: KeyValueStorage ) -> ChatClient { - let accountService = AccountService(currentAccount: account) let kms = KeyManagementService(keychain: keychain) let messageStore = KeyedDatabase(storage: keyValueStorage, identifier: ChatStorageIdentifiers.messages.rawValue) let receivedInviteStore = KeyedDatabase(storage: keyValueStorage, identifier: ChatStorageIdentifiers.receivedInvites.rawValue) let sentInviteStore = KeyedDatabase(storage: keyValueStorage, identifier: ChatStorageIdentifiers.sentInvites.rawValue) let threadStore = KeyedDatabase(storage: keyValueStorage, identifier: ChatStorageIdentifiers.threads.rawValue) - let chatStorage = ChatStorage(accountService: accountService, messageStore: messageStore, receivedInviteStore: receivedInviteStore, sentInviteStore: sentInviteStore, threadStore: threadStore) - let resubscriptionService = ResubscriptionService(networkingInteractor: networkingInteractor, kms: kms, accountService: accountService, chatStorage: chatStorage, logger: logger) + let chatStorage = ChatStorage(messageStore: messageStore, receivedInviteStore: receivedInviteStore, sentInviteStore: sentInviteStore, threadStore: threadStore) + let resubscriptionService = ResubscriptionService(networkingInteractor: networkingInteractor, kms: kms, chatStorage: chatStorage, logger: logger) let identityClient = IdentityClientFactory.create(keyserver: keyserverURL, keychain: keychain, logger: logger) - let invitationHandlingService = InvitationHandlingService(keyserverURL: keyserverURL, networkingInteractor: networkingInteractor, identityClient: identityClient, accountService: accountService, kms: kms, logger: logger, chatStorage: chatStorage) - let inviteService = InviteService(keyserverURL: keyserverURL, networkingInteractor: networkingInteractor, identityClient: identityClient, accountService: accountService, kms: kms, chatStorage: chatStorage, logger: logger) + let invitationHandlingService = InvitationHandlingService(keyserverURL: keyserverURL, networkingInteractor: networkingInteractor, identityClient: identityClient, kms: kms, logger: logger, chatStorage: chatStorage) + let inviteService = InviteService(keyserverURL: keyserverURL, networkingInteractor: networkingInteractor, identityClient: identityClient, kms: kms, chatStorage: chatStorage, logger: logger) let leaveService = LeaveService() - let messagingService = MessagingService(keyserverURL: keyserverURL, networkingInteractor: networkingInteractor, identityClient: identityClient, accountService: accountService, chatStorage: chatStorage, logger: logger) + let messagingService = MessagingService(keyserverURL: keyserverURL, networkingInteractor: networkingInteractor, identityClient: identityClient, chatStorage: chatStorage, logger: logger) let client = ChatClient( identityClient: identityClient, messagingService: messagingService, - accountService: accountService, resubscriptionService: resubscriptionService, invitationHandlingService: invitationHandlingService, inviteService: inviteService, diff --git a/Sources/Chat/ChatStorage.swift b/Sources/Chat/ChatStorage.swift index 0213a97ce..c26ed3e1f 100644 --- a/Sources/Chat/ChatStorage.swift +++ b/Sources/Chat/ChatStorage.swift @@ -3,8 +3,6 @@ import Combine final class ChatStorage { - private let accountService: AccountService - private let messageStore: KeyedDatabase private let receivedInviteStore: KeyedDatabase private let sentInviteStore: KeyedDatabase @@ -63,50 +61,42 @@ final class ChatStorage { rejectPublisherSubject.eraseToAnyPublisher() } - var currentAccount: Account { - return accountService.currentAccount - } - init( - accountService: AccountService, messageStore: KeyedDatabase, receivedInviteStore: KeyedDatabase, sentInviteStore: KeyedDatabase, threadStore: KeyedDatabase ) { - self.accountService = accountService self.messageStore = messageStore self.receivedInviteStore = receivedInviteStore self.sentInviteStore = sentInviteStore self.threadStore = threadStore - - setupSubscriptions() } - func setupSubscriptions() { + func setupSubscriptions(account: Account) { messageStore.onUpdate = { [unowned self] in - messagesPublisherSubject.send(getMessages(account: currentAccount)) + messagesPublisherSubject.send(getMessages(account: account)) } receivedInviteStore.onUpdate = { [unowned self] in - receivedInvitesPublisherSubject.send(getReceivedInvites(account: currentAccount)) + receivedInvitesPublisherSubject.send(getReceivedInvites(account: account)) } sentInviteStore.onUpdate = { [unowned self] in - sentInvitesPublisherSubject.send(getSentInvites(account: currentAccount)) + sentInvitesPublisherSubject.send(getSentInvites(account: account)) } threadStore.onUpdate = { [unowned self] in - threadsPublisherSubject.send(getThreads(account: currentAccount)) + threadsPublisherSubject.send(getThreads(account: account)) } } // MARK: - Invites - func getReceivedInvite(id: Int64, account: Account) -> ReceivedInvite? { - return receivedInviteStore.getElements(for: account.absoluteString) + func getReceivedInvite(id: Int64) -> ReceivedInvite? { + return receivedInviteStore.getAll() .first(where: { $0.id == id }) } - func getSentInvite(id: Int64, account: Account) -> SentInvite? { - return sentInviteStore.getElements(for: account.absoluteString) + func getSentInvite(id: Int64) -> SentInvite? { + return sentInviteStore.getAll() .first(where: { $0.id == id }) } @@ -143,7 +133,7 @@ final class ChatStorage { } func accept(sentInviteId: Int64, account: Account, topic: String) { - guard let invite = getSentInvite(id: sentInviteId, account: account) + guard let invite = getSentInvite(id: sentInviteId) else { return } sentInviteStore.delete(invite, for: account.absoluteString) @@ -155,7 +145,7 @@ final class ChatStorage { } func reject(sentInviteId: Int64, account: Account) { - guard let invite = getSentInvite(id: sentInviteId, account: account) + guard let invite = getSentInvite(id: sentInviteId) else { return } sentInviteStore.delete(invite, for: account.absoluteString) @@ -177,8 +167,8 @@ final class ChatStorage { return threadStore.getElements(for: account.absoluteString) } - func getThread(topic: String, account: Account) -> Thread? { - return getThreads(account: account).first(where: { $0.topic == topic }) + func getThread(topic: String) -> Thread? { + return getAllThreads().first(where: { $0.topic == topic }) } func set(thread: Thread, account: Account) { @@ -193,11 +183,11 @@ final class ChatStorage { newMessagePublisherSubject.send(message) } - func getMessages(account: Account) -> [Message] { - return messageStore.getElements(for: account.absoluteString) + func getMessages(topic: String) -> [Message] { + return messageStore.getAll().filter { $0.topic == topic } } - func getMessages(topic: String, account: Account) -> [Message] { - return messageStore.getElements(for: account.absoluteString).filter { $0.topic == topic } + func getMessages(account: Account) -> [Message] { + return messageStore.getElements(for: account.absoluteString) } } diff --git a/Sources/Chat/ProtocolServices/Accounts/AccountService.swift b/Sources/Chat/ProtocolServices/Accounts/AccountService.swift deleted file mode 100644 index e0343aa0d..000000000 --- a/Sources/Chat/ProtocolServices/Accounts/AccountService.swift +++ /dev/null @@ -1,14 +0,0 @@ -import Foundation - -final class AccountService { - - private(set) var currentAccount: Account - - init(currentAccount: Account) { - self.currentAccount = currentAccount - } - - func setAccount(_ account: Account) { - currentAccount = account - } -} diff --git a/Sources/Chat/ProtocolServices/Common/MessagingService.swift b/Sources/Chat/ProtocolServices/Common/MessagingService.swift index 4beaa3e27..554254e05 100644 --- a/Sources/Chat/ProtocolServices/Common/MessagingService.swift +++ b/Sources/Chat/ProtocolServices/Common/MessagingService.swift @@ -6,28 +6,21 @@ class MessagingService { private let keyserverURL: URL private let networkingInteractor: NetworkInteracting private let identityClient: IdentityClient - private let accountService: AccountService private let chatStorage: ChatStorage private let logger: ConsoleLogging private var publishers = [AnyCancellable]() - private var currentAccount: Account { - return accountService.currentAccount - } - init( keyserverURL: URL, networkingInteractor: NetworkInteracting, identityClient: IdentityClient, - accountService: AccountService, chatStorage: ChatStorage, logger: ConsoleLogging ) { self.keyserverURL = keyserverURL self.networkingInteractor = networkingInteractor self.identityClient = identityClient - self.accountService = accountService self.chatStorage = chatStorage self.logger = logger setUpResponseHandling() @@ -35,14 +28,15 @@ class MessagingService { } func send(topic: String, messageString: String) async throws { - guard let thread = chatStorage.getThread(topic: topic, account: currentAccount) else { + guard let thread = chatStorage.getThread(topic: topic) else { throw Errors.threadDoNotExist } let payload = MessagePayload(keyserver: keyserverURL, message: messageString, recipientAccount: thread.peerAccount) let wrapper = try identityClient.signAndCreateWrapper( payload: payload, - account: accountService.currentAccount + account: thread.selfAccount ) + let protocolMethod = ChatMessageProtocolMethod() let request = RPCRequest(method: protocolMethod.method, params: wrapper) try await networkingInteractor.request(request, topic: topic, protocolMethod: protocolMethod) @@ -113,8 +107,9 @@ private extension MessagingService { ) let wrapper = try identityClient.signAndCreateWrapper( payload: receiptPayload, - account: accountService.currentAccount + account: message.recipientAccount ) + let response = RPCResponse(id: payload.id, result: wrapper) try await networkingInteractor.respond( diff --git a/Sources/Chat/ProtocolServices/Common/ResubscriptionService.swift b/Sources/Chat/ProtocolServices/Common/ResubscriptionService.swift index b6afe3a9f..b2f87f7b6 100644 --- a/Sources/Chat/ProtocolServices/Common/ResubscriptionService.swift +++ b/Sources/Chat/ProtocolServices/Common/ResubscriptionService.swift @@ -4,7 +4,6 @@ import Combine class ResubscriptionService { private let networkingInteractor: NetworkInteracting private let kms: KeyManagementServiceProtocol - private let accountService: AccountService private let logger: ConsoleLogging private var chatStorage: ChatStorage private var publishers = [AnyCancellable]() @@ -12,13 +11,11 @@ class ResubscriptionService { init( networkingInteractor: NetworkInteracting, kms: KeyManagementServiceProtocol, - accountService: AccountService, chatStorage: ChatStorage, logger: ConsoleLogging ) { self.networkingInteractor = networkingInteractor self.kms = kms - self.accountService = accountService self.logger = logger self.chatStorage = chatStorage diff --git a/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift b/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift index 75fcffcb4..8970e693b 100644 --- a/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift +++ b/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift @@ -7,20 +7,14 @@ class InvitationHandlingService { private let networkingInteractor: NetworkInteracting private let identityClient: IdentityClient private let chatStorage: ChatStorage - private let accountService: AccountService private let logger: ConsoleLogging private let kms: KeyManagementService private var publishers = [AnyCancellable]() - private var currentAccount: Account { - return accountService.currentAccount - } - init( keyserverURL: URL, networkingInteractor: NetworkInteracting, identityClient: IdentityClient, - accountService: AccountService, kms: KeyManagementService, logger: ConsoleLogging, chatStorage: ChatStorage @@ -29,17 +23,16 @@ class InvitationHandlingService { self.kms = kms self.networkingInteractor = networkingInteractor self.identityClient = identityClient - self.accountService = accountService self.logger = logger self.chatStorage = chatStorage setUpRequestHandling() } func accept(inviteId: Int64) async throws -> String { - guard let invite = chatStorage.getReceivedInvite(id: inviteId, account: currentAccount) + guard let invite = chatStorage.getReceivedInvite(id: inviteId) else { throw Errors.inviteForIdNotFound } - let inviteePublicKey = try identityClient.getInviteKey(for: currentAccount) + let inviteePublicKey = try identityClient.getInviteKey(for: invite.inviteeAccount) let inviterPublicKey = try DIDKey(did: invite.inviterPublicKey).hexString let symmetricKey = try kms.performKeyAgreement(selfPublicKey: inviteePublicKey, peerPublicKey: inviterPublicKey) @@ -55,7 +48,7 @@ class InvitationHandlingService { ) let wrapper = try identityClient.signAndCreateWrapper( payload: payload, - account: currentAccount + account: invite.inviteeAccount ) try await networkingInteractor.respond( topic: acceptTopic, @@ -72,21 +65,21 @@ class InvitationHandlingService { let thread = Thread( topic: threadTopic, - selfAccount: currentAccount, + selfAccount: invite.inviteeAccount, peerAccount: invite.inviterAccount ) - chatStorage.set(thread: thread, account: currentAccount) - chatStorage.accept(receivedInvite: invite, account: currentAccount) + chatStorage.set(thread: thread, account: invite.inviteeAccount) + chatStorage.accept(receivedInvite: invite, account: invite.inviteeAccount) return thread.topic } func reject(inviteId: Int64) async throws { - guard let invite = chatStorage.getReceivedInvite(id: inviteId, account: currentAccount) + guard let invite = chatStorage.getReceivedInvite(id: inviteId) else { throw Errors.inviteForIdNotFound } - let inviteePublicKey = try identityClient.getInviteKey(for: currentAccount) + let inviteePublicKey = try identityClient.getInviteKey(for: invite.inviteeAccount) let inviterPublicKey = try DIDKey(did: invite.inviterPublicKey) let symmAgreementKey = try kms.performKeyAgreement(selfPublicKey: inviteePublicKey, peerPublicKey: inviterPublicKey.hexString) @@ -100,7 +93,7 @@ class InvitationHandlingService { reason: ChatError.userRejected ) - chatStorage.reject(receivedInvite: invite, account: currentAccount) + chatStorage.reject(receivedInvite: invite, account: invite.inviteeAccount) } } diff --git a/Sources/Chat/ProtocolServices/Inviter/InviteService.swift b/Sources/Chat/ProtocolServices/Inviter/InviteService.swift index bde61bb5f..3ae0b2745 100644 --- a/Sources/Chat/ProtocolServices/Inviter/InviteService.swift +++ b/Sources/Chat/ProtocolServices/Inviter/InviteService.swift @@ -7,7 +7,6 @@ class InviteService { private let keyserverURL: URL private let networkingInteractor: NetworkInteracting private let identityClient: IdentityClient - private let accountService: AccountService private let logger: ConsoleLogging private let kms: KeyManagementService private let chatStorage: ChatStorage @@ -16,7 +15,6 @@ class InviteService { keyserverURL: URL, networkingInteractor: NetworkInteracting, identityClient: IdentityClient, - accountService: AccountService, kms: KeyManagementService, chatStorage: ChatStorage, logger: ConsoleLogging @@ -25,7 +23,6 @@ class InviteService { self.keyserverURL = keyserverURL self.networkingInteractor = networkingInteractor self.identityClient = identityClient - self.accountService = accountService self.logger = logger self.chatStorage = chatStorage setUpResponseHandling() @@ -51,8 +48,9 @@ class InviteService { ) let wrapper = try identityClient.signAndCreateWrapper( payload: payload, - account: accountService.currentAccount + account: invite.inviterAccount ) + let inviteId = RPCID() let request = RPCRequest(method: protocolMethod.method, params: wrapper, rpcid: inviteId) diff --git a/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift b/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift index 16979743b..1363b0c6a 100644 --- a/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift +++ b/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift @@ -18,15 +18,18 @@ final class ChatClientProxy { switch event { case .getReceivedInvites: - let invites = client.getReceivedInvites() + let params = try parse(GetReceivedInvitesRequest.self, params: request.params) + let invites = client.getReceivedInvites(account: params.account) try await respond(with: invites, request: request) case .getSentInvites: - let invites = client.getSentInvites() + let params = try parse(GetSentInvitesRequest.self, params: request.params) + let invites = client.getSentInvites(account: params.account) try await respond(with: invites, request: request) case .getThreads: - let threads = client.getThreads() + let params = try parse(GetThreadsRequest.self, params: request.params) + let threads = client.getThreads(account: params.account) try await respond(with: threads, request: request) case .register: @@ -84,6 +87,18 @@ private extension ChatClientProxy { let account: Account } + struct GetReceivedInvitesRequest: Codable { + let account: Account + } + + struct GetSentInvitesRequest: Codable { + let account: Account + } + + struct GetThreadsRequest: Codable { + let account: Account + } + struct GetMessagesRequest: Codable { let topic: String } diff --git a/Sources/Web3Inbox/Web3Inbox.swift b/Sources/Web3Inbox/Web3Inbox.swift index 8728f45dc..d8af0c263 100644 --- a/Sources/Web3Inbox/Web3Inbox.swift +++ b/Sources/Web3Inbox/Web3Inbox.swift @@ -19,7 +19,6 @@ public final class Web3Inbox { /// - Parameters: /// - account: Web3Inbox initial account static public func configure(account: Account, onSign: @escaping SigningCallback) { - Chat.configure(account: account) Web3Inbox.account = account Web3Inbox.onSign = onSign } From 0aa4e7b18b709e19adb7f156b2f3c21a226b2c29 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Mon, 27 Mar 2023 21:07:24 +0500 Subject: [PATCH 34/55] Inject keyserverUrl --- .../Classes/DomainLayer/Chat/ChatService.swift | 1 + Sources/Chat/Chat.swift | 13 +++++++++++++ Sources/Chat/ChatClientFactory.swift | 4 ++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift b/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift index addd4ab45..a55dc13b7 100644 --- a/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift +++ b/Example/Showcase/Classes/DomainLayer/Chat/ChatService.swift @@ -8,6 +8,7 @@ typealias Stream = AnyPublisher final class ChatService { private lazy var client: ChatClient = { + Chat.configure() return Chat.instance }() diff --git a/Sources/Chat/Chat.swift b/Sources/Chat/Chat.swift index 24177a2ba..9937d51ba 100644 --- a/Sources/Chat/Chat.swift +++ b/Sources/Chat/Chat.swift @@ -5,11 +5,24 @@ public class Chat { /// Chat client instance public static var instance: ChatClient = { + guard let keyserverUrl = keyserverUrl else { + fatalError("Error - you must call Chat.configure(_:) before accessing the shared instance.") + } return ChatClientFactory.create( + keyserverUrl: keyserverUrl, relayClient: Relay.instance, networkingInteractor: Networking.interactor ) }() + private static var keyserverUrl: String? + private init() { } + + /// Chat instance config method + /// - Parameters: + /// - account: Chat initial account + static public func configure(keyserverUrl: String = "https://keys.walletconnect.com") { + Chat.keyserverUrl = keyserverUrl + } } diff --git a/Sources/Chat/ChatClientFactory.swift b/Sources/Chat/ChatClientFactory.swift index 1ab48e594..a36b2cac5 100644 --- a/Sources/Chat/ChatClientFactory.swift +++ b/Sources/Chat/ChatClientFactory.swift @@ -2,9 +2,9 @@ import Foundation public struct ChatClientFactory { - static func create(relayClient: RelayClient, networkingInteractor: NetworkingInteractor) -> ChatClient { + static func create(keyserverUrl: String, relayClient: RelayClient, networkingInteractor: NetworkingInteractor) -> ChatClient { let keychain = KeychainStorage(serviceIdentifier: "com.walletconnect.sdk") - let keyserverURL = URL(string: "https://keys.walletconnect.com")! + let keyserverURL = URL(string: keyserverUrl)! return ChatClientFactory.create( keyserverURL: keyserverURL, relayClient: relayClient, From fc8ec9a084797839bc33bbc1c74d4e60eb231f27 Mon Sep 17 00:00:00 2001 From: Alexander Lisovyk Date: Tue, 28 Mar 2023 10:31:46 +0400 Subject: [PATCH 35/55] Add default environment --- Sources/Web3Wallet/Web3Wallet.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sources/Web3Wallet/Web3Wallet.swift b/Sources/Web3Wallet/Web3Wallet.swift index 2326009d8..a0ea0224a 100644 --- a/Sources/Web3Wallet/Web3Wallet.swift +++ b/Sources/Web3Wallet/Web3Wallet.swift @@ -36,7 +36,12 @@ public class Web3Wallet { /// - Parameters: /// - metadata: App metadata /// - signerFactory: Auth signers factory - static public func configure(metadata: AppMetadata, signerFactory: SignerFactory, echoHost: String = "echo.walletconnect.com", environment: APNSEnvironment) { + static public func configure( + metadata: AppMetadata, + signerFactory: SignerFactory, + echoHost: String = "echo.walletconnect.com", + environment: APNSEnvironment = .production + ) { Pair.configure(metadata: metadata) Auth.configure(signerFactory: signerFactory) let clientId = try! Networking.interactor.getClientId() From edecba6b6dd7a7161432188a0ff1132bca573068 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 28 Mar 2023 13:24:59 +0500 Subject: [PATCH 36/55] Web3Inbox fix --- Sources/Web3Inbox/ChatClient/ChatClientProxy.swift | 2 +- Sources/Web3Inbox/WebView/WebViewRequestSubscriber.swift | 2 +- Tests/ChatTests/RegistryServiceTests.swift | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift b/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift index 1363b0c6a..0166c5a36 100644 --- a/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift +++ b/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift @@ -112,7 +112,7 @@ private extension ChatClientProxy { } func parse(_ type: Request.Type, params: AnyCodable?) throws -> Request { - guard let params = try params?.get(Request.self) + guard let params = try params?.get([Request].self).first else { throw Errors.unregisteredParams } return params } diff --git a/Sources/Web3Inbox/WebView/WebViewRequestSubscriber.swift b/Sources/Web3Inbox/WebView/WebViewRequestSubscriber.swift index c09414e29..94fc39139 100644 --- a/Sources/Web3Inbox/WebView/WebViewRequestSubscriber.swift +++ b/Sources/Web3Inbox/WebView/WebViewRequestSubscriber.swift @@ -29,7 +29,7 @@ final class WebViewRequestSubscriber: NSObject, WKScriptMessageHandler { do { try await onRequest?(request) } catch { - logger.error("WebView Request error: \(error.localizedDescription)") + logger.error("WebView Request error: \(error.localizedDescription). Request: \(request)") } } } diff --git a/Tests/ChatTests/RegistryServiceTests.swift b/Tests/ChatTests/RegistryServiceTests.swift index 55c146430..949350b7c 100644 --- a/Tests/ChatTests/RegistryServiceTests.swift +++ b/Tests/ChatTests/RegistryServiceTests.swift @@ -41,15 +41,13 @@ final class RegistryServiceTests: XCTestCase { identityClient = IdentityClient(identityService: identitySevice, identityStorage: identityStorage, logger: ConsoleLoggerMock()) let storage = RuntimeKeyValueStorage() - let accountService = AccountService(currentAccount: account) let chatStorage = ChatStorage( - accountService: accountService, messageStore: .init(storage: storage, identifier: ""), receivedInviteStore: .init(storage: storage, identifier: ""), sentInviteStore: .init(storage: storage, identifier: ""), threadStore: .init(storage: storage, identifier: "") ) - resubscriptionService = ResubscriptionService(networkingInteractor: networkingInteractor, kms: kms, accountService: accountService, chatStorage: chatStorage, logger: ConsoleLoggerMock()) + resubscriptionService = ResubscriptionService(networkingInteractor: networkingInteractor, kms: kms, chatStorage: chatStorage, logger: ConsoleLoggerMock()) } func testRegister() async throws { From edf8c30e630fe63048aa08635530a0e69badf7a7 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 28 Mar 2023 14:00:02 +0500 Subject: [PATCH 37/55] Integration tests fixed --- Example/IntegrationTests/Chat/ChatTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/IntegrationTests/Chat/ChatTests.swift b/Example/IntegrationTests/Chat/ChatTests.swift index 116718414..00c9b0bc9 100644 --- a/Example/IntegrationTests/Chat/ChatTests.swift +++ b/Example/IntegrationTests/Chat/ChatTests.swift @@ -35,7 +35,7 @@ final class ChatTests: XCTestCase { logger: logger, keychainStorage: keychain, keyValueStorage: keyValueStorage) - return ChatClientFactory.create(account: account, keyserverURL: keyserverURL, relayClient: relayClient, networkingInteractor: networkingInteractor, keychain: keychain, logger: logger, keyValueStorage: keyValueStorage) + return ChatClientFactory.create(keyserverURL: keyserverURL, relayClient: relayClient, networkingInteractor: networkingInteractor, keychain: keychain, logger: logger, keyValueStorage: keyValueStorage) } func testInvite() async throws { From 3a527eca3fb7dd17c67c255d9fef78a2fbce700d Mon Sep 17 00:00:00 2001 From: Alexander Lisovyk Date: Wed, 29 Mar 2023 13:42:21 +0400 Subject: [PATCH 38/55] Increase RPCID enptory --- Sources/JSONRPC/RPCID.swift | 6 +++--- Sources/WalletConnectRelay/RPC/WalletConnectRPCID.swift | 4 ++-- Sources/WalletConnectUtils/JsonRecID.swift | 6 +++--- Tests/WalletConnectSignTests/WCResponseTests.swift | 5 +++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Sources/JSONRPC/RPCID.swift b/Sources/JSONRPC/RPCID.swift index 234a4dd23..3a251872d 100644 --- a/Sources/JSONRPC/RPCID.swift +++ b/Sources/JSONRPC/RPCID.swift @@ -9,8 +9,8 @@ public protocol IdentifierGenerator { struct IntIdentifierGenerator: IdentifierGenerator { func next() -> RPCID { - let timestamp = Int64(Date().timeIntervalSince1970 * 1000) * 1000 - let random = Int64.random(in: 0..<1000) + let timestamp = Int64(Date().timeIntervalSince1970 * 1000) * 1000000 + let random = Int64.random(in: 0..<1000000) return RPCID(timestamp + random) } } @@ -41,7 +41,7 @@ extension RPCID { public var timestamp: Date { guard let id = self.right else { return .distantPast } - let interval = TimeInterval(id / 1000 / 1000) + let interval = TimeInterval(id / 1000 / 1000000) return Date(timeIntervalSince1970: interval) } } diff --git a/Sources/WalletConnectRelay/RPC/WalletConnectRPCID.swift b/Sources/WalletConnectRelay/RPC/WalletConnectRPCID.swift index 290576b9e..aa84175f5 100644 --- a/Sources/WalletConnectRelay/RPC/WalletConnectRPCID.swift +++ b/Sources/WalletConnectRelay/RPC/WalletConnectRPCID.swift @@ -3,8 +3,8 @@ import Foundation struct WalletConnectRPCID: IdentifierGenerator { func next() -> RPCID { - let timestamp = Int64(Date().timeIntervalSince1970 * 1000) * 1000 - let random = Int64.random(in: 0..<1000) + let timestamp = Int64(Date().timeIntervalSince1970 * 1000) * 1000000 + let random = Int64.random(in: 0..<1000000) return .right(Int64(timestamp + random)) } } diff --git a/Sources/WalletConnectUtils/JsonRecID.swift b/Sources/WalletConnectUtils/JsonRecID.swift index 3907f5ab5..741ca8579 100644 --- a/Sources/WalletConnectUtils/JsonRecID.swift +++ b/Sources/WalletConnectUtils/JsonRecID.swift @@ -3,13 +3,13 @@ import Foundation public struct JsonRpcID { public static func generate() -> Int64 { - let timestamp = Int64(Date().timeIntervalSince1970 * 1000) * 1000 - let random = Int64.random(in: 0..<1000) + let timestamp = Int64(Date().timeIntervalSince1970 * 1000) * 1000000 + let random = Int64.random(in: 0..<1000000) return timestamp + random } public static func timestamp(from id: Int64) -> Date { - let interval = TimeInterval(id / 1000 / 1000) + let interval = TimeInterval(id / 1000 / 1000000) return Date(timeIntervalSince1970: interval) } } diff --git a/Tests/WalletConnectSignTests/WCResponseTests.swift b/Tests/WalletConnectSignTests/WCResponseTests.swift index b4d814d9e..8172bdfb5 100644 --- a/Tests/WalletConnectSignTests/WCResponseTests.swift +++ b/Tests/WalletConnectSignTests/WCResponseTests.swift @@ -7,8 +7,9 @@ final class RPCIDTests: XCTestCase { func testTimestamp() { let request = RPCRequest(method: "method") let response = RPCResponse(matchingRequest: request, error: JSONRPCError(code: 0, message: "message")) - let timestamp = Date(timeIntervalSince1970: TimeInterval(request.id!.right! / 1000 / 1000)) - + let timestamp = Date(timeIntervalSince1970: TimeInterval(request.id!.right! / 1000 / 1000000)) + + XCTAssertEqual(response.id!.right!.description.count, 19) XCTAssertEqual(response.id!.timestamp, timestamp) XCTAssertTrue(Calendar.current.isDateInToday(response.id!.timestamp)) } From 5dd6bf474f7b88c64f0324d9d311bb22c8356690 Mon Sep 17 00:00:00 2001 From: Alexander Lisovyk Date: Wed, 29 Mar 2023 16:50:27 +0400 Subject: [PATCH 39/55] Update client to js rpcid --- Sources/JSONRPC/RPCID.swift | 6 +++--- Sources/WalletConnectUtils/JsonRecID.swift | 6 +++--- Tests/WalletConnectSignTests/WCResponseTests.swift | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Sources/JSONRPC/RPCID.swift b/Sources/JSONRPC/RPCID.swift index 3a251872d..234a4dd23 100644 --- a/Sources/JSONRPC/RPCID.swift +++ b/Sources/JSONRPC/RPCID.swift @@ -9,8 +9,8 @@ public protocol IdentifierGenerator { struct IntIdentifierGenerator: IdentifierGenerator { func next() -> RPCID { - let timestamp = Int64(Date().timeIntervalSince1970 * 1000) * 1000000 - let random = Int64.random(in: 0..<1000000) + let timestamp = Int64(Date().timeIntervalSince1970 * 1000) * 1000 + let random = Int64.random(in: 0..<1000) return RPCID(timestamp + random) } } @@ -41,7 +41,7 @@ extension RPCID { public var timestamp: Date { guard let id = self.right else { return .distantPast } - let interval = TimeInterval(id / 1000 / 1000000) + let interval = TimeInterval(id / 1000 / 1000) return Date(timeIntervalSince1970: interval) } } diff --git a/Sources/WalletConnectUtils/JsonRecID.swift b/Sources/WalletConnectUtils/JsonRecID.swift index 741ca8579..3907f5ab5 100644 --- a/Sources/WalletConnectUtils/JsonRecID.swift +++ b/Sources/WalletConnectUtils/JsonRecID.swift @@ -3,13 +3,13 @@ import Foundation public struct JsonRpcID { public static func generate() -> Int64 { - let timestamp = Int64(Date().timeIntervalSince1970 * 1000) * 1000000 - let random = Int64.random(in: 0..<1000000) + let timestamp = Int64(Date().timeIntervalSince1970 * 1000) * 1000 + let random = Int64.random(in: 0..<1000) return timestamp + random } public static func timestamp(from id: Int64) -> Date { - let interval = TimeInterval(id / 1000 / 1000000) + let interval = TimeInterval(id / 1000 / 1000) return Date(timeIntervalSince1970: interval) } } diff --git a/Tests/WalletConnectSignTests/WCResponseTests.swift b/Tests/WalletConnectSignTests/WCResponseTests.swift index 8172bdfb5..fc3be3ae9 100644 --- a/Tests/WalletConnectSignTests/WCResponseTests.swift +++ b/Tests/WalletConnectSignTests/WCResponseTests.swift @@ -7,9 +7,9 @@ final class RPCIDTests: XCTestCase { func testTimestamp() { let request = RPCRequest(method: "method") let response = RPCResponse(matchingRequest: request, error: JSONRPCError(code: 0, message: "message")) - let timestamp = Date(timeIntervalSince1970: TimeInterval(request.id!.right! / 1000 / 1000000)) + let timestamp = Date(timeIntervalSince1970: TimeInterval(request.id!.right! / 1000 / 1000)) - XCTAssertEqual(response.id!.right!.description.count, 19) + XCTAssertEqual(response.id!.right!.description.count, 16) XCTAssertEqual(response.id!.timestamp, timestamp) XCTAssertTrue(Calendar.current.isDateInToday(response.id!.timestamp)) } From ec2a4984316d9529ad380f34e82498e9719b4e0f Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Wed, 29 Mar 2023 19:09:08 +0500 Subject: [PATCH 40/55] JWT Validator fix --- Sources/WalletConnectJWT/JWT.swift | 15 -------------- Sources/WalletConnectJWT/JWTDecodable.swift | 5 ++--- Sources/WalletConnectJWT/JWTValidator.swift | 22 +++++++++++++++++++++ Tests/RelayerTests/AuthTests/JWTTests.swift | 9 +++++++++ 4 files changed, 33 insertions(+), 18 deletions(-) create mode 100644 Sources/WalletConnectJWT/JWTValidator.swift diff --git a/Sources/WalletConnectJWT/JWT.swift b/Sources/WalletConnectJWT/JWT.swift index 0e6185469..f1eab051c 100644 --- a/Sources/WalletConnectJWT/JWT.swift +++ b/Sources/WalletConnectJWT/JWT.swift @@ -28,21 +28,6 @@ struct JWT: Codable, Equatable { self.signature = try jwtSigner.sign(header: headerString, claims: claimsString) } - func isValid(publicKey: SigningPublicKey) throws -> Bool { - guard let signature else { throw JWTError.noSignature } - - let headerString = try header.encode() - let claimsString = try claims.encode() - let unsignedJWT = [headerString, claimsString].joined(separator: ".") - - guard let unsignedData = unsignedJWT.data(using: .utf8) else { - throw JWTError.invalidJWTString - } - - let signatureData = try JWTEncoder.base64urlDecodedData(string: signature) - return publicKey.isValid(signature: signatureData, for: unsignedData) - } - func encoded() throws -> String { guard let signature = signature else { throw JWTError.jwtNotSigned } let headerString = try header.encode() diff --git a/Sources/WalletConnectJWT/JWTDecodable.swift b/Sources/WalletConnectJWT/JWTDecodable.swift index 58fe76ca6..f1931dd77 100644 --- a/Sources/WalletConnectJWT/JWTDecodable.swift +++ b/Sources/WalletConnectJWT/JWTDecodable.swift @@ -29,9 +29,8 @@ extension JWTClaimsCodable { let publicKey = try DIDKey(did: jwt.claims.iss) let signingPublicKey = try SigningPublicKey(rawRepresentation: publicKey.rawData) - guard try jwt.isValid(publicKey: signingPublicKey) else { - throw JWTError.signatureVerificationFailed - } + guard try JWTValidator(jwtString: wrapper.jwtString).isValid(publicKey: signingPublicKey) + else { throw JWTError.signatureVerificationFailed } return (try Self.init(claims: jwt.claims), jwt.claims) } diff --git a/Sources/WalletConnectJWT/JWTValidator.swift b/Sources/WalletConnectJWT/JWTValidator.swift new file mode 100644 index 000000000..e94a72bdf --- /dev/null +++ b/Sources/WalletConnectJWT/JWTValidator.swift @@ -0,0 +1,22 @@ +import Foundation + +struct JWTValidator { + + let jwtString: String + + func isValid(publicKey: SigningPublicKey) throws -> Bool { + var components = jwtString.components(separatedBy: ".") + + guard components.count == 3 else { throw JWTError.undefinedFormat } + + let signature = components.removeLast() + + guard let unsignedData = components + .joined(separator: ".") + .data(using: .utf8) + else { throw JWTError.invalidJWTString } + + let signatureData = try JWTEncoder.base64urlDecodedData(string: signature) + return publicKey.isValid(signature: signatureData, for: unsignedData) + } +} diff --git a/Tests/RelayerTests/AuthTests/JWTTests.swift b/Tests/RelayerTests/AuthTests/JWTTests.swift index de21300c5..83f8ebf4c 100644 --- a/Tests/RelayerTests/AuthTests/JWTTests.swift +++ b/Tests/RelayerTests/AuthTests/JWTTests.swift @@ -14,6 +14,15 @@ final class JWTTests: XCTestCase { let encoded = try! jwt.encoded() XCTAssertEqual(expectedJWT, encoded) } + + func testBase64Encoding() throws { + let signature = "gf8ZZb04-6DeqhboeA-I7EucdSVuLCJmKcPSTHJqG0CBfVKn0YihgosaD9-6gXED8Itrx5EsyEi49kLmTvS8DA" + + let data = try JWTEncoder.base64urlDecodedData(string: signature) + let string = JWTEncoder.base64urlEncodedString(data: data) + + XCTAssertEqual(signature, string) + } } extension RelayAuthPayload.Claims { From 28b620887d631d70f95fbb7d19c3ff7d1073a0e7 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Thu, 30 Mar 2023 12:23:23 +0200 Subject: [PATCH 41/55] Add multibase to did key --- Example/ExampleApp/AppDelegate.swift | 2 +- Example/IntegrationTests/Chat/RegistryTests.swift | 2 +- .../Configurator/ThirdPartyConfigurator.swift | 2 +- .../Invitee/InvitationHandlingService.swift | 2 +- Sources/Chat/Types/Payloads/AcceptPayload.swift | 2 +- Sources/Chat/Types/Payloads/InvitePayload.swift | 2 +- .../WalletConnectEcho/Register/EchoRegisterService.swift | 6 ++---- Sources/WalletConnectIdentity/IdentityService.swift | 2 +- .../WalletConnectIdentity/Types/InviteKeyPayload.swift | 2 +- .../Crypto/CryptoKitWrapper/AgreementCryptoKit.swift | 2 +- .../Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift | 2 +- .../WalletConnectRelay/ClientAuth/ClientIdStorage.swift | 2 +- Sources/WalletConnectUtils/DID/DIDKey.swift | 8 ++++++-- Tests/RelayerTests/AuthTests/ClientIdStorageTests.swift | 2 +- 14 files changed, 20 insertions(+), 18 deletions(-) diff --git a/Example/ExampleApp/AppDelegate.swift b/Example/ExampleApp/AppDelegate.swift index bdf63d927..ba40c5efa 100644 --- a/Example/ExampleApp/AppDelegate.swift +++ b/Example/ExampleApp/AppDelegate.swift @@ -22,7 +22,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { Networking.configure(projectId: InputConfig.projectId, socketFactory: DefaultSocketFactory()) Pair.configure(metadata: metadata) - Push.configure() + Push.configure(environment: .sandbox) Push.wallet.requestPublisher.sink { (id: RPCID, account: Account, metadata: AppMetadata) in Task(priority: .high) { try! await Push.wallet.approve(id: id) } }.store(in: &publishers) diff --git a/Example/IntegrationTests/Chat/RegistryTests.swift b/Example/IntegrationTests/Chat/RegistryTests.swift index ccaa03d1f..d98559981 100644 --- a/Example/IntegrationTests/Chat/RegistryTests.swift +++ b/Example/IntegrationTests/Chat/RegistryTests.swift @@ -35,7 +35,7 @@ final class RegistryTests: XCTestCase { func testRegisterIdentityAndInviteKey() async throws { let publicKey = try await sut.registerIdentity(account: account, onSign: onSign) - let iss = DIDKey(rawData: Data(hex: publicKey)).did(prefix: true, variant: .ED25519) + let iss = DIDKey(rawData: Data(hex: publicKey)).did(variant: .ED25519) let resolvedAccount = try await sut.resolveIdentity(iss: iss) XCTAssertEqual(resolvedAccount, account) diff --git a/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift index 876a7e701..512c560e3 100644 --- a/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift +++ b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift @@ -14,7 +14,7 @@ struct ThirdPartyConfigurator: Configurator { icons: ["https://avatars.githubusercontent.com/u/37784886"] ) - Web3Wallet.configure(metadata: metadata, signerFactory: DefaultSignerFactory(), environment: .sandbox) + Web3Wallet.configure(metadata: metadata, signerFactory: DefaultSignerFactory(), environment: BuildConfiguration.shared.apnsEnvironment) Push.configure(environment: BuildConfiguration.shared.apnsEnvironment) } diff --git a/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift b/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift index 75fcffcb4..4c7500460 100644 --- a/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift +++ b/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift @@ -122,7 +122,7 @@ private extension InvitationHandlingService { let inviterAccount = try await identityClient.resolveIdentity(iss: claims.iss) // TODO: Should we cache it? let inviteePublicKey = try await identityClient.resolveInvite(account: inviterAccount) - let inviterPublicKey = invite.inviterPublicKey.did(prefix: false, variant: .X25519) + let inviterPublicKey = invite.inviterPublicKey.multibase(variant: .ED25519) let invite = ReceivedInvite( id: payload.id.integer, diff --git a/Sources/Chat/Types/Payloads/AcceptPayload.swift b/Sources/Chat/Types/Payloads/AcceptPayload.swift index 97287eef4..10d2ed557 100644 --- a/Sources/Chat/Types/Payloads/AcceptPayload.swift +++ b/Sources/Chat/Types/Payloads/AcceptPayload.swift @@ -47,7 +47,7 @@ struct AcceptPayload: JWTClaimsCodable { exp: expiry(days: 30), ksu: keyserver.absoluteString, aud: inviterAccount.did, - sub: inviteePublicKey.did(prefix: true, variant: .X25519) + sub: inviteePublicKey.did(variant: .X25519) ) } } diff --git a/Sources/Chat/Types/Payloads/InvitePayload.swift b/Sources/Chat/Types/Payloads/InvitePayload.swift index c71b2b939..b0d3241e5 100644 --- a/Sources/Chat/Types/Payloads/InvitePayload.swift +++ b/Sources/Chat/Types/Payloads/InvitePayload.swift @@ -52,7 +52,7 @@ struct InvitePayload: JWTClaimsCodable { ksu: keyserver.absoluteString, aud: inviteeAccount.did, sub: message, - pke: inviterPublicKey.did(prefix: true, variant: .X25519) + pke: inviterPublicKey.did(variant: .X25519) ) } } diff --git a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift index 4076cc80a..dcf5588b7 100644 --- a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift +++ b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift @@ -9,10 +9,6 @@ actor EchoRegisterService { private let logger: ConsoleLogging private let environment: APNSEnvironment private let echoAuthenticator: EchoAuthenticating - // DID method specific identifier - private var clientIdMutlibase: String { - return clientId.replacingOccurrences(of: "did:key:", with: "") - } enum Errors: Error { case registrationFailed @@ -36,6 +32,7 @@ actor EchoRegisterService { let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) } let token = tokenParts.joined() let echoAuthToken = try echoAuthenticator.createAuthToken() + let clientIdMutlibase = try DIDKey(did: clientId).multibase(variant: .ED25519) logger.debug("APNS device token: \(token)") let response = try await httpClient.request( EchoResponse.self, @@ -50,6 +47,7 @@ actor EchoRegisterService { #if DEBUG public func register(deviceToken: String) async throws { let echoAuthToken = try echoAuthenticator.createAuthToken() + let clientIdMutlibase = try DIDKey(did: clientId).multibase(variant: .ED25519) let response = try await httpClient.request( EchoResponse.self, at: EchoAPI.register(clientId: clientIdMutlibase, token: deviceToken, projectId: projectId, environment: environment, auth: echoAuthToken) diff --git a/Sources/WalletConnectIdentity/IdentityService.swift b/Sources/WalletConnectIdentity/IdentityService.swift index e88536a50..faa729803 100644 --- a/Sources/WalletConnectIdentity/IdentityService.swift +++ b/Sources/WalletConnectIdentity/IdentityService.swift @@ -72,7 +72,7 @@ actor IdentityService { } func resolveIdentity(iss: String) async throws -> Account { - let did = try DIDKey(did: iss).did(prefix: false, variant: .ED25519) + let did = try DIDKey(did: iss).multibase(variant: .ED25519) let cacao = try await networkService.resolveIdentity(publicKey: did) return try Account(DIDPKHString: cacao.p.iss) } diff --git a/Sources/WalletConnectIdentity/Types/InviteKeyPayload.swift b/Sources/WalletConnectIdentity/Types/InviteKeyPayload.swift index e785ca1b0..b2a3f7a87 100644 --- a/Sources/WalletConnectIdentity/Types/InviteKeyPayload.swift +++ b/Sources/WalletConnectIdentity/Types/InviteKeyPayload.swift @@ -34,7 +34,7 @@ struct InviteKeyPayload: JWTClaimsCodable { func encode(iss: String) throws -> Claims { return Claims( iss: iss, - sub: invitePublicKey.did(prefix: true, variant: .X25519), + sub: invitePublicKey.did(variant: .X25519), aud: keyserver.absoluteString, iat: defaultIatMilliseconds(), exp: expiry(days: 30), diff --git a/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/AgreementCryptoKit.swift b/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/AgreementCryptoKit.swift index 5d11a2214..01f0ed2a2 100644 --- a/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/AgreementCryptoKit.swift +++ b/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/AgreementCryptoKit.swift @@ -44,7 +44,7 @@ public struct AgreementPublicKey: GenericPasswordConvertible, Equatable { public var did: String { let key = DIDKey(rawData: rawRepresentation) - return key.did(prefix: true, variant: .X25519) + return key.did(variant: .X25519) } } diff --git a/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift b/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift index e3bc6d37e..a6b0d3e19 100644 --- a/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift +++ b/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift @@ -47,7 +47,7 @@ public struct SigningPublicKey: GenericPasswordConvertible, Equatable { public var did: String { let key = DIDKey(rawData: rawRepresentation) - return key.did(prefix: true, variant: .ED25519) + return key.did(variant: .ED25519) } } diff --git a/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift b/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift index b2c1f6014..2e3c9cd7f 100644 --- a/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift +++ b/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift @@ -26,6 +26,6 @@ public struct ClientIdStorage: ClientIdStoring { public func getClientId() throws -> String { let privateKey: SigningPrivateKey = try keychain.read(key: key) let pubKey = privateKey.publicKey.rawRepresentation - return DIDKey(rawData: pubKey).did(prefix: true, variant: .ED25519) + return DIDKey(rawData: pubKey).did(variant: .ED25519) } } diff --git a/Sources/WalletConnectUtils/DID/DIDKey.swift b/Sources/WalletConnectUtils/DID/DIDKey.swift index 1fbfb1fb4..7b6e7be77 100644 --- a/Sources/WalletConnectUtils/DID/DIDKey.swift +++ b/Sources/WalletConnectUtils/DID/DIDKey.swift @@ -16,7 +16,11 @@ public struct DIDKey { return rawData.toHexString() } - public func did(prefix: Bool, variant: DIDKeyVariant) -> String { - return DIDKeyFactory().make(pubKey: rawData, variant: variant, prefix: prefix) + public func multibase(variant: DIDKeyVariant) -> String { + return DIDKeyFactory().make(pubKey: rawData, variant: variant, prefix: false) + } + + public func did(variant: DIDKeyVariant) -> String { + return DIDKeyFactory().make(pubKey: rawData, variant: variant, prefix: true) } } diff --git a/Tests/RelayerTests/AuthTests/ClientIdStorageTests.swift b/Tests/RelayerTests/AuthTests/ClientIdStorageTests.swift index eaf2ac5e2..05532fa8d 100644 --- a/Tests/RelayerTests/AuthTests/ClientIdStorageTests.swift +++ b/Tests/RelayerTests/AuthTests/ClientIdStorageTests.swift @@ -32,6 +32,6 @@ final class ClientIdStorageTests: XCTestCase { let clientId = try sut.getClientId() let didPublicKey = DIDKey(rawData: privateKey.publicKey.rawRepresentation) - XCTAssertEqual(clientId, didPublicKey.did(prefix: true, variant: .ED25519)) + XCTAssertEqual(clientId, didPublicKey.did(variant: .ED25519)) } } From e7e06239e07c1c9c6c0319b245310fa6d0f5e752 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Thu, 30 Mar 2023 13:12:52 +0200 Subject: [PATCH 42/55] rename http client header fields --- Sources/WalletConnectEcho/Register/EchoService.swift | 2 +- Sources/WalletConnectIdentity/IdentityKeyAPI.swift | 2 +- Sources/WalletConnectNetworking/HTTPClient/HTTPService.swift | 4 ++-- .../Signer/Ethereum/ContractCall/RPCService.swift | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/WalletConnectEcho/Register/EchoService.swift b/Sources/WalletConnectEcho/Register/EchoService.swift index e954de6a5..246f8b086 100644 --- a/Sources/WalletConnectEcho/Register/EchoService.swift +++ b/Sources/WalletConnectEcho/Register/EchoService.swift @@ -44,7 +44,7 @@ enum EchoAPI: HTTPService { return "https" } - var headerFields: [String : String]? { + var additionalHeaderFields: [String : String]? { switch self { case .register(_, _, _, _, let auth): return ["Authorization": auth] diff --git a/Sources/WalletConnectIdentity/IdentityKeyAPI.swift b/Sources/WalletConnectIdentity/IdentityKeyAPI.swift index 470b95b9c..f4833593a 100644 --- a/Sources/WalletConnectIdentity/IdentityKeyAPI.swift +++ b/Sources/WalletConnectIdentity/IdentityKeyAPI.swift @@ -51,7 +51,7 @@ enum IdentityKeyAPI: HTTPService { } } - var headerFields: [String : String]? { + var additionalHeaderFields: [String : String]? { return nil } } diff --git a/Sources/WalletConnectNetworking/HTTPClient/HTTPService.swift b/Sources/WalletConnectNetworking/HTTPClient/HTTPService.swift index 4c9c86eb4..46a8e53d7 100644 --- a/Sources/WalletConnectNetworking/HTTPClient/HTTPService.swift +++ b/Sources/WalletConnectNetworking/HTTPClient/HTTPService.swift @@ -12,7 +12,7 @@ public protocol HTTPService { var method: HTTPMethod { get } var body: Data? { get } var queryParameters: [String: String]? { get } - var headerFields: [String: String]? { get } + var additionalHeaderFields: [String: String]? { get } func resolve(for host: String) -> URLRequest? } @@ -35,7 +35,7 @@ public extension HTTPService { } var request = URLRequest(url: url) request.httpMethod = method.rawValue - headerFields?.forEach { + additionalHeaderFields?.forEach { request.addValue($0.value, forHTTPHeaderField: $0.key) } diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/RPCService.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/RPCService.swift index affda4701..eb6db47e7 100644 --- a/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/RPCService.swift +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/RPCService.swift @@ -28,7 +28,7 @@ struct RPCService: HTTPService { ] } - var headerFields: [String : String]? { + var additionalHeaderFields: [String : String]? { return nil } From e6873cc104c2f91d5d10ab79972b278d25861d52 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Thu, 30 Mar 2023 14:16:52 +0200 Subject: [PATCH 43/55] add review suggestion --- .../ProtocolServices/Invitee/InvitationHandlingService.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift b/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift index 4c7500460..a1f36bb39 100644 --- a/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift +++ b/Sources/Chat/ProtocolServices/Invitee/InvitationHandlingService.swift @@ -122,7 +122,7 @@ private extension InvitationHandlingService { let inviterAccount = try await identityClient.resolveIdentity(iss: claims.iss) // TODO: Should we cache it? let inviteePublicKey = try await identityClient.resolveInvite(account: inviterAccount) - let inviterPublicKey = invite.inviterPublicKey.multibase(variant: .ED25519) + let inviterPublicKey = invite.inviterPublicKey.did(variant: .X25519) let invite = ReceivedInvite( id: payload.id.integer, From 49a9452b6d4326fbb9653673449a6c6ebd558aaa Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Fri, 31 Mar 2023 15:28:12 +0500 Subject: [PATCH 44/55] web3Inbox fix --- Sources/Web3Inbox/ChatClient/ChatClientProxy.swift | 2 +- Sources/Web3Inbox/WebView/WebViewRequestSubscriber.swift | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift b/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift index 0166c5a36..1363b0c6a 100644 --- a/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift +++ b/Sources/Web3Inbox/ChatClient/ChatClientProxy.swift @@ -112,7 +112,7 @@ private extension ChatClientProxy { } func parse(_ type: Request.Type, params: AnyCodable?) throws -> Request { - guard let params = try params?.get([Request].self).first + guard let params = try params?.get(Request.self) else { throw Errors.unregisteredParams } return params } diff --git a/Sources/Web3Inbox/WebView/WebViewRequestSubscriber.swift b/Sources/Web3Inbox/WebView/WebViewRequestSubscriber.swift index 94fc39139..9d7df5a54 100644 --- a/Sources/Web3Inbox/WebView/WebViewRequestSubscriber.swift +++ b/Sources/Web3Inbox/WebView/WebViewRequestSubscriber.swift @@ -20,8 +20,7 @@ final class WebViewRequestSubscriber: NSObject, WKScriptMessageHandler { guard message.name == WebViewRequestSubscriber.name else { return } guard - let dict = message.body as? [String: Any], - let data = try? JSONSerialization.data(withJSONObject: dict), + let body = message.body as? String, let data = body.data(using: .utf8), let request = try? JSONDecoder().decode(RPCRequest.self, from: data) else { return } From 5a463e6b67df93282721e5188cffd8656e7ecdb1 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 28 Mar 2023 15:00:22 +0500 Subject: [PATCH 45/55] Structure --- Sources/Auth/Auth.swift | 6 +- Sources/Auth/AuthClientFactory.swift | 12 +-- Sources/Auth/AuthConfig.swift | 2 +- .../Services/App/AppRespondSubscriber.swift | 4 +- .../Signer/CryptoProvider.swift | 6 ++ .../Signer/ENSResolverFactory.swift | 8 +- .../Ethereum/EIP1271/EIP1271Verifier.swift | 8 +- .../Ethereum/EIP191/EIP191Verifier.swift | 10 +-- .../Signer/Ethereum/ENS/ENSResolver.swift | 10 +-- .../Signer/EthereumSigner.swift | 2 - .../Signer/Extensions/Data+EIP191.swift | 9 +++ .../Signer/MessageSigner.swift | 74 ++----------------- .../Signer/MessageSignerFactory.swift | 10 +-- .../Signer/MessageVerifier.swift | 45 +++++++++++ .../Signer/MessageVerifierFactory.swift | 18 +++++ 15 files changed, 115 insertions(+), 109 deletions(-) create mode 100644 Sources/WalletConnectSigner/Signer/CryptoProvider.swift create mode 100644 Sources/WalletConnectSigner/Signer/Extensions/Data+EIP191.swift create mode 100644 Sources/WalletConnectSigner/Signer/MessageVerifier.swift create mode 100644 Sources/WalletConnectSigner/Signer/MessageVerifierFactory.swift diff --git a/Sources/Auth/Auth.swift b/Sources/Auth/Auth.swift index 263e742e6..c3261ad34 100644 --- a/Sources/Auth/Auth.swift +++ b/Sources/Auth/Auth.swift @@ -22,7 +22,7 @@ public class Auth { return AuthClientFactory.create( metadata: Pair.metadata, projectId: Networking.projectId, - signerFactory: config.signerFactory, + crypto: config.crypto, networkingClient: Networking.interactor, pairingRegisterer: Pair.registerer ) @@ -35,7 +35,7 @@ public class Auth { /// Auth instance wallet config method. For DApp usage /// - Parameters: /// - signerFactory: Auth signers factory - static public func configure(signerFactory: SignerFactory) { - Auth.config = Auth.Config(signerFactory: signerFactory) + static public func configure(crypto: CryptoProvider) { + Auth.config = Auth.Config(crypto: crypto) } } diff --git a/Sources/Auth/AuthClientFactory.swift b/Sources/Auth/AuthClientFactory.swift index f9688eaf6..51b973a37 100644 --- a/Sources/Auth/AuthClientFactory.swift +++ b/Sources/Auth/AuthClientFactory.swift @@ -5,7 +5,7 @@ public struct AuthClientFactory { public static func create( metadata: AppMetadata, projectId: String, - signerFactory: SignerFactory, + crypto: CryptoProvider, networkingClient: NetworkingInteractor, pairingRegisterer: PairingRegisterer ) -> AuthClient { @@ -18,7 +18,7 @@ public struct AuthClientFactory { return AuthClientFactory.create( metadata: metadata, projectId: projectId, - signerFactory: signerFactory, + crypto: crypto, logger: logger, keyValueStorage: keyValueStorage, keychainStorage: keychainStorage, @@ -31,7 +31,7 @@ public struct AuthClientFactory { static func create( metadata: AppMetadata, projectId: String, - signerFactory: SignerFactory, + crypto: CryptoProvider, logger: ConsoleLogging, keyValueStorage: KeyValueStorage, keychainStorage: KeychainStorageProtocol, @@ -44,9 +44,9 @@ public struct AuthClientFactory { let history = RPCHistoryFactory.createForNetwork(keyValueStorage: keyValueStorage) let messageFormatter = SIWECacaoFormatter() let appRequestService = AppRequestService(networkingInteractor: networkingClient, kms: kms, appMetadata: metadata, logger: logger, iatProvader: iatProvider) - let messageSignerFactory = MessageSignerFactory(signerFactory: signerFactory) - let messageSigner = messageSignerFactory.create(projectId: projectId) - let appRespondSubscriber = AppRespondSubscriber(networkingInteractor: networkingClient, logger: logger, rpcHistory: history, signatureVerifier: messageSigner, pairingRegisterer: pairingRegisterer, messageFormatter: messageFormatter) + let messageVerifierFactory = MessageVerifierFactory(crypto: crypto) + let signatureVerifier = messageVerifierFactory.create(projectId: projectId) + let appRespondSubscriber = AppRespondSubscriber(networkingInteractor: networkingClient, logger: logger, rpcHistory: history, signatureVerifier: signatureVerifier, pairingRegisterer: pairingRegisterer, messageFormatter: messageFormatter) let walletErrorResponder = WalletErrorResponder(networkingInteractor: networkingClient, logger: logger, kms: kms, rpcHistory: history) let walletRequestSubscriber = WalletRequestSubscriber(networkingInteractor: networkingClient, logger: logger, kms: kms, walletErrorResponder: walletErrorResponder, pairingRegisterer: pairingRegisterer) let walletRespondService = WalletRespondService(networkingInteractor: networkingClient, logger: logger, kms: kms, rpcHistory: history, walletErrorResponder: walletErrorResponder) diff --git a/Sources/Auth/AuthConfig.swift b/Sources/Auth/AuthConfig.swift index bf5c09c24..183617159 100644 --- a/Sources/Auth/AuthConfig.swift +++ b/Sources/Auth/AuthConfig.swift @@ -2,6 +2,6 @@ import Foundation extension Auth { struct Config { - let signerFactory: SignerFactory + let crypto: CryptoProvider } } diff --git a/Sources/Auth/Services/App/AppRespondSubscriber.swift b/Sources/Auth/Services/App/AppRespondSubscriber.swift index 075b9f30d..0973e1cf1 100644 --- a/Sources/Auth/Services/App/AppRespondSubscriber.swift +++ b/Sources/Auth/Services/App/AppRespondSubscriber.swift @@ -5,7 +5,7 @@ class AppRespondSubscriber { private let networkingInteractor: NetworkInteracting private let logger: ConsoleLogging private let rpcHistory: RPCHistory - private let signatureVerifier: MessageSignatureVerifying + private let signatureVerifier: MessageVerifier private let messageFormatter: SIWECacaoFormatting private let pairingRegisterer: PairingRegisterer private var publishers = [AnyCancellable]() @@ -15,7 +15,7 @@ class AppRespondSubscriber { init(networkingInteractor: NetworkInteracting, logger: ConsoleLogging, rpcHistory: RPCHistory, - signatureVerifier: MessageSignatureVerifying, + signatureVerifier: MessageVerifier, pairingRegisterer: PairingRegisterer, messageFormatter: SIWECacaoFormatting) { self.networkingInteractor = networkingInteractor diff --git a/Sources/WalletConnectSigner/Signer/CryptoProvider.swift b/Sources/WalletConnectSigner/Signer/CryptoProvider.swift new file mode 100644 index 000000000..a04efbcff --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/CryptoProvider.swift @@ -0,0 +1,6 @@ +import Foundation + +public protocol CryptoProvider { + func recoverPubKey(signature: EthereumSignature, message: Data) throws -> Data + func keccak256(_ data: Data) -> Data +} diff --git a/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift b/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift index 3d95cd40d..0f85ada83 100644 --- a/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift +++ b/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift @@ -2,10 +2,10 @@ import Foundation public final class ENSResolverFactory { - public let signerFactory: SignerFactory + public let crypto: CryptoProvider - public init(signerFactory: SignerFactory) { - self.signerFactory = signerFactory + public init(crypto: CryptoProvider) { + self.crypto = crypto } public func create() -> ENSResolver { @@ -23,7 +23,7 @@ public final class ENSResolverFactory { projectId: projectId, httpClient: httpClient ), - signer: signerFactory.createEthereumSigner() + crypto: crypto ) } } diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift b/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift index 83a23d5c2..bd3c318da 100644 --- a/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift +++ b/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift @@ -3,16 +3,16 @@ import Foundation actor EIP1271Verifier { private let projectId: String private let httpClient: HTTPClient - private let signer: EthereumSigner + private let crypto: CryptoProvider - init(projectId: String, httpClient: HTTPClient, signer: EthereumSigner) { + init(projectId: String, httpClient: HTTPClient, crypto: CryptoProvider) { self.projectId = projectId self.httpClient = httpClient - self.signer = signer + self.crypto = crypto } func verify(signature: Data, message: Data, address: String, chainId: String) async throws { - let messageHash = signer.keccak256(message) + let messageHash = crypto.keccak256(message) let encoder = ValidSignatureMethod(signature: signature, messageHash: messageHash) let call = EthCall(to: address, data: encoder.encode()) let params = AnyCodable([AnyCodable(call), AnyCodable("latest")]) diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/EIP191/EIP191Verifier.swift b/Sources/WalletConnectSigner/Signer/Ethereum/EIP191/EIP191Verifier.swift index 9517e0831..57251d586 100644 --- a/Sources/WalletConnectSigner/Signer/Ethereum/EIP191/EIP191Verifier.swift +++ b/Sources/WalletConnectSigner/Signer/Ethereum/EIP191/EIP191Verifier.swift @@ -2,20 +2,20 @@ import Foundation actor EIP191Verifier { - let signer: EthereumSigner + let crypto: CryptoProvider - init(signer: EthereumSigner) { - self.signer = signer + init(crypto: CryptoProvider) { + self.crypto = crypto } func verify(signature: Data, message: Data, address: String) async throws { let sig = EthereumSignature(serialized: signature) - let publicKey = try signer.recoverPubKey(signature: sig, message: message) + let publicKey = try crypto.recoverPubKey(signature: sig, message: message) try verifyPublicKey(publicKey, address: address) } private func verifyPublicKey(_ publicKey: Data, address: String) throws { - let recovered = "0x" + signer.keccak256(publicKey) + let recovered = "0x" + crypto.keccak256(publicKey) .suffix(20) .toHexString() diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift index e1ee8d2e1..e59f1f2b3 100644 --- a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift +++ b/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift @@ -5,13 +5,13 @@ public actor ENSResolver { private let projectId: String private let httpClient: HTTPClient private let registry: ENSRegistryContract - private let signer: EthereumSigner + private let crypto: CryptoProvider - init(projectId: String, httpClient: HTTPClient, registry: ENSRegistryContract, signer: EthereumSigner) { + init(projectId: String, httpClient: HTTPClient, registry: ENSRegistryContract, crypto: CryptoProvider) { self.projectId = projectId self.httpClient = httpClient self.registry = registry - self.signer = signer + self.crypto = crypto } public func resolveEns(account: Account) async throws -> String { @@ -61,9 +61,9 @@ private extension ENSResolver { var result = [UInt8](repeating: 0, count: 32) let labels = name.split(separator: ".") for label in labels.reversed() { - let labelHash = signer.keccak256(label.lowercased().rawRepresentation) + let labelHash = crypto.keccak256(label.lowercased().rawRepresentation) result.append(contentsOf: labelHash) - result = [UInt8](signer.keccak256(Data(result))) + result = [UInt8](crypto.keccak256(Data(result))) } return Data(result) } diff --git a/Sources/WalletConnectSigner/Signer/EthereumSigner.swift b/Sources/WalletConnectSigner/Signer/EthereumSigner.swift index 9865b04c3..bf561ff88 100644 --- a/Sources/WalletConnectSigner/Signer/EthereumSigner.swift +++ b/Sources/WalletConnectSigner/Signer/EthereumSigner.swift @@ -2,6 +2,4 @@ import Foundation public protocol EthereumSigner { func sign(message: Data, with key: Data) throws -> EthereumSignature - func recoverPubKey(signature: EthereumSignature, message: Data) throws -> Data - func keccak256(_ data: Data) -> Data } diff --git a/Sources/WalletConnectSigner/Signer/Extensions/Data+EIP191.swift b/Sources/WalletConnectSigner/Signer/Extensions/Data+EIP191.swift new file mode 100644 index 000000000..7c6b27132 --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/Extensions/Data+EIP191.swift @@ -0,0 +1,9 @@ +import Foundation + +extension Data { + + public var prefixed: Data { + return "\u{19}Ethereum Signed Message:\n\(count)" + .data(using: .utf8)! + self + } +} diff --git a/Sources/WalletConnectSigner/Signer/MessageSigner.swift b/Sources/WalletConnectSigner/Signer/MessageSigner.swift index 83db2d9b2..b1c8efc4c 100644 --- a/Sources/WalletConnectSigner/Signer/MessageSigner.swift +++ b/Sources/WalletConnectSigner/Signer/MessageSigner.swift @@ -1,47 +1,20 @@ import Foundation -public protocol MessageSignatureVerifying { - func verify(signature: CacaoSignature, - message: String, - address: String, - chainId: String - ) async throws -} - -public protocol MessageSigning { - func sign(message: String, - privateKey: Data, - type: CacaoSignatureType - ) throws -> CacaoSignature - - func sign(payload: CacaoPayload, - privateKey: Data, - type: CacaoSignatureType - ) throws -> CacaoSignature -} - -// TODO: Fix naming -public typealias CacaoMessageSigner = MessageSignatureVerifying & MessageSigning - -struct MessageSigner: CacaoMessageSigner { +public struct MessageSigner { enum Errors: Error { case utf8EncodingFailed } private let signer: EthereumSigner - private let eip191Verifier: EIP191Verifier - private let eip1271Verifier: EIP1271Verifier private let messageFormatter: SIWECacaoFormatting - init(signer: EthereumSigner, eip191Verifier: EIP191Verifier, eip1271Verifier: EIP1271Verifier, messageFormatter: SIWECacaoFormatting) { + init(signer: EthereumSigner, messageFormatter: SIWECacaoFormatting) { self.signer = signer - self.eip191Verifier = eip191Verifier - self.eip1271Verifier = eip1271Verifier self.messageFormatter = messageFormatter } - func sign(payload: CacaoPayload, + public func sign(payload: CacaoPayload, privateKey: Data, type: CacaoSignatureType ) throws -> CacaoSignature { @@ -50,7 +23,7 @@ struct MessageSigner: CacaoMessageSigner { return try sign(message: message, privateKey: privateKey, type: type) } - func sign(message: String, + public func sign(message: String, privateKey: Data, type: CacaoSignatureType ) throws -> CacaoSignature { @@ -59,44 +32,7 @@ struct MessageSigner: CacaoMessageSigner { throw Errors.utf8EncodingFailed } - let signature = try signer.sign(message: prefixed(messageData), with: privateKey) + let signature = try signer.sign(message: messageData.prefixed, with: privateKey) return CacaoSignature(t: type, s: signature.hex()) } - - func verify(signature: CacaoSignature, - message: String, - address: String, - chainId: String - ) async throws { - - guard let messageData = message.data(using: .utf8) else { - throw Errors.utf8EncodingFailed - } - - let signatureData = Data(hex: signature.s) - - switch signature.t { - case .eip191: - return try await eip191Verifier.verify( - signature: signatureData, - message: prefixed(messageData), - address: address - ) - case .eip1271: - return try await eip1271Verifier.verify( - signature: signatureData, - message: prefixed(messageData), - address: address, - chainId: chainId - ) - } - } -} - -private extension MessageSigner { - - private func prefixed(_ message: Data) -> Data { - return "\u{19}Ethereum Signed Message:\n\(message.count)" - .data(using: .utf8)! + message - } } diff --git a/Sources/WalletConnectSigner/Signer/MessageSignerFactory.swift b/Sources/WalletConnectSigner/Signer/MessageSignerFactory.swift index ef4f53879..a5f739a88 100644 --- a/Sources/WalletConnectSigner/Signer/MessageSignerFactory.swift +++ b/Sources/WalletConnectSigner/Signer/MessageSignerFactory.swift @@ -8,19 +8,13 @@ public struct MessageSignerFactory { self.signerFactory = signerFactory } - public func create() -> CacaoMessageSigner { + public func create() -> MessageSigner { return create(projectId: Networking.projectId) } - public func create(projectId: String) -> CacaoMessageSigner { + public func create(projectId: String) -> MessageSigner { return MessageSigner( signer: signerFactory.createEthereumSigner(), - eip191Verifier: EIP191Verifier(signer: signerFactory.createEthereumSigner()), - eip1271Verifier: EIP1271Verifier( - projectId: projectId, - httpClient: HTTPNetworkClient(host: "rpc.walletconnect.com"), - signer: signerFactory.createEthereumSigner() - ), messageFormatter: SIWECacaoFormatter() ) } diff --git a/Sources/WalletConnectSigner/Signer/MessageVerifier.swift b/Sources/WalletConnectSigner/Signer/MessageVerifier.swift new file mode 100644 index 000000000..66b24ef8a --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/MessageVerifier.swift @@ -0,0 +1,45 @@ +import Foundation + +public struct MessageVerifier { + + enum Errors: Error { + case utf8EncodingFailed + } + + private let eip191Verifier: EIP191Verifier + private let eip1271Verifier: EIP1271Verifier + + init(eip191Verifier: EIP191Verifier, eip1271Verifier: EIP1271Verifier) { + self.eip191Verifier = eip191Verifier + self.eip1271Verifier = eip1271Verifier + } + + public func verify(signature: CacaoSignature, + message: String, + address: String, + chainId: String + ) async throws { + + guard let messageData = message.data(using: .utf8) else { + throw Errors.utf8EncodingFailed + } + + let signatureData = Data(hex: signature.s) + + switch signature.t { + case .eip191: + return try await eip191Verifier.verify( + signature: signatureData, + message: messageData.prefixed, + address: address + ) + case .eip1271: + return try await eip1271Verifier.verify( + signature: signatureData, + message: messageData.prefixed, + address: address, + chainId: chainId + ) + } + } +} diff --git a/Sources/WalletConnectSigner/Signer/MessageVerifierFactory.swift b/Sources/WalletConnectSigner/Signer/MessageVerifierFactory.swift new file mode 100644 index 000000000..2dcc4255c --- /dev/null +++ b/Sources/WalletConnectSigner/Signer/MessageVerifierFactory.swift @@ -0,0 +1,18 @@ +import Foundation + +public struct MessageVerifierFactory { + + public let crypto: CryptoProvider + + public init(crypto: CryptoProvider) { + self.crypto = crypto + } + + public func create() -> MessageVerifier { + return create(projectId: Networking.projectId) + } + + public func create(projectId: String) -> MessageVerifier { + return MessageVerifier(eip191Verifier: EIP191Verifier(crypto: crypto), eip1271Verifier: EIP1271Verifier(projectId: projectId, httpClient: HTTPNetworkClient(host: "rpc.walletconnect.com"), crypto: crypto)) + } +} From cac0515614bbddfc06a2ebb2fb33020be0a33996 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 28 Mar 2023 15:04:52 +0500 Subject: [PATCH 46/55] WalletConnectSigner file structure --- Sources/WalletConnectSigner/{Signer => }/CryptoProvider.swift | 0 .../{Signer => }/Ethereum/ContractCall/ContractDecoder.swift | 0 .../{Signer => }/Ethereum/ContractCall/ContractEncoder.swift | 0 .../{Signer => }/Ethereum/ContractCall/EthCall.swift | 0 .../{Signer => }/Ethereum/ContractCall/RPCService.swift | 0 .../{Signer => }/Ethereum/EIP1271/EIP1271Verifier.swift | 0 .../{Signer => }/Ethereum/EIP1271/ValidSignatureMethod.swift | 0 .../{Signer => }/Ethereum/EIP191/EIP191Verifier.swift | 0 .../{Signer => }/Ethereum/ENS/ENSAddressMethod.swift | 0 .../{Signer => }/Ethereum/ENS/ENSNameMethod.swift | 0 .../{Signer => }/Ethereum/ENS/ENSRegistryContract.swift | 0 .../{Signer => }/Ethereum/ENS/ENSResolver.swift | 0 .../{Signer => }/Ethereum/ENS/ENSResolverContract.swift | 0 .../{Signer => Ethereum/ENS}/ENSResolverFactory.swift | 0 .../{Signer => }/Ethereum/ENS/ENSResolverMethod.swift | 0 .../WalletConnectSigner/{Signer => }/Extensions/Data+EIP191.swift | 0 .../{Signer => Verifier}/MessageVerifier.swift | 0 .../{Signer => Verifier}/MessageVerifierFactory.swift | 0 18 files changed, 0 insertions(+), 0 deletions(-) rename Sources/WalletConnectSigner/{Signer => }/CryptoProvider.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/ContractCall/ContractDecoder.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/ContractCall/ContractEncoder.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/ContractCall/EthCall.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/ContractCall/RPCService.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/EIP1271/EIP1271Verifier.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/EIP1271/ValidSignatureMethod.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/EIP191/EIP191Verifier.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/ENS/ENSAddressMethod.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/ENS/ENSNameMethod.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/ENS/ENSRegistryContract.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/ENS/ENSResolver.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/ENS/ENSResolverContract.swift (100%) rename Sources/WalletConnectSigner/{Signer => Ethereum/ENS}/ENSResolverFactory.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Ethereum/ENS/ENSResolverMethod.swift (100%) rename Sources/WalletConnectSigner/{Signer => }/Extensions/Data+EIP191.swift (100%) rename Sources/WalletConnectSigner/{Signer => Verifier}/MessageVerifier.swift (100%) rename Sources/WalletConnectSigner/{Signer => Verifier}/MessageVerifierFactory.swift (100%) diff --git a/Sources/WalletConnectSigner/Signer/CryptoProvider.swift b/Sources/WalletConnectSigner/CryptoProvider.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/CryptoProvider.swift rename to Sources/WalletConnectSigner/CryptoProvider.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/ContractDecoder.swift b/Sources/WalletConnectSigner/Ethereum/ContractCall/ContractDecoder.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/ContractDecoder.swift rename to Sources/WalletConnectSigner/Ethereum/ContractCall/ContractDecoder.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/ContractEncoder.swift b/Sources/WalletConnectSigner/Ethereum/ContractCall/ContractEncoder.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/ContractEncoder.swift rename to Sources/WalletConnectSigner/Ethereum/ContractCall/ContractEncoder.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/EthCall.swift b/Sources/WalletConnectSigner/Ethereum/ContractCall/EthCall.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/EthCall.swift rename to Sources/WalletConnectSigner/Ethereum/ContractCall/EthCall.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/RPCService.swift b/Sources/WalletConnectSigner/Ethereum/ContractCall/RPCService.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/ContractCall/RPCService.swift rename to Sources/WalletConnectSigner/Ethereum/ContractCall/RPCService.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift b/Sources/WalletConnectSigner/Ethereum/EIP1271/EIP1271Verifier.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/EIP1271Verifier.swift rename to Sources/WalletConnectSigner/Ethereum/EIP1271/EIP1271Verifier.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift b/Sources/WalletConnectSigner/Ethereum/EIP1271/ValidSignatureMethod.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/EIP1271/ValidSignatureMethod.swift rename to Sources/WalletConnectSigner/Ethereum/EIP1271/ValidSignatureMethod.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/EIP191/EIP191Verifier.swift b/Sources/WalletConnectSigner/Ethereum/EIP191/EIP191Verifier.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/EIP191/EIP191Verifier.swift rename to Sources/WalletConnectSigner/Ethereum/EIP191/EIP191Verifier.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSAddressMethod.swift b/Sources/WalletConnectSigner/Ethereum/ENS/ENSAddressMethod.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSAddressMethod.swift rename to Sources/WalletConnectSigner/Ethereum/ENS/ENSAddressMethod.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSNameMethod.swift b/Sources/WalletConnectSigner/Ethereum/ENS/ENSNameMethod.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSNameMethod.swift rename to Sources/WalletConnectSigner/Ethereum/ENS/ENSNameMethod.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSRegistryContract.swift b/Sources/WalletConnectSigner/Ethereum/ENS/ENSRegistryContract.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSRegistryContract.swift rename to Sources/WalletConnectSigner/Ethereum/ENS/ENSRegistryContract.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift b/Sources/WalletConnectSigner/Ethereum/ENS/ENSResolver.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolver.swift rename to Sources/WalletConnectSigner/Ethereum/ENS/ENSResolver.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverContract.swift b/Sources/WalletConnectSigner/Ethereum/ENS/ENSResolverContract.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverContract.swift rename to Sources/WalletConnectSigner/Ethereum/ENS/ENSResolverContract.swift diff --git a/Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift b/Sources/WalletConnectSigner/Ethereum/ENS/ENSResolverFactory.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/ENSResolverFactory.swift rename to Sources/WalletConnectSigner/Ethereum/ENS/ENSResolverFactory.swift diff --git a/Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverMethod.swift b/Sources/WalletConnectSigner/Ethereum/ENS/ENSResolverMethod.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Ethereum/ENS/ENSResolverMethod.swift rename to Sources/WalletConnectSigner/Ethereum/ENS/ENSResolverMethod.swift diff --git a/Sources/WalletConnectSigner/Signer/Extensions/Data+EIP191.swift b/Sources/WalletConnectSigner/Extensions/Data+EIP191.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/Extensions/Data+EIP191.swift rename to Sources/WalletConnectSigner/Extensions/Data+EIP191.swift diff --git a/Sources/WalletConnectSigner/Signer/MessageVerifier.swift b/Sources/WalletConnectSigner/Verifier/MessageVerifier.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/MessageVerifier.swift rename to Sources/WalletConnectSigner/Verifier/MessageVerifier.swift diff --git a/Sources/WalletConnectSigner/Signer/MessageVerifierFactory.swift b/Sources/WalletConnectSigner/Verifier/MessageVerifierFactory.swift similarity index 100% rename from Sources/WalletConnectSigner/Signer/MessageVerifierFactory.swift rename to Sources/WalletConnectSigner/Verifier/MessageVerifierFactory.swift From 943cca94cfa888da4c56d53d32f92df8f9be20aa Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 28 Mar 2023 15:24:13 +0500 Subject: [PATCH 47/55] Integration tests repaired --- Example/ExampleApp.xcodeproj/project.pbxproj | 10 ++++++ Example/IntegrationTests/Auth/AuthTests.swift | 2 +- .../Auth/ENS/ENSResolverTests.swift | 4 +-- .../Auth/Signer/CacaoSignerTests.swift | 3 +- .../Auth/Signer/EIP1271VerifierTests.swift | 6 ++-- .../Auth/Signer/EIP191VerifierTests.swift | 2 +- .../IntegrationTests/Chat/RegistryTests.swift | 2 +- Example/Shared/DefaultCryptoProvider.swift | 23 +++++++++++++ Example/Shared/DefaultSignerFactory.swift | 16 --------- Sources/Web3Wallet/Web3Wallet.swift | 8 ++--- Sources/Web3Wallet/Web3WalletConfig.swift | 2 +- .../AuthTests/AppRespondSubscriberTests.swift | 6 ++-- Tests/AuthTests/Stubs/MessageSignerMock.swift | 34 +++++++++++-------- 13 files changed, 69 insertions(+), 49 deletions(-) create mode 100644 Example/Shared/DefaultCryptoProvider.swift diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 1b0cd5522..bdbf7d999 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -173,6 +173,10 @@ A59CF4F6292F83D50031A42F /* DefaultSignerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */; }; A59F877628B5462900A9CD80 /* WalletConnectAuth in Frameworks */ = {isa = PBXBuildFile; productRef = A59F877528B5462900A9CD80 /* WalletConnectAuth */; }; A59FAEC928B7B93A002BB66F /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = A59FAEC828B7B93A002BB66F /* Web3 */; }; + A5A0843D29D2F624000B9B17 /* DefaultCryptoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A0843B29D2F60A000B9B17 /* DefaultCryptoProvider.swift */; }; + A5A0843E29D2F624000B9B17 /* DefaultCryptoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A0843B29D2F60A000B9B17 /* DefaultCryptoProvider.swift */; }; + A5A0843F29D2F625000B9B17 /* DefaultCryptoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A0843B29D2F60A000B9B17 /* DefaultCryptoProvider.swift */; }; + A5A0844029D2F626000B9B17 /* DefaultCryptoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A0843B29D2F60A000B9B17 /* DefaultCryptoProvider.swift */; }; A5A4FC56283CBB7800BBEC1E /* SessionDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A4FC55283CBB7800BBEC1E /* SessionDetailView.swift */; }; A5A4FC58283CBB9F00BBEC1E /* SessionDetailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A4FC57283CBB9F00BBEC1E /* SessionDetailViewModel.swift */; }; A5A4FC5A283CC08600BBEC1E /* SessionNamespaceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5A4FC59283CC08600BBEC1E /* SessionNamespaceViewModel.swift */; }; @@ -522,6 +526,7 @@ A58E7D472872EF610082D443 /* MessageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageViewModel.swift; sourceTree = ""; }; A58EC615299D5C6400F3452A /* PlainButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlainButton.swift; sourceTree = ""; }; A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultSignerFactory.swift; sourceTree = ""; }; + A5A0843B29D2F60A000B9B17 /* DefaultCryptoProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultCryptoProvider.swift; sourceTree = ""; }; A5A4FC55283CBB7800BBEC1E /* SessionDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionDetailView.swift; sourceTree = ""; }; A5A4FC57283CBB9F00BBEC1E /* SessionDetailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionDetailViewModel.swift; sourceTree = ""; }; A5A4FC59283CC08600BBEC1E /* SessionNamespaceViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionNamespaceViewModel.swift; sourceTree = ""; }; @@ -1395,6 +1400,7 @@ 84CB43D429B9FC88004DDA31 /* Tests */, A5629AEF2877F73000094373 /* DefaultSocketFactory.swift */, A59CF4F5292F83D50031A42F /* DefaultSignerFactory.swift */, + A5A0843B29D2F60A000B9B17 /* DefaultCryptoProvider.swift */, ); path = Shared; sourceTree = ""; @@ -2208,6 +2214,7 @@ A5BB7FA928B6A5FD00707FC6 /* AuthViewModel.swift in Sources */, 84CE6452279ED42B00142511 /* ConnectView.swift in Sources */, A5A8E47E293A1CFE00FEB97D /* DefaultSignerFactory.swift in Sources */, + A5A0843D29D2F624000B9B17 /* DefaultCryptoProvider.swift in Sources */, 84CE6448279AE68600142511 /* AccountRequestViewController.swift in Sources */, A5BB7F9F28B69B7100707FC6 /* SignCoordinator.swift in Sources */, 84CE642127981DED00142511 /* SceneDelegate.swift in Sources */, @@ -2261,6 +2268,7 @@ A578FA35287304A300AA7720 /* Color.swift in Sources */, A5629ADE2876CC6E00094373 /* InviteListModule.swift in Sources */, A578FA322873036400AA7720 /* InputView.swift in Sources */, + A5A0843F29D2F625000B9B17 /* DefaultCryptoProvider.swift in Sources */, A5C2021B287E1FD8007E3188 /* ImportRouter.swift in Sources */, A5629AE42876E6D200094373 /* ThreadViewModel.swift in Sources */, A58E7D0C2872A45B0082D443 /* MainModule.swift in Sources */, @@ -2324,6 +2332,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + A5A0843E29D2F624000B9B17 /* DefaultCryptoProvider.swift in Sources */, 84CEC64628D89D6B00D081A8 /* PairingTests.swift in Sources */, 767DC83528997F8E00080FA9 /* EthSendTransaction.swift in Sources */, 8439CB89293F658E00F2F2E2 /* PushMessage.swift in Sources */, @@ -2373,6 +2382,7 @@ C56EE250293F566D004840D1 /* ScanTargetView.swift in Sources */, C56EE28F293F5757004840D1 /* MigrationConfigurator.swift in Sources */, 84B815552991217900FAD54E /* PushMessagesPresenter.swift in Sources */, + A5A0844029D2F626000B9B17 /* DefaultCryptoProvider.swift in Sources */, 847BD1DD2989494F00076C90 /* TabPage.swift in Sources */, C55D348B295DD8CA0004314A /* PasteUriRouter.swift in Sources */, 84B815572991217900FAD54E /* PushMessagesInteractor.swift in Sources */, diff --git a/Example/IntegrationTests/Auth/AuthTests.swift b/Example/IntegrationTests/Auth/AuthTests.swift index 436091772..992c9f1c5 100644 --- a/Example/IntegrationTests/Auth/AuthTests.swift +++ b/Example/IntegrationTests/Auth/AuthTests.swift @@ -50,7 +50,7 @@ final class AuthTests: XCTestCase { let authClient = AuthClientFactory.create( metadata: AppMetadata(name: name, description: "", url: "", icons: [""]), projectId: InputConfig.projectId, - signerFactory: DefaultSignerFactory(), + crypto: DefaultCryptoProvider(), logger: logger, keyValueStorage: keyValueStorage, keychainStorage: keychain, diff --git a/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift b/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift index 1d951341a..7bad1e112 100644 --- a/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift +++ b/Example/IntegrationTests/Auth/ENS/ENSResolverTests.swift @@ -8,13 +8,13 @@ class ENSSignerTests: XCTestCase { private let ens = "web3.eth" func testResolveEns() async throws { - let resolver = ENSResolverFactory(signerFactory: DefaultSignerFactory()).create(projectId: InputConfig.projectId) + let resolver = ENSResolverFactory(crypto: DefaultCryptoProvider()).create(projectId: InputConfig.projectId) let resolved = try await resolver.resolveEns(account: account) XCTAssertEqual(resolved, ens) } func testResolveAddress() async throws { - let resolver = ENSResolverFactory(signerFactory: DefaultSignerFactory()).create(projectId: InputConfig.projectId) + let resolver = ENSResolverFactory(crypto: DefaultCryptoProvider()).create(projectId: InputConfig.projectId) let resolved = try await resolver.resolveAddress(ens: ens, blockchain: account.blockchain) XCTAssertEqual(resolved, account) } diff --git a/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift b/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift index ee5224a1d..285173cc3 100644 --- a/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift +++ b/Example/IntegrationTests/Auth/Signer/CacaoSignerTests.swift @@ -6,6 +6,7 @@ class CacaoSignerTest: XCTestCase { let signer = MessageSignerFactory(signerFactory: DefaultSignerFactory()) .create(projectId: InputConfig.projectId) + let verifier = MessageVerifierFactory(crypto: DefaultCryptoProvider()).create(projectId: InputConfig.projectId) let privateKey = Data(hex: "305c6cde3846927892cd32762f6120539f3ec74c9e3a16b9b798b1e85351ae2a") @@ -52,6 +53,6 @@ class CacaoSignerTest: XCTestCase { } func testCacaoVerify() async throws { - try await signer.verify(signature: signature, message: message, address: "0x15bca56b6e2728aec2532df9d436bd1600e86688", chainId: "eip155:1") + try await verifier.verify(signature: signature, message: message, address: "0x15bca56b6e2728aec2532df9d436bd1600e86688", chainId: "eip155:1") } } diff --git a/Example/IntegrationTests/Auth/Signer/EIP1271VerifierTests.swift b/Example/IntegrationTests/Auth/Signer/EIP1271VerifierTests.swift index 40b66bcb4..4bf4fba1b 100644 --- a/Example/IntegrationTests/Auth/Signer/EIP1271VerifierTests.swift +++ b/Example/IntegrationTests/Auth/Signer/EIP1271VerifierTests.swift @@ -15,8 +15,7 @@ class EIP1271VerifierTests: XCTestCase { func testSuccessVerify() async throws { let httpClient = HTTPNetworkClient(host: "rpc.walletconnect.com") - let signer = DefaultSignerFactory().createEthereumSigner() - let verifier = EIP1271Verifier(projectId: InputConfig.projectId, httpClient: httpClient, signer: signer) + let verifier = EIP1271Verifier(projectId: InputConfig.projectId, httpClient: httpClient, crypto: DefaultCryptoProvider()) try await verifier.verify( signature: signature, message: message, @@ -27,8 +26,7 @@ class EIP1271VerifierTests: XCTestCase { func testFailureVerify() async throws { let httpClient = HTTPNetworkClient(host: "rpc.walletconnect.com") - let signer = DefaultSignerFactory().createEthereumSigner() - let verifier = EIP1271Verifier(projectId: InputConfig.projectId, httpClient: httpClient, signer: signer) + let verifier = EIP1271Verifier(projectId: InputConfig.projectId, httpClient: httpClient, crypto: DefaultCryptoProvider()) await XCTAssertThrowsErrorAsync(try await verifier.verify( signature: Data("deadbeaf"), diff --git a/Example/IntegrationTests/Auth/Signer/EIP191VerifierTests.swift b/Example/IntegrationTests/Auth/Signer/EIP191VerifierTests.swift index 5d5aa2c25..ae565315c 100644 --- a/Example/IntegrationTests/Auth/Signer/EIP191VerifierTests.swift +++ b/Example/IntegrationTests/Auth/Signer/EIP191VerifierTests.swift @@ -5,7 +5,7 @@ import XCTest class EIP191VerifierTests: XCTestCase { - private let verifier = EIP191Verifier(signer: DefaultSignerFactory().createEthereumSigner()) + private let verifier = EIP191Verifier(crypto: DefaultCryptoProvider()) private let address = "0x15bca56b6e2728aec2532df9d436bd1600e86688" private let message = "\u{19}Ethereum Signed Message:\n7Message".data(using: .utf8)! diff --git a/Example/IntegrationTests/Chat/RegistryTests.swift b/Example/IntegrationTests/Chat/RegistryTests.swift index d98559981..074251e63 100644 --- a/Example/IntegrationTests/Chat/RegistryTests.swift +++ b/Example/IntegrationTests/Chat/RegistryTests.swift @@ -12,7 +12,7 @@ final class RegistryTests: XCTestCase { var sut: IdentityService! var storage: IdentityStorage! - var signer: CacaoMessageSigner! + var signer: MessageSigner! override func setUp() { let keyserverURL = URL(string: "https://keys.walletconnect.com")! diff --git a/Example/Shared/DefaultCryptoProvider.swift b/Example/Shared/DefaultCryptoProvider.swift new file mode 100644 index 000000000..79a11fe2c --- /dev/null +++ b/Example/Shared/DefaultCryptoProvider.swift @@ -0,0 +1,23 @@ +import Foundation +import Auth +import Web3 +import CryptoSwift + +struct DefaultCryptoProvider: CryptoProvider { + + public func recoverPubKey(signature: EthereumSignature, message: Data) throws -> Data { + let publicKey = try EthereumPublicKey( + message: message.bytes, + v: EthereumQuantity(quantity: BigUInt(signature.v)), + r: EthereumQuantity(signature.r), + s: EthereumQuantity(signature.s) + ) + return Data(publicKey.rawPublicKey) + } + + public func keccak256(_ data: Data) -> Data { + let digest = SHA3(variant: .keccak256) + let hash = digest.calculate(for: [UInt8](data)) + return Data(hash) + } +} diff --git a/Example/Shared/DefaultSignerFactory.swift b/Example/Shared/DefaultSignerFactory.swift index ac720452d..133094d00 100644 --- a/Example/Shared/DefaultSignerFactory.swift +++ b/Example/Shared/DefaultSignerFactory.swift @@ -17,20 +17,4 @@ public struct Web3Signer: EthereumSigner { let signature = try privateKey.sign(message: message.bytes) return EthereumSignature(v: UInt8(signature.v), r: signature.r, s: signature.s) } - - public func recoverPubKey(signature: EthereumSignature, message: Data) throws -> Data { - let publicKey = try EthereumPublicKey( - message: message.bytes, - v: EthereumQuantity(quantity: BigUInt(signature.v)), - r: EthereumQuantity(signature.r), - s: EthereumQuantity(signature.s) - ) - return Data(publicKey.rawPublicKey) - } - - public func keccak256(_ data: Data) -> Data { - let digest = SHA3(variant: .keccak256) - let hash = digest.calculate(for: [UInt8](data)) - return Data(hash) - } } diff --git a/Sources/Web3Wallet/Web3Wallet.swift b/Sources/Web3Wallet/Web3Wallet.swift index a0ea0224a..d075ae68c 100644 --- a/Sources/Web3Wallet/Web3Wallet.swift +++ b/Sources/Web3Wallet/Web3Wallet.swift @@ -35,17 +35,17 @@ public class Web3Wallet { /// Wallet instance wallet config method. /// - Parameters: /// - metadata: App metadata - /// - signerFactory: Auth signers factory + /// - crypto: Auth crypto utils static public func configure( metadata: AppMetadata, - signerFactory: SignerFactory, + crypto: CryptoProvider, echoHost: String = "echo.walletconnect.com", environment: APNSEnvironment = .production ) { Pair.configure(metadata: metadata) - Auth.configure(signerFactory: signerFactory) + Auth.configure(crypto: crypto) let clientId = try! Networking.interactor.getClientId() Echo.configure(clientId: clientId, echoHost: echoHost, environment: environment) - Web3Wallet.config = Web3Wallet.Config(signerFactory: signerFactory) + Web3Wallet.config = Web3Wallet.Config(crypto: crypto) } } diff --git a/Sources/Web3Wallet/Web3WalletConfig.swift b/Sources/Web3Wallet/Web3WalletConfig.swift index 166be6ca3..c9bf1aa6e 100644 --- a/Sources/Web3Wallet/Web3WalletConfig.swift +++ b/Sources/Web3Wallet/Web3WalletConfig.swift @@ -2,6 +2,6 @@ import Foundation extension Web3Wallet { struct Config { - let signerFactory: SignerFactory + let crypto: CryptoProvider } } diff --git a/Tests/AuthTests/AppRespondSubscriberTests.swift b/Tests/AuthTests/AppRespondSubscriberTests.swift index cd2fb8f5b..60c975e65 100644 --- a/Tests/AuthTests/AppRespondSubscriberTests.swift +++ b/Tests/AuthTests/AppRespondSubscriberTests.swift @@ -14,14 +14,14 @@ class AppRespondSubscriberTests: XCTestCase { var messageFormatter: SIWECacaoFormatter! var rpcHistory: RPCHistory! let defaultTimeout: TimeInterval = 0.01 - var messageSigner: CacaoMessageSigner! + var messageVerifier: MessageVerifier! var pairingStorage: WCPairingStorageMock! var pairingRegisterer: PairingRegistererMock! override func setUp() { networkingInteractor = NetworkingInteractorMock() messageFormatter = SIWECacaoFormatter() - messageSigner = MessageSignerMock() + messageVerifier = .stub() rpcHistory = RPCHistoryFactory.createForNetwork(keyValueStorage: RuntimeKeyValueStorage()) pairingStorage = WCPairingStorageMock() pairingRegisterer = PairingRegistererMock() @@ -29,7 +29,7 @@ class AppRespondSubscriberTests: XCTestCase { networkingInteractor: networkingInteractor, logger: ConsoleLoggerMock(), rpcHistory: rpcHistory, - signatureVerifier: messageSigner, + signatureVerifier: messageVerifier, pairingRegisterer: pairingRegisterer, messageFormatter: messageFormatter) } diff --git a/Tests/AuthTests/Stubs/MessageSignerMock.swift b/Tests/AuthTests/Stubs/MessageSignerMock.swift index 869febeeb..3809c2dbb 100644 --- a/Tests/AuthTests/Stubs/MessageSignerMock.swift +++ b/Tests/AuthTests/Stubs/MessageSignerMock.swift @@ -1,23 +1,27 @@ import Foundation -import Auth +@testable import WalletConnectSigner -struct MessageSignerMock: CacaoMessageSigner { - func sign(message: String, privateKey: Data, type: WalletConnectUtils.CacaoSignatureType) throws -> WalletConnectUtils.CacaoSignature { - return CacaoSignature(t: .eip191, s: "") +extension MessageVerifier { + + static func stub() -> MessageVerifier { + return MessageVerifier( + eip191Verifier: EIP191Verifier(crypto: Crypto()), + eip1271Verifier: EIP1271Verifier( + projectId: "", + httpClient: HTTPNetworkClient(host: ""), + crypto: Crypto() + ) + ) } - func verify(signature: CacaoSignature, - message: String, - address: String, - chainId: String - ) async throws { + struct Crypto: CryptoProvider { - } + func keccak256(_ data: Data) -> Data { + return Data() + } - func sign(payload: CacaoPayload, - privateKey: Data, - type: CacaoSignatureType - ) throws -> CacaoSignature { - return CacaoSignature(t: .eip191, s: "") + func recoverPubKey(signature: EthereumSignature, message: Data) throws -> Data { + return Data() + } } } From 0234ab7c33c8e5703ef07573aaf45641276cba55 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Tue, 28 Mar 2023 15:26:46 +0500 Subject: [PATCH 48/55] Sample apps fixed --- Example/DApp/SceneDelegate.swift | 2 +- .../ApplicationLayer/Configurator/ThirdPartyConfigurator.swift | 2 +- .../PresentationLayer/Chat/Invite/InviteInteractor.swift | 2 +- .../ApplicationLayer/Configurator/ThirdPartyConfigurator.swift | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/DApp/SceneDelegate.swift b/Example/DApp/SceneDelegate.swift index c1ea35937..f6b051abc 100644 --- a/Example/DApp/SceneDelegate.swift +++ b/Example/DApp/SceneDelegate.swift @@ -12,7 +12,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { Networking.configure(projectId: InputConfig.projectId, socketFactory: DefaultSocketFactory()) - Auth.configure(signerFactory: DefaultSignerFactory()) + Auth.configure(crypto: DefaultCryptoProvider()) setupWindow(scene: scene) } diff --git a/Example/Showcase/Classes/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift b/Example/Showcase/Classes/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift index f71b9de3e..fbd9ee1a7 100644 --- a/Example/Showcase/Classes/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift +++ b/Example/Showcase/Classes/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift @@ -14,6 +14,6 @@ struct ThirdPartyConfigurator: Configurator { icons: ["https://avatars.githubusercontent.com/u/37784886"] )) - Auth.configure(signerFactory: DefaultSignerFactory()) + Auth.configure(crypto: DefaultCryptoProvider()) } } diff --git a/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InviteInteractor.swift b/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InviteInteractor.swift index 7d9ca4bd8..f56f3b6eb 100644 --- a/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InviteInteractor.swift +++ b/Example/Showcase/Classes/PresentationLayer/Chat/Invite/InviteInteractor.swift @@ -15,7 +15,7 @@ final class InviteInteractor { } func resolve(ens: String) async throws -> Account { - let resolver = ENSResolverFactory(signerFactory: DefaultSignerFactory()).create() + let resolver = ENSResolverFactory(crypto: DefaultCryptoProvider()).create() let blochain = Blockchain("eip155:1")! return try await resolver.resolveAddress(ens: ens, blockchain: Blockchain("eip155:1")!) } diff --git a/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift index 512c560e3..a977e8fdd 100644 --- a/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift +++ b/Example/WalletApp/ApplicationLayer/Configurator/ThirdPartyConfigurator.swift @@ -14,7 +14,7 @@ struct ThirdPartyConfigurator: Configurator { icons: ["https://avatars.githubusercontent.com/u/37784886"] ) - Web3Wallet.configure(metadata: metadata, signerFactory: DefaultSignerFactory(), environment: BuildConfiguration.shared.apnsEnvironment) + Web3Wallet.configure(metadata: metadata, crypto: DefaultCryptoProvider(), environment: BuildConfiguration.shared.apnsEnvironment) Push.configure(environment: BuildConfiguration.shared.apnsEnvironment) } From 9e63d4a5482ba5b7330333f579cf138df2f64922 Mon Sep 17 00:00:00 2001 From: flypaper0 Date: Fri, 31 Mar 2023 12:13:45 +0000 Subject: [PATCH 49/55] Set User Agent --- Sources/WalletConnectRelay/PackageConfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnectRelay/PackageConfig.json b/Sources/WalletConnectRelay/PackageConfig.json index 2901f0eb7..dc217fa7b 100644 --- a/Sources/WalletConnectRelay/PackageConfig.json +++ b/Sources/WalletConnectRelay/PackageConfig.json @@ -1 +1 @@ -{"version": "1.5.3"} +{"version": "1.5.4"} From a9587f7de6b4b8075d34fcdd7beb3ffde985be76 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Fri, 31 Mar 2023 18:25:29 +0500 Subject: [PATCH 50/55] WalletConnectEcho cocoapods support --- Sources/WalletConnectEcho/Echo.swift | 1 - Sources/WalletConnectEcho/EchoClient.swift | 1 - Sources/WalletConnectEcho/EchoClientFactory.swift | 1 - Sources/WalletConnectEcho/EchoImports.swift | 4 ++++ Sources/WalletConnectEcho/Register/EchoAuthPayload.swift | 1 - Sources/WalletConnectEcho/Register/EchoAuthenticator.swift | 1 - .../WalletConnectEcho/Register/EchoRegisterService.swift | 2 -- Sources/WalletConnectEcho/Register/EchoService.swift | 1 - WalletConnectSwiftV2.podspec | 7 +++++++ 9 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 Sources/WalletConnectEcho/EchoImports.swift diff --git a/Sources/WalletConnectEcho/Echo.swift b/Sources/WalletConnectEcho/Echo.swift index 13f91a4b8..60b9f6e9d 100644 --- a/Sources/WalletConnectEcho/Echo.swift +++ b/Sources/WalletConnectEcho/Echo.swift @@ -1,5 +1,4 @@ import Foundation -import WalletConnectNetworking public class Echo { static public let echoHost = "echo.walletconnect.com" diff --git a/Sources/WalletConnectEcho/EchoClient.swift b/Sources/WalletConnectEcho/EchoClient.swift index ae4801e91..d7724ec5a 100644 --- a/Sources/WalletConnectEcho/EchoClient.swift +++ b/Sources/WalletConnectEcho/EchoClient.swift @@ -1,5 +1,4 @@ import Foundation -import WalletConnectNetworking public class EchoClient: EchoClientProtocol { private let registerService: EchoRegisterService diff --git a/Sources/WalletConnectEcho/EchoClientFactory.swift b/Sources/WalletConnectEcho/EchoClientFactory.swift index 53c0f1081..43bdc82b7 100644 --- a/Sources/WalletConnectEcho/EchoClientFactory.swift +++ b/Sources/WalletConnectEcho/EchoClientFactory.swift @@ -1,5 +1,4 @@ import Foundation -import WalletConnectNetworking public struct EchoClientFactory { public static func create(projectId: String, diff --git a/Sources/WalletConnectEcho/EchoImports.swift b/Sources/WalletConnectEcho/EchoImports.swift new file mode 100644 index 000000000..463cb7c23 --- /dev/null +++ b/Sources/WalletConnectEcho/EchoImports.swift @@ -0,0 +1,4 @@ +#if !CocoaPods +@_exported import WalletConnectNetworking +@_exported import WalletConnectJWT +#endif diff --git a/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift b/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift index dc42a5be2..12b0e26e9 100644 --- a/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift +++ b/Sources/WalletConnectEcho/Register/EchoAuthPayload.swift @@ -1,5 +1,4 @@ import Foundation -import WalletConnectJWT struct EchoAuthPayload: JWTClaimsCodable { diff --git a/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift b/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift index 892ada61b..c47247fa4 100644 --- a/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift +++ b/Sources/WalletConnectEcho/Register/EchoAuthenticator.swift @@ -1,5 +1,4 @@ import Foundation -import WalletConnectNetworking protocol EchoAuthenticating { func createAuthToken() throws -> String diff --git a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift index dcf5588b7..e7e27e68f 100644 --- a/Sources/WalletConnectEcho/Register/EchoRegisterService.swift +++ b/Sources/WalletConnectEcho/Register/EchoRegisterService.swift @@ -1,6 +1,4 @@ import Foundation -import WalletConnectNetworking -import WalletConnectJWT actor EchoRegisterService { private let httpClient: HTTPClient diff --git a/Sources/WalletConnectEcho/Register/EchoService.swift b/Sources/WalletConnectEcho/Register/EchoService.swift index 246f8b086..44c328101 100644 --- a/Sources/WalletConnectEcho/Register/EchoService.swift +++ b/Sources/WalletConnectEcho/Register/EchoService.swift @@ -1,5 +1,4 @@ import Foundation -import WalletConnectNetworking enum EchoAPI: HTTPService { case register(clientId: String, token: String, projectId: String, environment: APNSEnvironment, auth: String) diff --git a/WalletConnectSwiftV2.podspec b/WalletConnectSwiftV2.podspec index a9f746cae..f87cf006f 100644 --- a/WalletConnectSwiftV2.podspec +++ b/WalletConnectSwiftV2.podspec @@ -89,6 +89,7 @@ Pod::Spec.new do |spec| ss.source_files = 'Sources/Web3Wallet/**/*.{h,m,swift}' ss.dependency 'WalletConnectSwiftV2/WalletConnect' ss.dependency 'WalletConnectSwiftV2/WalletConnectAuth' + ss.dependency 'WalletConnectSwiftV2/WalletConnectEcho' end spec.subspec 'WalletConnectChat' do |ss| @@ -108,6 +109,12 @@ Pod::Spec.new do |spec| ss.dependency 'WalletConnectSwiftV2/WalletConnectJWT' end + spec.subspec 'WalletConnectEcho' do |ss| + ss.source_files = 'Sources/WalletConnectEcho/**/*.{h,m,swift}' + ss.dependency 'WalletConnectSwiftV2/WalletConnectNetworking' + ss.dependency 'WalletConnectSwiftV2/WalletConnectJWT' + end + spec.subspec 'WalletConnectJWT' do |ss| ss.source_files = 'Sources/WalletConnectJWT/**/*.{h,m,swift}' ss.dependency 'WalletConnectSwiftV2/WalletConnectKMS' From 0e126fc31d09643c55756b775f3d5b23a6965554 Mon Sep 17 00:00:00 2001 From: flypaper0 Date: Fri, 31 Mar 2023 17:54:25 +0000 Subject: [PATCH 51/55] Set User Agent --- Sources/WalletConnectRelay/PackageConfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnectRelay/PackageConfig.json b/Sources/WalletConnectRelay/PackageConfig.json index dc217fa7b..bfd3cd59b 100644 --- a/Sources/WalletConnectRelay/PackageConfig.json +++ b/Sources/WalletConnectRelay/PackageConfig.json @@ -1 +1 @@ -{"version": "1.5.4"} +{"version": "1.5.5"} From 1d8e7db7210c4b860bacf57273e66cc7e4e304ec Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Sat, 1 Apr 2023 00:37:38 +0500 Subject: [PATCH 52/55] Web3Wallet cocoapods --- Sources/Web3Wallet/Web3Wallet.swift | 1 - Sources/Web3Wallet/Web3WalletClient.swift | 1 - Sources/Web3Wallet/Web3WalletClientFactory.swift | 1 - Sources/Web3Wallet/Web3WalletImports.swift | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Sources/Web3Wallet/Web3Wallet.swift b/Sources/Web3Wallet/Web3Wallet.swift index d075ae68c..c016d47d1 100644 --- a/Sources/Web3Wallet/Web3Wallet.swift +++ b/Sources/Web3Wallet/Web3Wallet.swift @@ -1,5 +1,4 @@ import Foundation -import WalletConnectEcho import Combine /// Web3Wallet instance wrapper diff --git a/Sources/Web3Wallet/Web3WalletClient.swift b/Sources/Web3Wallet/Web3WalletClient.swift index dcd9d7654..7218dbf3a 100644 --- a/Sources/Web3Wallet/Web3WalletClient.swift +++ b/Sources/Web3Wallet/Web3WalletClient.swift @@ -1,5 +1,4 @@ import Foundation -import WalletConnectEcho import Combine /// Web3 Wallet Client diff --git a/Sources/Web3Wallet/Web3WalletClientFactory.swift b/Sources/Web3Wallet/Web3WalletClientFactory.swift index 7315600db..b27654757 100644 --- a/Sources/Web3Wallet/Web3WalletClientFactory.swift +++ b/Sources/Web3Wallet/Web3WalletClientFactory.swift @@ -1,5 +1,4 @@ import Foundation -import WalletConnectEcho public struct Web3WalletClientFactory { public static func create( diff --git a/Sources/Web3Wallet/Web3WalletImports.swift b/Sources/Web3Wallet/Web3WalletImports.swift index cbc2a3e73..03faad8ad 100644 --- a/Sources/Web3Wallet/Web3WalletImports.swift +++ b/Sources/Web3Wallet/Web3WalletImports.swift @@ -1,5 +1,5 @@ #if !CocoaPods @_exported import Auth @_exported import WalletConnectSign -@_exported import WalletConnectPairing +@_exported import WalletConnectEcho #endif From d2cebb8cc4a7f14689ebbc33a6d18feb3fb51ce8 Mon Sep 17 00:00:00 2001 From: flypaper0 Date: Sat, 1 Apr 2023 09:54:31 +0000 Subject: [PATCH 53/55] Set User Agent --- Sources/WalletConnectRelay/PackageConfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnectRelay/PackageConfig.json b/Sources/WalletConnectRelay/PackageConfig.json index bfd3cd59b..d96c39706 100644 --- a/Sources/WalletConnectRelay/PackageConfig.json +++ b/Sources/WalletConnectRelay/PackageConfig.json @@ -1 +1 @@ -{"version": "1.5.5"} +{"version": "1.5.6"} From a407f39741a849287243df934cb5958195471ec5 Mon Sep 17 00:00:00 2001 From: Artur Guseinov Date: Sat, 1 Apr 2023 15:59:37 +0500 Subject: [PATCH 54/55] targetEnvironment changed to DEBUG --- Sources/Web3Wallet/Web3WalletClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Web3Wallet/Web3WalletClient.swift b/Sources/Web3Wallet/Web3WalletClient.swift index 7218dbf3a..58cb53ce6 100644 --- a/Sources/Web3Wallet/Web3WalletClient.swift +++ b/Sources/Web3Wallet/Web3WalletClient.swift @@ -222,7 +222,7 @@ public class Web3WalletClient { } } -#if targetEnvironment(simulator) +#if DEBUG extension Web3WalletClient { public func registerEchoClient(deviceToken: String) async throws { try await echoClient.register(deviceToken: deviceToken) From 8dc92a8d96ef3a45e4b99316d1d9e3296e5adc36 Mon Sep 17 00:00:00 2001 From: flypaper0 Date: Sat, 1 Apr 2023 11:47:58 +0000 Subject: [PATCH 55/55] Set User Agent --- Sources/WalletConnectRelay/PackageConfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnectRelay/PackageConfig.json b/Sources/WalletConnectRelay/PackageConfig.json index d96c39706..ed062727d 100644 --- a/Sources/WalletConnectRelay/PackageConfig.json +++ b/Sources/WalletConnectRelay/PackageConfig.json @@ -1 +1 @@ -{"version": "1.5.6"} +{"version": "1.5.7"}